Merge branch 'master' of http://git.roojs.com:8081/roojs1
authorAlan Knowles <alan@roojs.com>
Wed, 15 Feb 2012 04:39:11 +0000 (12:39 +0800)
committerAlan Knowles <alan@roojs.com>
Wed, 15 Feb 2012 04:39:11 +0000 (12:39 +0800)
Roo/form/HtmlEditor.js
Roo/form/HtmlEditor/ToolbarStandard.js
Roo/lib/Color.js [new file with mode: 0644]
roojs-all.js
roojs-debug.js
roojs-ui-debug.js
roojs-ui.js

index bdba027..d8b96d2 100644 (file)
@@ -437,6 +437,10 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             }
             html = this.cleanHtml(html);
+            // fix up the special chars..
+            html = html.replace(/([\x80-\uffff])/g, function (a, b) {
+                return "&#"+b.charCodeAt()+";" 
+            });
             if(this.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
                 this.fireEvent('sync', this, html);
@@ -662,12 +666,17 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     /**
      * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
      * to insert tRoo.
-     * @param {String} text
+     * @param {String} text | dom node.. 
      */
-    insertAtCursor : function(text){
+    insertAtCursor : function(text)
+    {
+        
+        
+        
         if(!this.activated){
             return;
         }
+        /*
         if(Roo.isIE){
             this.win.focus();
             var r = this.doc.selection.createRange();
@@ -676,10 +685,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 r.pasteHTML(text);
                 this.syncValue();
                 this.deferFocus();
+            
             }
-        }else if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
+            return;
+        }
+        */
+        if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
-            this.execCmd('InsertHTML', text);
+            
+            
+            // from jquery ui (MIT licenced)
+            var range, node;
+            var win = this.win;
+            
+            if (win.getSelection && win.getSelection().getRangeAt) {
+                range = win.getSelection().getRangeAt(0);
+                node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
+                range.insertNode(node);
+            } else if (win.document.selection && win.document.selection.createRange) {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                win.document.selection.createRange().pasteHTML(txt);
+            } else {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                this.execCmd('InsertHTML', txt);
+            } 
+            
+            this.syncValue();
+            
             this.deferFocus();
         }
     },
index df3f5e5..610a690 100644 (file)
@@ -330,6 +330,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     html: this.specialChars[i],
                     handler: function(a,b) {
                         editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+                        //editor.insertAtCursor(a.html);
                         
                     },
                     tabIndex:-1
diff --git a/Roo/lib/Color.js b/Roo/lib/Color.js
new file mode 100644 (file)
index 0000000..41b364a
--- /dev/null
@@ -0,0 +1,719 @@
+/*
+
+Colour.js
+
+Functions for colour handling and processing.
+
+http://www.safalra.com/web-design/javascript/colour-handling-and-processing/
+
+The author of this program, Safalra (Stephen Morley), irrevocably releases all
+rights to this program, with the intention of it becoming part of the public
+domain. Because this program is released into the public domain, it comes with
+no warranty either expressed or implied, to the extent permitted by law.
+
+For more free and public domain JavaScript code by the same author, visit:
+http://www.safalra.com/web-design/javascript/
+
+*/
+
+
+/* An abstract Colour implementation. Concrete Colour implementations should use
+ * an instance of this function as their prototype, and implement the getRGB and
+ * getHSL functions. getRGB should return an object representing the RGB
+ * components of this Colour, with the red, green, and blue components in the
+ * range [0,255] and the alpha component in the range [0,100]. getHSL should
+ * return an object representing the HSL components of this Colour, with the hue
+ * component in the range [0,360), the saturation and lightness components in
+ * the range [0,100], and the alpha component in the range [0,1].
+ */
+Roo.lib.Colour = function(){
+
+  /* Returns an object representing the RGBA components of this Colour. The red,
+   * green, and blue components are converted to integers in the range [0,255].
+   * The alpha is a value in the range [0,1].
+   */
+  this.getIntegerRGB = function(){
+
+    // get the RGB components of this colour
+    var rgb = this.getRGB();
+
+    // return the integer components
+    return {
+      'r' : Math.round(rgb.r),
+      'g' : Math.round(rgb.g),
+      'b' : Math.round(rgb.b),
+      'a' : rgb.a
+    };
+
+  };
+
+  /* Returns an object representing the RGBA components of this Colour. The red,
+   * green, and blue components are converted to numbers in the range [0,100].
+   * The alpha is a value in the range [0,1].
+   */
+  this.getPercentageRGB = function(){
+
+    // get the RGB components of this colour
+    var rgb = this.getRGB();
+
+    // return the percentage components
+    return {
+      'r' : 100 * rgb.r / 255,
+      'g' : 100 * rgb.g / 255,
+      'b' : 100 * rgb.b / 255,
+      'a' : rgb.a
+    };
+
+  };
+
+  /* Returns a string representing this Colour as a CSS hexadecimal RGB colour
+   * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
+   * are two-digit hexadecimal numbers.
+   */
+  this.getCSSHexadecimalRGB = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // determine the hexadecimal equivalents
+    var r16 = rgb.r.toString(16);
+    var g16 = rgb.g.toString(16);
+    var b16 = rgb.b.toString(16);
+
+    // return the CSS RGB colour value
+    return '#'
+        + (r16.length == 2 ? r16 : '0' + r16)
+        + (g16.length == 2 ? g16 : '0' + g16)
+        + (b16.length == 2 ? b16 : '0' + b16);
+
+  };
+
+  /* Returns a string representing this Colour as a CSS integer RGB colour
+   * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
+   * are integers in the range [0,255].
+   */
+  this.getCSSIntegerRGB = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // return the CSS RGB colour value
+    return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS integer RGBA colour
+   * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
+   * b are integers in the range [0,255] and a is in the range [0,1].
+   */
+  this.getCSSIntegerRGBA = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // return the CSS integer RGBA colour value
+    return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS percentage RGB colour
+   * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
+   * b are in the range [0,100].
+   */
+  this.getCSSPercentageRGB = function(){
+
+    // get the percentage RGB components
+    var rgb = this.getPercentageRGB();
+
+    // return the CSS RGB colour value
+    return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS percentage RGBA colour
+   * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
+   * and b are in the range [0,100] and a is in the range [0,1].
+   */
+  this.getCSSPercentageRGBA = function(){
+
+    // get the percentage RGB components
+    var rgb = this.getPercentageRGB();
+
+    // return the CSS percentage RGBA colour value
+    return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS HSL colour value - that
+   * is, a string of the form hsl(h,s%,l%) where h is in the range [0,100] and
+   * s and l are in the range [0,100].
+   */
+  this.getCSSHSL = function(){
+
+    // get the HSL components
+    var hsl = this.getHSL();
+
+    // return the CSS HSL colour value
+    return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS HSLA colour value - that
+   * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,100],
+   * s and l are in the range [0,100], and a is in the range [0,1].
+   */
+  this.getCSSHSLA = function(){
+
+    // get the HSL components
+    var hsl = this.getHSL();
+
+    // return the CSS HSL colour value
+    return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
+
+  };
+
+  /* Sets the colour of the specified node to this Colour. This functions sets
+   * the CSS 'color' property for the node. The parameter is:
+   *
+   * node - the node whose colour should be set
+   */
+  this.setNodeColour = function(node){
+
+    // set the colour of the node
+    node.style.color = this.getCSSHexadecimalRGB();
+
+  };
+
+  /* Sets the background colour of the specified node to this Colour. This
+   * functions sets the CSS 'background-color' property for the node. The
+   * parameter is:
+   *
+   * node - the node whose background colour should be set
+   */
+  this.setNodeBackgroundColour = function(node){
+
+    // set the background colour of the node
+    node.style.backgroundColor = this.getCSSHexadecimalRGB();
+
+  };
+  // convert between formats..
+  this.toRGB= function()
+  {
+    var r = this.getIntegerRGB();
+    return new Roo.lib.RGBColour(r.r,r.g,r.b,r.a);
+    
+  }
+  this.toHSL = function()
+  {
+     var hsl = this.getHSL();
+  // return the CSS HSL colour value
+    return new Roo.lib.HSLColour(hsl.h,  hsl.s, hsl.l ,  hsl.a );
+    
+  }
+  
+  this.toHSV = function()
+  {
+    var rgb = this.toRGB();
+    var hsv = rgb.getHSV();
+   // return the CSS HSL colour value
+    return new Roo.lib.HSVColour(hsv.h,  hsv.s, hsv.v ,  hsv.a );
+    
+  }
+  
+  // modify  v = 0 ... 1 (eg. 0.5)
+    this.saturate = function(v)
+    {
+        var rgb = this.toRGB();
+        var hsv = rgb.getHSV();
+        return new Roo.lib.HSVColour(hsv.h,  hsv.s * v, hsv.v ,  hsv.a );
+        
+    
+    }
+  
+   
+  
+
+}
+
+
+/* Creates a colour specified in the RGB colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * r - the red component, clipped to the range [0,255]
+ * g - the green component, clipped to the range [0,255]
+ * b - the blue component, clipped to the range [0,255]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+Roo.lib.RGBColour = function (r, g, b, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the RGB components after clipping them if necessary
+  var rgb =
+      {
+        'r' : Math.max(0, Math.min(255, r)),
+        'g' : Math.max(0, Math.min(255, g)),
+        'b' : Math.max(0, Math.min(255, b))
+      };
+
+  // initialise the HSV and HSL components to null
+  var hsv = null;
+  var hsl = null;
+
+  /* Returns the HSV or HSL hue component of this RGBColour. The hue is in the
+   * range [0,360). The parameters are:
+   *
+   * maximum - the maximum of the RGB component values
+   * range   - the range of the RGB component values
+   */
+  function getHue(maximum, range){
+
+    // check whether the range is zero
+    if (range == 0){
+
+      // set the hue to zero (any hue is acceptable as the colour is grey)
+      var hue = 0;
+
+    }else{
+
+      // determine which of the components has the highest value and set the hue
+      switch (maximum){
+
+        // red has the highest value
+        case rgb.r:
+          var hue = (rgb.g - rgb.b) / range * 60;
+          if (hue < 0) hue += 360;
+          break;
+
+        // green has the highest value
+        case rgb.g:
+          var hue = (rgb.b - rgb.r) / range * 60 + 120;
+          break;
+
+        // blue has the highest value
+        case rgb.b:
+          var hue = (rgb.r - rgb.g) / range * 60 + 240;
+          break;
+
+      }
+
+    }
+
+    // return the hue
+    return hue;
+
+  }
+
+  /* Calculates and stores the HSV components of this RGBColour so that they can
+   * be returned be the getHSV function.
+   */
+  function calculateHSV(){
+
+    // get the maximum and range of the RGB component values
+    var maximum = Math.max(rgb.r, rgb.g, rgb.b);
+    var range   = maximum - Math.min(rgb.r, rgb.g, rgb.b);
+
+    // store the HSV components
+    hsv =
+        {
+          'h' : getHue(maximum, range),
+          's' : (maximum == 0 ? 0 : 100 * range / maximum),
+          'v' : maximum / 2.55
+        };
+
+  }
+
+  /* Calculates and stores the HSL components of this RGBColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSL(){
+
+    // get the maximum and range of the RGB component values
+    var maximum = Math.max(rgb.r, rgb.g, rgb.b);
+    var range   = maximum - Math.min(rgb.r, rgb.g, rgb.b);
+
+    // determine the lightness in the range [0,1]
+    var l = maximum / 255 - range / 510;
+
+    // store the HSL components
+    hsl =
+        {
+          'h' : getHue(maximum, range),
+          's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
+          'l' : 100 * l
+        };
+
+  }
+
+  /* Returns the RGB and alpha components of this RGBColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this RGBColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // calculate the HSV components if necessary
+    if (hsv == null) calculateHSV();
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this RGBColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // calculate the HSV components if necessary
+    if (hsl == null) calculateHSL();
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
+Roo.lib.RGBColour.prototype = new Roo.lib.Colour();
+
+
+/* Creates a colour specified in the HSV colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * h - the hue component, wrapped to the range [0,360)
+ * s - the saturation component, clipped to the range [0,100]
+ * v - the value component, clipped to the range [0,100]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+Roo.lib.HSVColour = function (h, s, v, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the HSV components after clipping or wrapping them if necessary
+  var hsv =
+      {
+        'h' : (h % 360 + 360) % 360,
+        's' : Math.max(0, Math.min(100, s)),
+        'v' : Math.max(0, Math.min(100, v))
+      };
+
+  // initialise the RGB and HSL components to null
+  var rgb = null;
+  var hsl = null;
+
+  /* Calculates and stores the RGB components of this HSVColour so that they can
+   * be returned be the getRGB function.
+   */
+  function calculateRGB(){
+
+    // check whether the saturation is zero
+    if (hsv.s == 0){
+
+      // set the colour to the appropriate shade of grey
+      var r = hsv.v;
+      var g = hsv.v;
+      var b = hsv.v;
+
+    }else{
+
+      // set some temporary values
+      var f  = hsv.h / 60 - Math.floor(hsv.h / 60);
+      var p  = hsv.v * (1 - hsv.s / 100);
+      var q  = hsv.v * (1 - hsv.s / 100 * f);
+      var t  = hsv.v * (1 - hsv.s / 100 * (1 - f));
+
+      // set the RGB colour components to their temporary values
+      switch (Math.floor(hsv.h / 60)){
+        case 0: var r = hsv.v; var g = t; var b = p; break;
+        case 1: var r = q; var g = hsv.v; var b = p; break;
+        case 2: var r = p; var g = hsv.v; var b = t; break;
+        case 3: var r = p; var g = q; var b = hsv.v; break;
+        case 4: var r = t; var g = p; var b = hsv.v; break;
+        case 5: var r = hsv.v; var g = p; var b = q; break;
+      }
+
+    }
+
+    // store the RGB components
+    rgb =
+        {
+          'r' : r * 2.55,
+          'g' : g * 2.55,
+          'b' : b * 2.55
+        };
+
+  }
+
+  /* Calculates and stores the HSL components of this HSVColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSL(){
+
+    // determine the lightness in the range [0,100]
+    var l = (2 - hsv.s / 100) * hsv.v / 2;
+
+    // store the HSL components
+    hsl =
+        {
+          'h' : hsv.h,
+          's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
+          'l' : l
+        };
+
+    // correct a division-by-zero error
+    if (isNaN(hsl.s)) hsl.s = 0;
+
+  }
+
+  /* Returns the RGB and alpha components of this HSVColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // calculate the RGB components if necessary
+    if (rgb == null) calculateRGB();
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this HSVColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this HSVColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // calculate the HSL components if necessary
+    if (hsl == null) calculateHSL();
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
+Roo.lib.HSVColour.prototype = new Roo.lib.Colour();
+
+
+/* Creates a colour specified in the HSL colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * h - the hue component, wrapped to the range [0,360)
+ * s - the saturation component, clipped to the range [0,100]
+ * l - the lightness component, clipped to the range [0,100]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+
+Roo.lib.HSLColour = function(h, s, l, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the HSL components after clipping or wrapping them if necessary
+  var hsl =
+      {
+        'h' : (h % 360 + 360) % 360,
+        's' : Math.max(0, Math.min(100, s)),
+        'l' : Math.max(0, Math.min(100, l))
+      };
+
+  // initialise the RGB and HSV components to null
+  var rgb = null;
+  var hsv = null;
+
+  /* Calculates and stores the RGB components of this HSLColour so that they can
+   * be returned be the getRGB function.
+   */
+  function calculateRGB(){
+
+    // check whether the saturation is zero
+    if (hsl.s == 0){
+
+      // store the RGB components representing the appropriate shade of grey
+      rgb =
+          {
+            'r' : hsl.l * 2.55,
+            'g' : hsl.l * 2.55,
+            'b' : hsl.l * 2.55
+          };
+
+    }else{
+
+      // set some temporary values
+      var p = hsl.l < 50
+            ? hsl.l * (1 + hsl.s / 100)
+            : hsl.l + hsl.s - hsl.l * hsl.s / 100;
+      var q = 2 * hsl.l - p;
+
+      // initialise the RGB components
+      rgb =
+          {
+            'r' : (h + 120) / 60 % 6,
+            'g' : h / 60,
+            'b' : (h + 240) / 60 % 6
+          };
+
+      // loop over the RGB components
+      for (var key in rgb){
+
+        // ensure that the property is not inherited from the root object
+        if (rgb.hasOwnProperty(key)){
+
+          // set the component to its value in the range [0,100]
+          if (rgb[key] < 1){
+            rgb[key] = q + (p - q) * rgb[key];
+          }else if (rgb[key] < 3){
+            rgb[key] = p;
+          }else if (rgb[key] < 4){
+            rgb[key] = q + (p - q) * (4 - rgb[key]);
+          }else{
+            rgb[key] = q;
+          }
+
+          // set the component to its value in the range [0,255]
+          rgb[key] *= 2.55;
+
+        }
+
+      }
+
+    }
+
+  }
+
+  /* Calculates and stores the HSV components of this HSLColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSV(){
+
+    // set a temporary value
+    var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
+
+    // store the HSV components
+    hsv =
+        {
+          'h' : hsl.h,
+          's' : 200 * t / (hsl.l + t),
+          'v' : t + hsl.l
+        };
+
+    // correct a division-by-zero error
+    if (isNaN(hsv.s)) hsv.s = 0;
+
+  }
+
+  /* Returns the RGB and alpha components of this HSLColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // calculate the RGB components if necessary
+    if (rgb == null) calculateRGB();
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this HSLColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // calculate the HSV components if necessary
+    if (hsv == null) calculateHSV();
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this HSLColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
+Roo.lib.HSLColour.prototype = new Roo.lib.Colour();
\ No newline at end of file
index 9f2bf4a..b996903 100644 (file)
@@ -800,12 +800,12 @@ this.wrap=this.el.wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}});i
 this.frameId=Roo.id();this.createToolbar(this);var B=this.wrap.createChild({tag:'iframe',id:this.frameId,name:this.frameId,frameBorder:'no','src':Roo.SSL_SECURE_URL?Roo.SSL_SECURE_URL:"javascript:false"},this.el);this.iframe=B.dom;this.assignDocWin();this.doc.designMode='on';this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var C={run:function(){this.assignDocWin();if(this.doc.body||this.doc.readyState=='complete'){try{this.doc.designMode="on";}catch(e){return;}
 Roo.TaskMgr.stop(C);this.initEditor.defer(10,this);}},interval:10,duration:10000,scope:this};Roo.TaskMgr.start(C);if(!this.width){this.setSize(this.wrap.getSize());}if(this.resizeEl){this.resizeEl.resizeTo.defer(100,this.resizeEl,[this.width,this.height]);}},onResize:function(w,h){Roo.form.HtmlEditor.superclass.onResize.apply(this,arguments);if(this.el&&this.iframe){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr');this.el.setWidth(this.adjustWidth('textarea',aw));this.iframe.style.width=aw+'px';}if(typeof h=='number'){var A=0;for(var i=0;i<this.toolbars.length;i++){A+=this.toolbars[i].tb.el.getHeight();if(this.toolbars[i].footer){A+=this.toolbars[i].footer.el.getHeight();}}var ah=h-this.wrap.getFrameWidth('tb')-A;ah-=5;this.el.setHeight(this.adjustWidth('textarea',ah));this.iframe.style.height=ah+'px';if(this.doc){(this.doc.body||this.doc.documentElement).style.height=(ah-(this.iframePad*2))+'px';}}}},toggleSourceEdit:function(A){this.sourceEditMode=A===true;if(this.sourceEditMode){this.syncValue();this.iframe.className='x-hidden';this.el.removeClass('x-hidden');this.el.dom.removeAttribute('tabIndex');this.el.focus();}else {this.pushValue();this.iframe.className='';this.el.addClass('x-hidden');this.el.dom.setAttribute('tabIndex',-1);this.deferFocus();}
 this.setSize(this.wrap.getSize());this.fireEvent('editmodechange',this,this.sourceEditMode);},createLink:function(){var A=prompt(this.createLinkText,this.defaultLinkValue);if(A&&A!='http:/'+'/'){this.relayCmd('createlink',A);}},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.wrap;},getPositionEl:function(){return this.wrap;},initEvents:function(){this.originalValue=this.getValue();},markInvalid:Roo.emptyFn,clearInvalid:Roo.emptyFn,setValue:function(v){Roo.form.HtmlEditor.superclass.setValue.call(this,v);this.pushValue();},cleanHtml:function(A){A=String(A);if(A.length>5){if(Roo.isSafari){A=A.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,'');}}if(A=='&nbsp;'){A='';}return A;},syncValue:function(){if(this.initialized){var bd=(this.doc.body||this.doc.documentElement);var A=bd.innerHTML;if(Roo.isSafari){var bs=bd.getAttribute('style');var m=bs.match(/text-align:(.*?);/i);if(m&&m[1]){A='<div style="'+m[0]+'">'+A+'</div>';}}
-A=this.cleanHtml(A);if(this.fireEvent('beforesync',this,A)!==false){this.el.dom.value=A;this.fireEvent('sync',this,A);}}},pushValue:function(){if(this.initialized){var v=this.el.dom.value;if(v.length<1){v='&#160;';}if(this.fireEvent('beforepush',this,v)!==false){var d=(this.doc.body||this.doc.documentElement);d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else {this.el.focus();}},assignDocWin:function(){var A=this.iframe;if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}else {if(!Roo.get(this.frameId)){return;}
+A=this.cleanHtml(A);A=A.replace(/([\x80-\uffff])/g,function(a,b){return "&#"+b.charCodeAt()+";"});if(this.fireEvent('beforesync',this,A)!==false){this.el.dom.value=A;this.fireEvent('sync',this,A);}}},pushValue:function(){if(this.initialized){var v=this.el.dom.value;if(v.length<1){v='&#160;';}if(this.fireEvent('beforepush',this,v)!==false){var d=(this.doc.body||this.doc.documentElement);d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else {this.el.focus();}},assignDocWin:function(){var A=this.iframe;if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}else {if(!Roo.get(this.frameId)){return;}
 this.doc=(A.contentDocument||Roo.get(this.frameId).dom.document);this.win=Roo.get(this.frameId).dom.contentWindow;}},initEditor:function(){this.assignDocWin();this.doc.designMode="on";this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var A=(this.doc.body||this.doc.documentElement);var ss=this.el.getStyles('font-size','background-image','background-repeat');ss['background-attachment']='fixed';A.bgProperties='fixed';Roo.DomHelper.applyStyles(A,ss);Roo.EventManager.on(this.doc,{'mouseup':this.onEditorEvent,'dblclick':this.onEditorEvent,'click':this.onEditorEvent,'keyup':this.onEditorEvent,buffer:100,scope:this});if(Roo.isGecko){Roo.EventManager.on(this.doc,'keypress',this.mozKeyPress,this);}if(Roo.isIE||Roo.isSafari||Roo.isOpera){Roo.EventManager.on(this.doc,'keydown',this.fixKeys,this);}
 this.initialized=true;this.fireEvent('initialize',this);this.pushValue();},onDestroy:function(){if(this.rendered){for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onDestroy();}
 this.wrap.dom.innerHTML='';this.wrap.remove();}},onFirstFocus:function(){this.assignDocWin();this.activated=true;for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onFirstFocus();}if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);this.execCmd('styleWithCSS',false);}catch(e){}}
 this.fireEvent('activate',this);},adjustFont:function(A){var B=A.cmd=='increasefontsize'?1:-1;var v=parseInt(this.doc.queryCommandValue('FontSize')||3,10);if(Roo.isSafari){var sm={10:1,13:2,16:3,18:4,24:5,32:6,48:7};v=(v<10)?10:v;v=(v>48)?48:v;v=typeof(sm[v])=='undefined'?1:sm[v];}
-v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){this.execCmd("formatblock",tg);},insertText:function(A){range=this.createRange();range.deleteContents();range.insertNode(this.doc.createTextNode(A));},relayBtnCmd:function(A){this.relayCmd(A.cmd);},relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.fireEvent('editorevent',this);this.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;}if(Roo.isIE){this.win.focus();var r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML(A);this.syncValue();this.deferFocus();}}else if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();this.execCmd('InsertHTML',A);this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;case 'v':this.cleanUpPaste.defer(100,this);return;break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br />');r.collapse(false);r.select();}}}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}
+v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){this.execCmd("formatblock",tg);},insertText:function(A){range=this.createRange();range.deleteContents();range.insertNode(this.doc.createTextNode(A));},relayBtnCmd:function(A){this.relayCmd(A.cmd);},relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.fireEvent('editorevent',this);this.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;D.document.selection.createRange().pasteHTML(E);}else {var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;case 'v':this.cleanUpPaste.defer(100,this);return;break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br />');r.collapse(false);r.select();}}}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}
 a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}
 B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);continue;}if(!this.rangeIntersectsNode(A,ar[i])||(this.rangeCompareNode(A,ar[i])==0)){continue;}
 F=true;}if(!D.length&&E.length){D=E;}if(F||!D.length||(D.length>1)){return false;}return D[0];},createRange:function(A){if(typeof A!="undefined"){try{return A.getRangeAt?A.getRangeAt(0):A.createRange();}catch(e){return this.doc.createRange();}}else {return this.doc.createRange();}},getParentElement:function(){this.assignDocWin();var A=Roo.isIE?this.doc.selection:this.win.getSelection();var B=this.createRange(A);try{var p=B.commonAncestorContainer;while(p.nodeType==3){p=p.parentNode;}return p;}catch(e){return null;}},rangeIntersectsNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){nodeRange.selectNodeContents(node);}var D=A.cloneRange();D.collapse(true);var E=A.cloneRange();E.collapse(false);var F=C.cloneRange();F.collapse(true);var G=C.cloneRange();G.collapse(false);return D.compareBoundaryPoints(Range.START_TO_START,G)==-1&&E.compareBoundaryPoints(Range.START_TO_START,F)==1;},rangeCompareNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){nodeRange.selectNodeContents(node);}
index 55d4257..4c162c7 100644 (file)
@@ -39025,6 +39025,10 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             }
             html = this.cleanHtml(html);
+            // fix up the special chars..
+            html = html.replace(/([\x80-\uffff])/g, function (a, b) {
+                return "&#"+b.charCodeAt()+";" 
+            });
             if(this.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
                 this.fireEvent('sync', this, html);
@@ -39250,12 +39254,17 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     /**
      * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
      * to insert tRoo.
-     * @param {String} text
+     * @param {String} text | dom node.. 
      */
-    insertAtCursor : function(text){
+    insertAtCursor : function(text)
+    {
+        
+        
+        
         if(!this.activated){
             return;
         }
+        /*
         if(Roo.isIE){
             this.win.focus();
             var r = this.doc.selection.createRange();
@@ -39264,10 +39273,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 r.pasteHTML(text);
                 this.syncValue();
                 this.deferFocus();
+            
             }
-        }else if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
+            return;
+        }
+        */
+        if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
-            this.execCmd('InsertHTML', text);
+            
+            
+            // from jquery ui (MIT licenced)
+            var range, node;
+            var win = this.win;
+            
+            if (win.getSelection && win.getSelection().getRangeAt) {
+                range = win.getSelection().getRangeAt(0);
+                node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
+                range.insertNode(node);
+            } else if (win.document.selection && win.document.selection.createRange) {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                win.document.selection.createRange().pasteHTML(txt);
+            } else {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                this.execCmd('InsertHTML', txt);
+            } 
+            
+            this.syncValue();
+            
             this.deferFocus();
         }
     },
@@ -40193,6 +40227,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     html: this.specialChars[i],
                     handler: function(a,b) {
                         editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+                        //editor.insertAtCursor(a.html);
                         
                     },
                     tabIndex:-1
index 8372437..908dfc3 100644 (file)
@@ -24564,6 +24564,10 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             }
             html = this.cleanHtml(html);
+            // fix up the special chars..
+            html = html.replace(/([\x80-\uffff])/g, function (a, b) {
+                return "&#"+b.charCodeAt()+";" 
+            });
             if(this.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
                 this.fireEvent('sync', this, html);
@@ -24789,12 +24793,17 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     /**
      * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
      * to insert tRoo.
-     * @param {String} text
+     * @param {String} text | dom node.. 
      */
-    insertAtCursor : function(text){
+    insertAtCursor : function(text)
+    {
+        
+        
+        
         if(!this.activated){
             return;
         }
+        /*
         if(Roo.isIE){
             this.win.focus();
             var r = this.doc.selection.createRange();
@@ -24803,10 +24812,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 r.pasteHTML(text);
                 this.syncValue();
                 this.deferFocus();
+            
             }
-        }else if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
+            return;
+        }
+        */
+        if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
-            this.execCmd('InsertHTML', text);
+            
+            
+            // from jquery ui (MIT licenced)
+            var range, node;
+            var win = this.win;
+            
+            if (win.getSelection && win.getSelection().getRangeAt) {
+                range = win.getSelection().getRangeAt(0);
+                node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
+                range.insertNode(node);
+            } else if (win.document.selection && win.document.selection.createRange) {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                win.document.selection.createRange().pasteHTML(txt);
+            } else {
+                // no firefox support
+                var txt = typeof(text) == 'string' ? text : text.outerHTML;
+                this.execCmd('InsertHTML', txt);
+            } 
+            
+            this.syncValue();
+            
             this.deferFocus();
         }
     },
@@ -25732,6 +25766,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     html: this.specialChars[i],
                     handler: function(a,b) {
                         editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+                        //editor.insertAtCursor(a.html);
                         
                     },
                     tabIndex:-1
index dece01d..69bf949 100644 (file)
@@ -552,12 +552,12 @@ this.wrap=this.el.wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}});i
 this.frameId=Roo.id();this.createToolbar(this);var B=this.wrap.createChild({tag:'iframe',id:this.frameId,name:this.frameId,frameBorder:'no','src':Roo.SSL_SECURE_URL?Roo.SSL_SECURE_URL:"javascript:false"},this.el);this.iframe=B.dom;this.assignDocWin();this.doc.designMode='on';this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var C={run:function(){this.assignDocWin();if(this.doc.body||this.doc.readyState=='complete'){try{this.doc.designMode="on";}catch(e){return;}
 Roo.TaskMgr.stop(C);this.initEditor.defer(10,this);}},interval:10,duration:10000,scope:this};Roo.TaskMgr.start(C);if(!this.width){this.setSize(this.wrap.getSize());}if(this.resizeEl){this.resizeEl.resizeTo.defer(100,this.resizeEl,[this.width,this.height]);}},onResize:function(w,h){Roo.form.HtmlEditor.superclass.onResize.apply(this,arguments);if(this.el&&this.iframe){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr');this.el.setWidth(this.adjustWidth('textarea',aw));this.iframe.style.width=aw+'px';}if(typeof h=='number'){var A=0;for(var i=0;i<this.toolbars.length;i++){A+=this.toolbars[i].tb.el.getHeight();if(this.toolbars[i].footer){A+=this.toolbars[i].footer.el.getHeight();}}var ah=h-this.wrap.getFrameWidth('tb')-A;ah-=5;this.el.setHeight(this.adjustWidth('textarea',ah));this.iframe.style.height=ah+'px';if(this.doc){(this.doc.body||this.doc.documentElement).style.height=(ah-(this.iframePad*2))+'px';}}}},toggleSourceEdit:function(A){this.sourceEditMode=A===true;if(this.sourceEditMode){this.syncValue();this.iframe.className='x-hidden';this.el.removeClass('x-hidden');this.el.dom.removeAttribute('tabIndex');this.el.focus();}else {this.pushValue();this.iframe.className='';this.el.addClass('x-hidden');this.el.dom.setAttribute('tabIndex',-1);this.deferFocus();}
 this.setSize(this.wrap.getSize());this.fireEvent('editmodechange',this,this.sourceEditMode);},createLink:function(){var A=prompt(this.createLinkText,this.defaultLinkValue);if(A&&A!='http:/'+'/'){this.relayCmd('createlink',A);}},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.wrap;},getPositionEl:function(){return this.wrap;},initEvents:function(){this.originalValue=this.getValue();},markInvalid:Roo.emptyFn,clearInvalid:Roo.emptyFn,setValue:function(v){Roo.form.HtmlEditor.superclass.setValue.call(this,v);this.pushValue();},cleanHtml:function(A){A=String(A);if(A.length>5){if(Roo.isSafari){A=A.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,'');}}if(A=='&nbsp;'){A='';}return A;},syncValue:function(){if(this.initialized){var bd=(this.doc.body||this.doc.documentElement);var A=bd.innerHTML;if(Roo.isSafari){var bs=bd.getAttribute('style');var m=bs.match(/text-align:(.*?);/i);if(m&&m[1]){A='<div style="'+m[0]+'">'+A+'</div>';}}
-A=this.cleanHtml(A);if(this.fireEvent('beforesync',this,A)!==false){this.el.dom.value=A;this.fireEvent('sync',this,A);}}},pushValue:function(){if(this.initialized){var v=this.el.dom.value;if(v.length<1){v='&#160;';}if(this.fireEvent('beforepush',this,v)!==false){var d=(this.doc.body||this.doc.documentElement);d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else {this.el.focus();}},assignDocWin:function(){var A=this.iframe;if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}else {if(!Roo.get(this.frameId)){return;}
+A=this.cleanHtml(A);A=A.replace(/([\x80-\uffff])/g,function(a,b){return "&#"+b.charCodeAt()+";"});if(this.fireEvent('beforesync',this,A)!==false){this.el.dom.value=A;this.fireEvent('sync',this,A);}}},pushValue:function(){if(this.initialized){var v=this.el.dom.value;if(v.length<1){v='&#160;';}if(this.fireEvent('beforepush',this,v)!==false){var d=(this.doc.body||this.doc.documentElement);d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else {this.el.focus();}},assignDocWin:function(){var A=this.iframe;if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}else {if(!Roo.get(this.frameId)){return;}
 this.doc=(A.contentDocument||Roo.get(this.frameId).dom.document);this.win=Roo.get(this.frameId).dom.contentWindow;}},initEditor:function(){this.assignDocWin();this.doc.designMode="on";this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var A=(this.doc.body||this.doc.documentElement);var ss=this.el.getStyles('font-size','background-image','background-repeat');ss['background-attachment']='fixed';A.bgProperties='fixed';Roo.DomHelper.applyStyles(A,ss);Roo.EventManager.on(this.doc,{'mouseup':this.onEditorEvent,'dblclick':this.onEditorEvent,'click':this.onEditorEvent,'keyup':this.onEditorEvent,buffer:100,scope:this});if(Roo.isGecko){Roo.EventManager.on(this.doc,'keypress',this.mozKeyPress,this);}if(Roo.isIE||Roo.isSafari||Roo.isOpera){Roo.EventManager.on(this.doc,'keydown',this.fixKeys,this);}
 this.initialized=true;this.fireEvent('initialize',this);this.pushValue();},onDestroy:function(){if(this.rendered){for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onDestroy();}
 this.wrap.dom.innerHTML='';this.wrap.remove();}},onFirstFocus:function(){this.assignDocWin();this.activated=true;for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onFirstFocus();}if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);this.execCmd('styleWithCSS',false);}catch(e){}}
 this.fireEvent('activate',this);},adjustFont:function(A){var B=A.cmd=='increasefontsize'?1:-1;var v=parseInt(this.doc.queryCommandValue('FontSize')||3,10);if(Roo.isSafari){var sm={10:1,13:2,16:3,18:4,24:5,32:6,48:7};v=(v<10)?10:v;v=(v>48)?48:v;v=typeof(sm[v])=='undefined'?1:sm[v];}
-v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){this.execCmd("formatblock",tg);},insertText:function(A){range=this.createRange();range.deleteContents();range.insertNode(this.doc.createTextNode(A));},relayBtnCmd:function(A){this.relayCmd(A.cmd);},relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.fireEvent('editorevent',this);this.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;}if(Roo.isIE){this.win.focus();var r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML(A);this.syncValue();this.deferFocus();}}else if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();this.execCmd('InsertHTML',A);this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;case 'v':this.cleanUpPaste.defer(100,this);return;break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br />');r.collapse(false);r.select();}}}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}
+v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){this.execCmd("formatblock",tg);},insertText:function(A){range=this.createRange();range.deleteContents();range.insertNode(this.doc.createTextNode(A));},relayBtnCmd:function(A){this.relayCmd(A.cmd);},relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.fireEvent('editorevent',this);this.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;D.document.selection.createRange().pasteHTML(E);}else {var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;case 'v':this.cleanUpPaste.defer(100,this);return;break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br />');r.collapse(false);r.select();}}}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}if(String.fromCharCode(k).toLowerCase()=='v'){this.cleanUpPaste.defer(100,this);return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}
 a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}
 B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);continue;}if(!this.rangeIntersectsNode(A,ar[i])||(this.rangeCompareNode(A,ar[i])==0)){continue;}
 F=true;}if(!D.length&&E.length){D=E;}if(F||!D.length||(D.length>1)){return false;}return D[0];},createRange:function(A){if(typeof A!="undefined"){try{return A.getRangeAt?A.getRangeAt(0):A.createRange();}catch(e){return this.doc.createRange();}}else {return this.doc.createRange();}},getParentElement:function(){this.assignDocWin();var A=Roo.isIE?this.doc.selection:this.win.getSelection();var B=this.createRange(A);try{var p=B.commonAncestorContainer;while(p.nodeType==3){p=p.parentNode;}return p;}catch(e){return null;}},rangeIntersectsNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){nodeRange.selectNodeContents(node);}var D=A.cloneRange();D.collapse(true);var E=A.cloneRange();E.collapse(false);var F=C.cloneRange();F.collapse(true);var G=C.cloneRange();G.collapse(false);return D.compareBoundaryPoints(Range.START_TO_START,G)==-1&&E.compareBoundaryPoints(Range.START_TO_START,F)==1;},rangeCompareNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){nodeRange.selectNodeContents(node);}