diff --git a/maxlength.js b/maxlength.js
index 79b13ba..b524753 100644
--- a/maxlength.js
+++ b/maxlength.js
@@ -1,7 +1,6 @@
 /* $Id$ */
 
 Drupal.maxLength_limit = function (field) {
-
   // Build maxlength values and settings
   var id = $(field).attr('id');
   // Skip form elements that do not exist. This sometimes occurs with more 
@@ -19,14 +18,20 @@ Drupal.maxLength_limit = function (field) {
   });
 
   // calculate the remaining count of chars  
-  var length = $(field).val().length;
-  var remainingCount = limit - length;  
+  var text = $(field).val()
+  , raw_length = $(field).val().length
+  , text_length = text.replace(/[\r\n]+/g, '#').replace(/<[^>]*>/g, '').replace(/&\w+;/g ,'#').length
+  , remainingCount = limit - text_length;  
 
   // if there is not remaining char, we clear additional content
+  // when tags are stripped, we can't use substr to effectively truncate text
+  // so disabling for now.
+  /*
   if (remainingCount < 0) {
     $(field).val($(field).val().substr(0, limit));    
     remainingCount = 0;
-  }  
+  }
+  */  
 
   // Update the remaing chars text.
   maxlength.span_remaining_count.html(remainingCount.toString());
diff --git a/maxlength.module b/maxlength.module
index 5dfb580..b520aa6 100644
--- a/maxlength.module
+++ b/maxlength.module
@@ -52,24 +52,24 @@ function maxlength_form_alter(&$form, &$form_state, $form_id) {
  * Implementation of hook_nodeapi().
  */
 function maxlength_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
-  if ($op != 'validate') {
-    return;
-  }
-  // Core fields, CCK takes care of CCK fields, no need to validate them
-  $fields = array('title', 'body');
-
-  foreach ($fields as $field) {
-    $limit = intval(variable_get('maxlength_' . $field .'_'. $node->type, ''));
-    if ($limit > 0) {
-      $form = $a3;
-      // line breaks can be stored 2 or more chars, breaking the count.
-      $text = $node->$field;
-
-      $text = str_replace("\r\n", '#', $text);
-      $text = str_replace("\n", '#', $text);
-      $text = str_replace("\r", '#', $text);
-      if (drupal_strlen($text) > $limit) {
-        form_set_error($field, t('The !field field has exceeded its maximum number of characters (!limit).', array('!limit' => $limit, '!field' => $field)));
+  if ($op == 'validate') {
+    // Core fields, CCK takes care of CCK fields, no need to validate them
+    $fields = array('title', 'body');
+
+    foreach ($fields as $field) {
+      $limit = intval(variable_get('maxlength_' . $field .'_'. $node->type, ''));
+      if ($limit > 0) {
+        $form = $a3;
+        // line breaks can be stored 2 or more chars, breaking the count.
+        $text = $node->$field;
+
+        $text = str_replace("\r\n", '#', $text);
+        $text = str_replace("\n", '#', $text);
+        $text = str_replace("\r", '#', $text);
+        $text = _maxlength_strip_html($text);
+        if (drupal_strlen($text) > $limit) {
+          form_set_error($field, t('The !field field has exceeded its maximum number of characters (!length instead of !limit).', array('!length' => drupal_strlen($text), '!limit' => $limit, '!field' => $field)));
+        }
       }
     }
   }
@@ -127,8 +127,13 @@ function _maxlength_format_element($element) {
     $path = drupal_get_path('module', 'maxlength');
     drupal_add_js($path .'/maxlength.js');
 
-    $remaining = $values['limit'] - drupal_strlen($value);
+    $raw_length = drupal_strlen($value);
+    $text_length = drupal_strlen(_maxlength_strip_html($value));
+    $remaining = $values['limit'] - $text_length;
 
+    // when tags are stripped, we can't use substr to effectively truncate text
+    // so disabling for now.
+    /*
     if ($remaining < 0) {
       drupal_set_message(
         t('%body_field_label truncated to %limit characters!',
@@ -142,6 +147,7 @@ function _maxlength_format_element($element) {
       $element['#default_value'] = drupal_substr($element['#default_value'], 0, $values['limit']);
       $remaining = 0;
     }
+    */
 
     if (in_array($element['#id'], $processed) === FALSE) {
       $js_settings = array(
@@ -151,9 +157,25 @@ function _maxlength_format_element($element) {
       );
       drupal_add_js($js_settings, 'setting');
     }
-    $element['#suffix'] = '<div id="maxlength-'. $id .'"
-      class="maxlength-counter">' . t($values['text'], array('!limit' => $values['limit'], '!count' => '<span class="maxlength-count">' . drupal_strlen($value) .'</span>', '!remaining' => '<span class="maxlength-counter-remaining">' . $remaining . '</span>')) . '</div>';
+    $element['#suffix'] = '<div id="maxlength-' . $id . '" class="maxlength-counter">';
+    $element['#suffix'] .= t($values['text'], array(
+      '!limit' => $values['limit'], 
+      '!count' =>'<span class="maxlength-count">'. $text_length.'</span>', 
+      '!remaining' => '<span class="maxlength-counter-remaining">' . $remaining . '</span>'));
+    $element['#suffix'] .= "</div>\n";
     $processed[] = $element['#id'];
   }
   return $element;
 }
+
+function _maxlength_strip_html($raw) {
+  if (module_exists('wysiwyg_maxlength')) {
+    //  1. remove linebreaks (artificially replaced by the character '#')
+    //  2. remove html tags
+    //  3. replace multiple spaces by only one
+    //  4. consider HTML entities (&eacute; for example) as one character (artificially replaced by the character 'X')
+    //  5. remove white spaces at the beginning and end of the text.
+    return trim(preg_replace('/&\w+;/', '#',preg_replace('/<[^>]*>/', '', str_replace("\r\n",'#',$raw))));
+  }
+  return $raw;
+}
