Roo/htmleditor/TidyWriter.js
[roojs1] / Roo / htmleditor / TidyWriter.js
index bfcb7cf..3a46ac4 100644 (file)
@@ -2,6 +2,12 @@
  * This is based loosely on tinymce 
  * @class Roo.htmleditor.TidyWriter
  * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js
+ *
+ * Known issues?
+ * - not tested much with 'PRE' formated elements.
+ * - long text inside of inline can be wrapped and clened?
+ *
+ *
  */
 
 Roo.htmleditor.TidyWriter = function(settings)
@@ -42,7 +48,7 @@ Roo.htmleditor.TidyWriter.prototype = {
     indentstr : '',
     in_pre: false,
     in_inline : false,
-    
+    last_inline : false,
     encode : false,
      
     
@@ -66,11 +72,35 @@ Roo.htmleditor.TidyWriter.prototype = {
         
         var is_short   = empty ? Roo.htmleditor.TidyWriter.shortend_elements.indexOf(name) > -1 : false;
         
+        var add_lb = name == 'BR' ? false : in_inline;
+        
+        if (!add_lb && !this.in_pre && this.lastElementEndsWS()) {
+            i_inline = false;
+        }
 
-        var indentstr = this.in_inline || this.in_pre ? '' : this.indentstr;
+        var indentstr =  this.indentstr;
         
-        if (!in_inline && !this.in_pre) {
-            this.addLine();
+        // e_inline = elements that can be inline, but still allow \n before and after?
+        // only 'BR' ??? any others?
+        
+        // ADD LINE BEFORE tage
+        if (!this.in_pre) {
+            if (in_inline) {
+                //code
+                if (name == 'BR') {
+                    this.addLine();
+                } else if (this.lastElementEndsWS()) {
+                    this.addLine();
+                } else{
+                    // otherwise - no new line. (and dont indent.)
+                    indentstr = '';
+                }
+                
+            } else {
+                this.addLine();
+            }
+        } else {
+            indentstr = '';
         }
         
         this.html.push(indentstr + '<', name.toLowerCase());
@@ -88,8 +118,9 @@ Roo.htmleditor.TidyWriter.prototype = {
             } else {
                 this.html[this.html.length] = '></' + name.toLowerCase() + '>';
             }
+            var e_inline = name == 'BR' ? false : this.in_inline;
             
-            if (!this.in_inline && !this.in_pre) {
+            if (!e_inline && !this.in_pre) {
                 this.addLine();
             }
             return;
@@ -129,6 +160,17 @@ Roo.htmleditor.TidyWriter.prototype = {
          
         
     },
+    
+    lastElementEndsWS : function()
+    {
+        var value = this.html.length > 0 ? this.html[this.html.length-1] : false;
+        if (value === false) {
+            return true;
+        }
+        return value.match(/\s+$/);
+        
+    },
+    
     /**
      * Writes the a end element such as </p>.
      *
@@ -138,13 +180,15 @@ Roo.htmleditor.TidyWriter.prototype = {
     end: function(name) {
         var value;
         this.popState();
-        var indentstr = ''; 
-        if (!this.in_pre && !this.in_inline) {
+        var indentstr = '';
+        var in_inline = this.in_inline || Roo.htmleditor.TidyWriter.inline_elements.indexOf(name) > -1;
+        
+        if (!this.in_pre && !in_inline) {
             this.addLine();
             indentstr  = this.indentstr;
         }
         this.html.push(indentstr + '</', name.toLowerCase(), '>');
-       
+        this.last_inline = in_inline;
         
         // pop the indent state..
     },
@@ -158,20 +202,46 @@ Roo.htmleditor.TidyWriter.prototype = {
      * @param {String} text String to write out.
      * @param {Boolean} raw Optional raw state if true the contents wont get encoded.
      */
-    text: function(text )
+    text: function(text, node)
     {
         // if not in whitespace critical
         if (text.length < 1) {
             return;
         }
-        if (this.in_pre || this.is_inline) {
-            this.html[this.html.length] =  text;
-            return;
+        if (this.in_pre || this.in_inline) {
             
+            if (this.in_inline) {
+                text = text.replace(/\s/g,' ') // all line breaks to ' '
+                    .replace(/\s+/,' ')  // all white space to single white space
+                // if next tag is '<BR>', then we can trim right..
+                if (node.nextSibling &&
+                    node.nextSibling.nodeType == 1 &&
+                    node.nextSibling.nodeName == 'BR' )
+                {
+                    text = text.replace(/\s+$/g,'');
+                }
+                // if previous tag was a BR, we can also trim..
+                if (node.previousSibling &&
+                    node.previousSibling.nodeType == 1 &&
+                    node.previousSibling.nodeName == 'BR' )
+                {
+                    text = text.replace(/^\s+/g,'');
+                }
+                
+            }
+            this.html[this.html.length] =  text;
+            return;   
+        }
+        // see if last element was a inline element.
+        var indentstr = this.indentstr;
+        if (node.previousSibling &&
+            node.previousSibling.nodeType == 1 &&
+            Roo.htmleditor.TidyWriter.inline_elements.indexOf(node.previousSibling.nodeName) > -1)
+        {
+            indentstr = '';
+        } else {
+            this.addLine();
         }
-        // see if last line is a line break
-        
-        this.addLine();
             
         
         
@@ -183,7 +253,7 @@ Roo.htmleditor.TidyWriter.prototype = {
             return;
         }
         if (!text.match(/\n/)) {
-            this.html.push(this.indentstr + text);
+            this.html.push(indentstr + text);
             return;
         }