bootsy 2.0.8 → 2.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a690695a8fe4970f189b8f070ec20a95a9a64102
4
- data.tar.gz: ec879d16e88ec7f56fff78bc5f1351ef08848246
3
+ metadata.gz: 0700c9ebccb580e9c29f62368ff77fd0f1653a6f
4
+ data.tar.gz: b2c537eb973c476363fbd6bf771c8841ba9e3a9b
5
5
  SHA512:
6
- metadata.gz: 10b8ff7d3b323ebb9e647ee150f4ca7d53132e8c395ff65be57063886e0d668340283b35dcadf739ad9a7d564aad31c7b4eecd8c44f07594f8bf3c90b2b51b86
7
- data.tar.gz: 15f0b8bdf3f6d417537904fb238ec74255c9bc29e1e95234b919d2b828e427b5b964295cb9c11d8af3e222df503b22f2bed6e57ef4b56e50a9aa770795c3449f
6
+ metadata.gz: ace2b6003ce07536e4993dc83a4dfd693b4da7e7ea6abc1987682e5a2cc4603eb7be47cef062b04761c9a82b837aaf7764f9867ad4b11cb3923531e68912da47
7
+ data.tar.gz: ecddbe09bc4c69e46550e254bab66de1736dec64ba15790ba2b1024f6d63f1411048dcc92a938c395da210d2d28e98eef21be6816473f9c2742e6519882553c9
data/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  * Ruby `2` or `1.9.3`;
20
20
  * ImageMagick or GraphicsMagick (for MiniMagick);
21
- * Rails `4.0`;
21
+ * Rails `4`;
22
22
  * [Bootstrap `3`](http://getbootstrap.com/) properly added to your application.
23
23
 
24
24
 
@@ -10,7 +10,7 @@
10
10
  */
11
11
  var wysihtml5 = {
12
12
  version: "0.3.0",
13
-
13
+
14
14
  // namespaces
15
15
  commands: {},
16
16
  dom: {},
@@ -19,14 +19,14 @@ var wysihtml5 = {
19
19
  lang: {},
20
20
  selection: {},
21
21
  views: {},
22
-
22
+
23
23
  INVISIBLE_SPACE: "\uFEFF",
24
-
24
+
25
25
  EMPTY_FUNCTION: function() {},
26
-
26
+
27
27
  ELEMENT_NODE: 1,
28
28
  TEXT_NODE: 3,
29
-
29
+
30
30
  BACKSPACE_KEY: 8,
31
31
  ENTER_KEY: 13,
32
32
  ESCAPE_KEY: 27,
@@ -701,7 +701,7 @@ rangy.createModule("DomUtil", function(api, module) {
701
701
  var dom = api.dom;
702
702
  var DomPosition = dom.DomPosition;
703
703
  var DOMException = api.DOMException;
704
-
704
+
705
705
  /*----------------------------------------------------------------------------------------------------------------*/
706
706
 
707
707
  // Utility functions
@@ -2972,7 +2972,8 @@ rangy.createModule("DomUtil", function(api, module) {
2972
2972
  if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {
2973
2973
  updateControlSelection(sel);
2974
2974
  } else {
2975
- sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;
2975
+ // patched for FF here - @glebm
2976
+ sel._ranges.length = sel.rangeCount = (sel.nativeSelection ? sel.nativeSelection.rangeCount : 0);
2976
2977
  if (sel.rangeCount) {
2977
2978
  for (var i = 0, len = sel.rangeCount; i < len; ++i) {
2978
2979
  sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));
@@ -3255,7 +3256,7 @@ var Base = function() {
3255
3256
 
3256
3257
  Base.extend = function(_instance, _static) { // subclass
3257
3258
  var extend = Base.prototype.extend;
3258
-
3259
+
3259
3260
  // build the prototype
3260
3261
  Base._prototyping = true;
3261
3262
  var proto = new this;
@@ -3264,7 +3265,7 @@ Base.extend = function(_instance, _static) { // subclass
3264
3265
  // call this method from any other method to invoke that method's ancestor
3265
3266
  };
3266
3267
  delete Base._prototyping;
3267
-
3268
+
3268
3269
  // create the wrapper for the constructor function
3269
3270
  //var constructor = proto.constructor.valueOf(); //-dean
3270
3271
  var constructor = proto.constructor;
@@ -3279,7 +3280,7 @@ Base.extend = function(_instance, _static) { // subclass
3279
3280
  }
3280
3281
  }
3281
3282
  };
3282
-
3283
+
3283
3284
  // build the class interface
3284
3285
  klass.ancestor = this;
3285
3286
  klass.extend = this.extend;
@@ -3297,7 +3298,7 @@ Base.extend = function(_instance, _static) { // subclass
3297
3298
  return klass;
3298
3299
  };
3299
3300
 
3300
- Base.prototype = {
3301
+ Base.prototype = {
3301
3302
  extend: function(source, value) {
3302
3303
  if (arguments.length > 1) { // extending with a name/value pair
3303
3304
  var ancestor = this[source];
@@ -3356,7 +3357,7 @@ Base = Base.extend({
3356
3357
  }, {
3357
3358
  ancestor: Object,
3358
3359
  version: "1.1",
3359
-
3360
+
3360
3361
  forEach: function(object, block, context) {
3361
3362
  for (var key in object) {
3362
3363
  if (this.prototype[key] === undefined) {
@@ -3364,7 +3365,7 @@ Base = Base.extend({
3364
3365
  }
3365
3366
  }
3366
3367
  },
3367
-
3368
+
3368
3369
  implement: function() {
3369
3370
  for (var i = 0; i < arguments.length; i++) {
3370
3371
  if (typeof arguments[i] == "function") {
@@ -3377,7 +3378,7 @@ Base = Base.extend({
3377
3378
  }
3378
3379
  return this;
3379
3380
  },
3380
-
3381
+
3381
3382
  toString: function() {
3382
3383
  return String(this.valueOf());
3383
3384
  }
@@ -3393,15 +3394,15 @@ wysihtml5.browser = (function() {
3393
3394
  isWebKit = userAgent.indexOf("AppleWebKit/") !== -1,
3394
3395
  isChrome = userAgent.indexOf("Chrome/") !== -1,
3395
3396
  isOpera = userAgent.indexOf("Opera/") !== -1;
3396
-
3397
+
3397
3398
  function iosVersion(userAgent) {
3398
3399
  return ((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [, 0])[1];
3399
3400
  }
3400
-
3401
+
3401
3402
  return {
3402
3403
  // Static variable needed, publicly accessible, to be able override it in unit tests
3403
3404
  USER_AGENT: userAgent,
3404
-
3405
+
3405
3406
  /**
3406
3407
  * Exclude browsers that are not capable of displaying and handling
3407
3408
  * contentEditable as desired:
@@ -3420,22 +3421,22 @@ wysihtml5.browser = (function() {
3420
3421
  hasQuerySelectorSupport = document.querySelector && document.querySelectorAll,
3421
3422
  // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)
3422
3423
  isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1;
3423
-
3424
+
3424
3425
  return hasContentEditableSupport
3425
3426
  && hasEditingApiSupport
3426
3427
  && hasQuerySelectorSupport
3427
3428
  && !isIncompatibleMobileBrowser;
3428
3429
  },
3429
-
3430
+
3430
3431
  isTouchDevice: function() {
3431
3432
  return this.supportsEvent("touchmove");
3432
3433
  },
3433
-
3434
+
3434
3435
  isIos: function() {
3435
3436
  var userAgent = this.USER_AGENT.toLowerCase();
3436
3437
  return userAgent.indexOf("webkit") !== -1 && userAgent.indexOf("mobile") !== -1;
3437
3438
  },
3438
-
3439
+
3439
3440
  /**
3440
3441
  * Whether the browser supports sandboxed iframes
3441
3442
  * Currently only IE 6+ offers such feature <iframe security="restricted">
@@ -3474,7 +3475,7 @@ wysihtml5.browser = (function() {
3474
3475
  hasCurrentStyleProperty: function() {
3475
3476
  return "currentStyle" in testElement;
3476
3477
  },
3477
-
3478
+
3478
3479
  /**
3479
3480
  * Firefox on OSX navigates through history when hitting CMD + Arrow right/left
3480
3481
  */
@@ -3506,7 +3507,7 @@ wysihtml5.browser = (function() {
3506
3507
  supportsEventsInIframeCorrectly: function() {
3507
3508
  return !isOpera;
3508
3509
  },
3509
-
3510
+
3510
3511
  /**
3511
3512
  * Everything below IE9 doesn't know how to treat HTML5 tags
3512
3513
  *
@@ -3545,7 +3546,7 @@ wysihtml5.browser = (function() {
3545
3546
  "insertUnorderedList": isIE || isOpera || isWebKit,
3546
3547
  "insertOrderedList": isIE || isOpera || isWebKit
3547
3548
  };
3548
-
3549
+
3549
3550
  // Firefox throws errors for queryCommandSupported, so we have to build up our own object of supported commands
3550
3551
  var supported = {
3551
3552
  "insertHTML": isGecko
@@ -3662,14 +3663,14 @@ wysihtml5.browser = (function() {
3662
3663
  supportsSelectionModify: function() {
3663
3664
  return "getSelection" in window && "modify" in window.getSelection();
3664
3665
  },
3665
-
3666
+
3666
3667
  /**
3667
3668
  * Opera needs a white space after a <br> in order to position the caret correctly
3668
3669
  */
3669
3670
  needsSpaceAfterLineBreak: function() {
3670
3671
  return isOpera;
3671
3672
  },
3672
-
3673
+
3673
3674
  /**
3674
3675
  * Whether the browser supports the speech api on the given element
3675
3676
  * See http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
@@ -3684,7 +3685,7 @@ wysihtml5.browser = (function() {
3684
3685
  var chromeVersion = userAgent.match(/Chrome\/(\d+)/) || [, 0];
3685
3686
  return chromeVersion[1] >= 11 && ("onwebkitspeechchange" in input || "speech" in input);
3686
3687
  },
3687
-
3688
+
3688
3689
  /**
3689
3690
  * IE9 crashes when setting a getter via Object.defineProperty on XMLHttpRequest or XDomainRequest
3690
3691
  * See https://connect.microsoft.com/ie/feedback/details/650112
@@ -3693,21 +3694,21 @@ wysihtml5.browser = (function() {
3693
3694
  crashesWhenDefineProperty: function(property) {
3694
3695
  return isIE && (property === "XMLHttpRequest" || property === "XDomainRequest");
3695
3696
  },
3696
-
3697
+
3697
3698
  /**
3698
3699
  * IE is the only browser who fires the "focus" event not immediately when .focus() is called on an element
3699
3700
  */
3700
3701
  doesAsyncFocus: function() {
3701
3702
  return isIE;
3702
3703
  },
3703
-
3704
+
3704
3705
  /**
3705
3706
  * In IE it's impssible for the user and for the selection library to set the caret after an <img> when it's the lastChild in the document
3706
3707
  */
3707
3708
  hasProblemsSettingCaretAfterImg: function() {
3708
3709
  return isIE;
3709
3710
  },
3710
-
3711
+
3711
3712
  hasUndoInContextMenu: function() {
3712
3713
  return isGecko || isChrome || isOpera;
3713
3714
  }
@@ -3731,7 +3732,7 @@ wysihtml5.browser = (function() {
3731
3732
  return false;
3732
3733
  }
3733
3734
  },
3734
-
3735
+
3735
3736
  /**
3736
3737
  * Substract one array from another
3737
3738
  *
@@ -3751,10 +3752,10 @@ wysihtml5.browser = (function() {
3751
3752
  }
3752
3753
  return newArr;
3753
3754
  },
3754
-
3755
+
3755
3756
  /**
3756
3757
  * Return a clean native array
3757
- *
3758
+ *
3758
3759
  * Following will convert a Live NodeList to a proper Array
3759
3760
  * @example
3760
3761
  * var childNodes = wysihtml5.lang.array(document.body.childNodes).get();
@@ -3825,11 +3826,11 @@ wysihtml5.browser = (function() {
3825
3826
  }
3826
3827
  return this;
3827
3828
  },
3828
-
3829
+
3829
3830
  get: function() {
3830
3831
  return obj;
3831
3832
  },
3832
-
3833
+
3833
3834
  /**
3834
3835
  * @example
3835
3836
  * wysihtml5.lang.object({ foo: 1 }).clone();
@@ -3843,7 +3844,7 @@ wysihtml5.browser = (function() {
3843
3844
  }
3844
3845
  return newObj;
3845
3846
  },
3846
-
3847
+
3847
3848
  /**
3848
3849
  * @example
3849
3850
  * wysihtml5.lang.object([]).isArray();
@@ -3867,7 +3868,7 @@ wysihtml5.browser = (function() {
3867
3868
  trim: function() {
3868
3869
  return str.replace(WHITE_SPACE_START, "").replace(WHITE_SPACE_END, "");
3869
3870
  },
3870
-
3871
+
3871
3872
  /**
3872
3873
  * @example
3873
3874
  * wysihtml5.lang.string("Hello #{name}").interpolate({ name: "Christopher" });
@@ -3879,7 +3880,7 @@ wysihtml5.browser = (function() {
3879
3880
  }
3880
3881
  return str;
3881
3882
  },
3882
-
3883
+
3883
3884
  /**
3884
3885
  * @example
3885
3886
  * wysihtml5.lang.string("Hello Tom").replace("Tom").with("Hans");
@@ -3923,7 +3924,7 @@ wysihtml5.browser = (function() {
3923
3924
  TRAILING_CHAR_REG_EXP = /([^\w\/\-](,?))$/i,
3924
3925
  MAX_DISPLAY_LENGTH = 100,
3925
3926
  BRACKETS = { ")": "(", "]": "[", "}": "{" };
3926
-
3927
+
3927
3928
  function autoLink(element) {
3928
3929
  if (_hasParentThatShouldBeIgnored(element)) {
3929
3930
  return element;
@@ -3935,7 +3936,7 @@ wysihtml5.browser = (function() {
3935
3936
 
3936
3937
  return _parseNode(element);
3937
3938
  }
3938
-
3939
+
3939
3940
  /**
3940
3941
  * This is basically a rebuild of
3941
3942
  * the rails auto_link_urls text helper
@@ -3959,11 +3960,11 @@ wysihtml5.browser = (function() {
3959
3960
  if (realUrl.substr(0, 4) === "www.") {
3960
3961
  realUrl = "http://" + realUrl;
3961
3962
  }
3962
-
3963
+
3963
3964
  return '<a href="' + realUrl + '">' + displayUrl + '</a>' + punctuation;
3964
3965
  });
3965
3966
  }
3966
-
3967
+
3967
3968
  /**
3968
3969
  * Creates or (if already cached) returns a temp element
3969
3970
  * for the given document object
@@ -3975,26 +3976,26 @@ wysihtml5.browser = (function() {
3975
3976
  }
3976
3977
  return tempElement;
3977
3978
  }
3978
-
3979
+
3979
3980
  /**
3980
3981
  * Replaces the original text nodes with the newly auto-linked dom tree
3981
3982
  */
3982
3983
  function _wrapMatchesInNode(textNode) {
3983
3984
  var parentNode = textNode.parentNode,
3984
3985
  tempElement = _getTempElement(parentNode.ownerDocument);
3985
-
3986
+
3986
3987
  // We need to insert an empty/temporary <span /> to fix IE quirks
3987
3988
  // Elsewise IE would strip white space in the beginning
3988
3989
  tempElement.innerHTML = "<span></span>" + _convertUrlsToLinks(textNode.data);
3989
3990
  tempElement.removeChild(tempElement.firstChild);
3990
-
3991
+
3991
3992
  while (tempElement.firstChild) {
3992
3993
  // inserts tempElement.firstChild before textNode
3993
3994
  parentNode.insertBefore(tempElement.firstChild, textNode);
3994
3995
  }
3995
3996
  parentNode.removeChild(textNode);
3996
3997
  }
3997
-
3998
+
3998
3999
  function _hasParentThatShouldBeIgnored(node) {
3999
4000
  var nodeName;
4000
4001
  while (node.parentNode) {
@@ -4008,35 +4009,35 @@ wysihtml5.browser = (function() {
4008
4009
  }
4009
4010
  return false;
4010
4011
  }
4011
-
4012
+
4012
4013
  function _parseNode(element) {
4013
4014
  if (IGNORE_URLS_IN.contains(element.nodeName)) {
4014
4015
  return;
4015
4016
  }
4016
-
4017
+
4017
4018
  if (element.nodeType === wysihtml5.TEXT_NODE && element.data.match(URL_REG_EXP)) {
4018
4019
  _wrapMatchesInNode(element);
4019
4020
  return;
4020
4021
  }
4021
-
4022
+
4022
4023
  var childNodes = wysihtml5.lang.array(element.childNodes).get(),
4023
4024
  childNodesLength = childNodes.length,
4024
4025
  i = 0;
4025
-
4026
+
4026
4027
  for (; i<childNodesLength; i++) {
4027
4028
  _parseNode(childNodes[i]);
4028
4029
  }
4029
-
4030
+
4030
4031
  return element;
4031
4032
  }
4032
-
4033
+
4033
4034
  wysihtml5.dom.autoLink = autoLink;
4034
-
4035
+
4035
4036
  // Reveal url reg exp to the outside
4036
4037
  wysihtml5.dom.autoLink.URL_REG_EXP = URL_REG_EXP;
4037
4038
  })(wysihtml5);(function(wysihtml5) {
4038
4039
  var api = wysihtml5.dom;
4039
-
4040
+
4040
4041
  api.addClass = function(element, className) {
4041
4042
  var classList = element.classList;
4042
4043
  if (classList) {
@@ -4047,22 +4048,22 @@ wysihtml5.browser = (function() {
4047
4048
  }
4048
4049
  element.className += " " + className;
4049
4050
  };
4050
-
4051
+
4051
4052
  api.removeClass = function(element, className) {
4052
4053
  var classList = element.classList;
4053
4054
  if (classList) {
4054
4055
  return classList.remove(className);
4055
4056
  }
4056
-
4057
+
4057
4058
  element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ");
4058
4059
  };
4059
-
4060
+
4060
4061
  api.hasClass = function(element, className) {
4061
4062
  var classList = element.classList;
4062
4063
  if (classList) {
4063
4064
  return classList.contains(className);
4064
4065
  }
4065
-
4066
+
4066
4067
  var elementClassName = element.className;
4067
4068
  return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
4068
4069
  };
@@ -4114,17 +4115,17 @@ wysihtml5.dom.convertToList = (function() {
4114
4115
  list.appendChild(listItem);
4115
4116
  return listItem;
4116
4117
  }
4117
-
4118
+
4118
4119
  function _createList(doc, type) {
4119
4120
  return doc.createElement(type);
4120
4121
  }
4121
-
4122
+
4122
4123
  function convertToList(element, listType) {
4123
4124
  if (element.nodeName === "UL" || element.nodeName === "OL" || element.nodeName === "MENU") {
4124
4125
  // Already a list
4125
4126
  return element;
4126
4127
  }
4127
-
4128
+
4128
4129
  var doc = element.ownerDocument,
4129
4130
  list = _createList(doc, listType),
4130
4131
  lineBreaks = element.querySelectorAll("br"),
@@ -4138,7 +4139,7 @@ wysihtml5.dom.convertToList = (function() {
4138
4139
  isLineBreak,
4139
4140
  currentListItem,
4140
4141
  i;
4141
-
4142
+
4142
4143
  // First find <br> at the end of inline elements and move them behind them
4143
4144
  for (i=0; i<lineBreaksLength; i++) {
4144
4145
  lineBreak = lineBreaks[i];
@@ -4150,16 +4151,16 @@ wysihtml5.dom.convertToList = (function() {
4150
4151
  wysihtml5.dom.insert(lineBreak).after(lineBreak.parentNode);
4151
4152
  }
4152
4153
  }
4153
-
4154
+
4154
4155
  childNodes = wysihtml5.lang.array(element.childNodes).get();
4155
4156
  childNodesLength = childNodes.length;
4156
-
4157
+
4157
4158
  for (i=0; i<childNodesLength; i++) {
4158
4159
  currentListItem = currentListItem || _createListItem(doc, list);
4159
4160
  childNode = childNodes[i];
4160
4161
  isBlockElement = wysihtml5.dom.getStyle("display").from(childNode) === "block";
4161
4162
  isLineBreak = childNode.nodeName === "BR";
4162
-
4163
+
4163
4164
  if (isBlockElement) {
4164
4165
  // Append blockElement to current <li> if empty, otherwise create a new one
4165
4166
  currentListItem = currentListItem.firstChild ? _createListItem(doc, list) : currentListItem;
@@ -4167,27 +4168,27 @@ wysihtml5.dom.convertToList = (function() {
4167
4168
  currentListItem = null;
4168
4169
  continue;
4169
4170
  }
4170
-
4171
+
4171
4172
  if (isLineBreak) {
4172
4173
  // Only create a new list item in the next iteration when the current one has already content
4173
4174
  currentListItem = currentListItem.firstChild ? null : currentListItem;
4174
4175
  continue;
4175
4176
  }
4176
-
4177
+
4177
4178
  currentListItem.appendChild(childNode);
4178
4179
  }
4179
-
4180
+
4180
4181
  element.parentNode.replaceChild(list, element);
4181
4182
  return list;
4182
4183
  }
4183
-
4184
+
4184
4185
  return convertToList;
4185
4186
  })();/**
4186
4187
  * Copy a set of attributes from one element to another
4187
4188
  *
4188
4189
  * @param {Array} attributesToCopy List of attributes which should be copied
4189
4190
  * @return {Object} Returns an object which offers the "from" method which can be invoked with the element where to
4190
- * copy the attributes from., this again returns an object which provides a method named "to" which can be invoked
4191
+ * copy the attributes from., this again returns an object which provides a method named "to" which can be invoked
4191
4192
  * with the element where to copy the attributes to (see example)
4192
4193
  *
4193
4194
  * @example
@@ -4225,7 +4226,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4225
4226
  *
4226
4227
  * @param {Array} stylesToCopy List of styles which should be copied
4227
4228
  * @return {Object} Returns an object which offers the "from" method which can be invoked with the element where to
4228
- * copy the styles from., this again returns an object which provides a method named "to" which can be invoked
4229
+ * copy the styles from., this again returns an object which provides a method named "to" which can be invoked
4229
4230
  * with the element where to copy the styles to (see example)
4230
4231
  *
4231
4232
  * @example
@@ -4236,21 +4237,21 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4236
4237
  *
4237
4238
  */
4238
4239
  (function(dom) {
4239
-
4240
+
4240
4241
  /**
4241
4242
  * Mozilla, WebKit and Opera recalculate the computed width when box-sizing: boder-box; is set
4242
- * So if an element has "width: 200px; -moz-box-sizing: border-box; border: 1px;" then
4243
+ * So if an element has "width: 200px; -moz-box-sizing: border-box; border: 1px;" then
4243
4244
  * its computed css width will be 198px
4244
4245
  */
4245
4246
  var BOX_SIZING_PROPERTIES = ["-webkit-box-sizing", "-moz-box-sizing", "-ms-box-sizing", "box-sizing"];
4246
-
4247
+
4247
4248
  var shouldIgnoreBoxSizingBorderBox = function(element) {
4248
4249
  if (hasBoxSizingBorderBox(element)) {
4249
4250
  return parseInt(dom.getStyle("width").from(element), 10) < element.offsetWidth;
4250
4251
  }
4251
4252
  return false;
4252
4253
  };
4253
-
4254
+
4254
4255
  var hasBoxSizingBorderBox = function(element) {
4255
4256
  var i = 0,
4256
4257
  length = BOX_SIZING_PROPERTIES.length;
@@ -4260,14 +4261,14 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4260
4261
  }
4261
4262
  }
4262
4263
  };
4263
-
4264
+
4264
4265
  dom.copyStyles = function(stylesToCopy) {
4265
4266
  return {
4266
4267
  from: function(element) {
4267
4268
  if (shouldIgnoreBoxSizingBorderBox(element)) {
4268
4269
  stylesToCopy = wysihtml5.lang.array(stylesToCopy).without(BOX_SIZING_PROPERTIES);
4269
4270
  }
4270
-
4271
+
4271
4272
  var cssText = "",
4272
4273
  length = stylesToCopy.length,
4273
4274
  i = 0,
@@ -4276,7 +4277,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4276
4277
  property = stylesToCopy[i];
4277
4278
  cssText += property + ":" + dom.getStyle(property).from(element) + ";";
4278
4279
  }
4279
-
4280
+
4280
4281
  return {
4281
4282
  to: function(element) {
4282
4283
  dom.setStyles(cssText).on(element);
@@ -4295,12 +4296,12 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4295
4296
  * });
4296
4297
  */
4297
4298
  (function(wysihtml5) {
4298
-
4299
+
4299
4300
  wysihtml5.dom.delegate = function(container, selector, eventName, handler) {
4300
4301
  return wysihtml5.dom.observe(container, eventName, function(event) {
4301
4302
  var target = event.target,
4302
4303
  match = wysihtml5.lang.array(container.querySelectorAll(selector));
4303
-
4304
+
4304
4305
  while (target && target !== container) {
4305
4306
  if (match.contains(target)) {
4306
4307
  handler.call(target, event);
@@ -4310,13 +4311,13 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4310
4311
  }
4311
4312
  });
4312
4313
  };
4313
-
4314
+
4314
4315
  })(wysihtml5);/**
4315
4316
  * Returns the given html wrapped in a div element
4316
4317
  *
4317
4318
  * Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly
4318
4319
  * when inserted via innerHTML
4319
- *
4320
+ *
4320
4321
  * @param {String} html The html which should be wrapped in a dom element
4321
4322
  * @param {Obejct} [context] Document object of the context the html belongs to
4322
4323
  *
@@ -4324,7 +4325,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
4324
4325
  * wysihtml5.dom.getAsDom("<article>foo</article>");
4325
4326
  */
4326
4327
  wysihtml5.dom.getAsDom = (function() {
4327
-
4328
+
4328
4329
  var _innerHTMLShiv = function(html, context) {
4329
4330
  var tempElement = context.createElement("div");
4330
4331
  tempElement.style.display = "none";
@@ -4334,7 +4335,7 @@ wysihtml5.dom.getAsDom = (function() {
4334
4335
  context.body.removeChild(tempElement);
4335
4336
  return tempElement;
4336
4337
  };
4337
-
4338
+
4338
4339
  /**
4339
4340
  * Make sure IE supports HTML5 tags, which is accomplished by simply creating one instance of each element
4340
4341
  */
@@ -4347,8 +4348,8 @@ wysihtml5.dom.getAsDom = (function() {
4347
4348
  }
4348
4349
  context._wysihtml5_supportsHTML5Tags = true;
4349
4350
  };
4350
-
4351
-
4351
+
4352
+
4352
4353
  /**
4353
4354
  * List of html5 tags
4354
4355
  * taken from http://simon.html5.org/html5-elements
@@ -4358,7 +4359,7 @@ wysihtml5.dom.getAsDom = (function() {
4358
4359
  "figure", "footer", "header", "hgroup", "keygen", "mark", "meter", "nav", "output", "progress",
4359
4360
  "rp", "rt", "ruby", "svg", "section", "source", "summary", "time", "track", "video", "wbr"
4360
4361
  ];
4361
-
4362
+
4362
4363
  return function(html, context) {
4363
4364
  context = context || document;
4364
4365
  var tempElement;
@@ -4390,23 +4391,23 @@ wysihtml5.dom.getAsDom = (function() {
4390
4391
  * var coloredElement = wysihtml5.dom.getParentElement(myTextNode, { nodeName: "SPAN", className: "wysiwyg-color-red", classRegExp: /wysiwyg-color-[a-z]/g });
4391
4392
  */
4392
4393
  wysihtml5.dom.getParentElement = (function() {
4393
-
4394
+
4394
4395
  function _isSameNodeName(nodeName, desiredNodeNames) {
4395
4396
  if (!desiredNodeNames || !desiredNodeNames.length) {
4396
4397
  return true;
4397
4398
  }
4398
-
4399
+
4399
4400
  if (typeof(desiredNodeNames) === "string") {
4400
4401
  return nodeName === desiredNodeNames;
4401
4402
  } else {
4402
4403
  return wysihtml5.lang.array(desiredNodeNames).contains(nodeName);
4403
4404
  }
4404
4405
  }
4405
-
4406
+
4406
4407
  function _isElement(node) {
4407
4408
  return node.nodeType === wysihtml5.ELEMENT_NODE;
4408
4409
  }
4409
-
4410
+
4410
4411
  function _hasClassName(element, className, classRegExp) {
4411
4412
  var classNames = (element.className || "").match(classRegExp) || [];
4412
4413
  if (!className) {
@@ -4414,7 +4415,7 @@ wysihtml5.dom.getParentElement = (function() {
4414
4415
  }
4415
4416
  return classNames[classNames.length - 1] === className;
4416
4417
  }
4417
-
4418
+
4418
4419
  function _getParentElementWithNodeName(node, nodeName, levels) {
4419
4420
  while (levels-- && node && node.nodeName !== "BODY") {
4420
4421
  if (_isSameNodeName(node.nodeName, nodeName)) {
@@ -4424,7 +4425,7 @@ wysihtml5.dom.getParentElement = (function() {
4424
4425
  }
4425
4426
  return null;
4426
4427
  }
4427
-
4428
+
4428
4429
  function _getParentElementWithNodeNameAndClassName(node, nodeName, className, classRegExp, levels) {
4429
4430
  while (levels-- && node && node.nodeName !== "BODY") {
4430
4431
  if (_isElement(node) &&
@@ -4436,7 +4437,7 @@ wysihtml5.dom.getParentElement = (function() {
4436
4437
  }
4437
4438
  return null;
4438
4439
  }
4439
-
4440
+
4440
4441
  return function(node, matchingSet, levels) {
4441
4442
  levels = levels || 50; // Go max 50 nodes upwards from current node
4442
4443
  if (matchingSet.className || matchingSet.classRegExp) {
@@ -4465,20 +4466,20 @@ wysihtml5.dom.getStyle = (function() {
4465
4466
  "float": ("styleFloat" in document.createElement("div").style) ? "styleFloat" : "cssFloat"
4466
4467
  },
4467
4468
  REG_EXP_CAMELIZE = /\-[a-z]/g;
4468
-
4469
+
4469
4470
  function camelize(str) {
4470
4471
  return str.replace(REG_EXP_CAMELIZE, function(match) {
4471
4472
  return match.charAt(1).toUpperCase();
4472
4473
  });
4473
4474
  }
4474
-
4475
+
4475
4476
  return function(property) {
4476
4477
  return {
4477
4478
  from: function(element) {
4478
4479
  if (element.nodeType !== wysihtml5.ELEMENT_NODE) {
4479
4480
  return;
4480
4481
  }
4481
-
4482
+
4482
4483
  var doc = element.ownerDocument,
4483
4484
  camelizedProperty = stylePropertyMapping[property] || camelize(property),
4484
4485
  style = element.style,
@@ -4487,7 +4488,7 @@ wysihtml5.dom.getStyle = (function() {
4487
4488
  if (styleValue) {
4488
4489
  return styleValue;
4489
4490
  }
4490
-
4491
+
4491
4492
  // currentStyle is no standard and only supported by Opera and IE but it has one important advantage over the standard-compliant
4492
4493
  // window.getComputedStyle, since it returns css property values in their original unit:
4493
4494
  // If you set an elements width to "50%", window.getComputedStyle will give you it's current width in px while currentStyle
@@ -4535,18 +4536,18 @@ wysihtml5.dom.getStyle = (function() {
4535
4536
  wysihtml5.dom.hasElementWithTagName = (function() {
4536
4537
  var LIVE_CACHE = {},
4537
4538
  DOCUMENT_IDENTIFIER = 1;
4538
-
4539
+
4539
4540
  function _getDocumentIdentifier(doc) {
4540
4541
  return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);
4541
4542
  }
4542
-
4543
+
4543
4544
  return function(doc, tagName) {
4544
4545
  var key = _getDocumentIdentifier(doc) + ":" + tagName,
4545
4546
  cacheEntry = LIVE_CACHE[key];
4546
4547
  if (!cacheEntry) {
4547
4548
  cacheEntry = LIVE_CACHE[key] = doc.getElementsByTagName(tagName);
4548
4549
  }
4549
-
4550
+
4550
4551
  return cacheEntry.length > 0;
4551
4552
  };
4552
4553
  })();/**
@@ -4566,7 +4567,7 @@ wysihtml5.dom.hasElementWithTagName = (function() {
4566
4567
  function _getDocumentIdentifier(doc) {
4567
4568
  return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);
4568
4569
  }
4569
-
4570
+
4570
4571
  wysihtml5.dom.hasElementWithClassName = function(doc, className) {
4571
4572
  // getElementsByClassName is not supported by IE<9
4572
4573
  // but is sometimes mocked via library code (which then doesn't return live node lists)
@@ -4588,18 +4589,18 @@ wysihtml5.dom.insert = function(elementToInsert) {
4588
4589
  after: function(element) {
4589
4590
  element.parentNode.insertBefore(elementToInsert, element.nextSibling);
4590
4591
  },
4591
-
4592
+
4592
4593
  before: function(element) {
4593
4594
  element.parentNode.insertBefore(elementToInsert, element);
4594
4595
  },
4595
-
4596
+
4596
4597
  into: function(element) {
4597
4598
  element.appendChild(elementToInsert);
4598
4599
  }
4599
4600
  };
4600
4601
  };wysihtml5.dom.insertCSS = function(rules) {
4601
4602
  rules = rules.join("\n");
4602
-
4603
+
4603
4604
  return {
4604
4605
  into: function(doc) {
4605
4606
  var head = doc.head || doc.getElementsByTagName("head")[0],
@@ -4626,12 +4627,12 @@ wysihtml5.dom.insert = function(elementToInsert) {
4626
4627
  */
4627
4628
  wysihtml5.dom.observe = function(element, eventNames, handler) {
4628
4629
  eventNames = typeof(eventNames) === "string" ? [eventNames] : eventNames;
4629
-
4630
+
4630
4631
  var handlerWrapper,
4631
4632
  eventName,
4632
4633
  i = 0,
4633
4634
  length = eventNames.length;
4634
-
4635
+
4635
4636
  for (; i<length; i++) {
4636
4637
  eventName = eventNames[i];
4637
4638
  if (element.addEventListener) {
@@ -4652,7 +4653,7 @@ wysihtml5.dom.observe = function(element, eventNames, handler) {
4652
4653
  element.attachEvent("on" + eventName, handlerWrapper);
4653
4654
  }
4654
4655
  }
4655
-
4656
+
4656
4657
  return {
4657
4658
  stop: function() {
4658
4659
  var eventName,
@@ -4721,7 +4722,7 @@ wysihtml5.dom.observe = function(element, eventNames, handler) {
4721
4722
  * // => '<p class="red">foo</p><p>bar</p>'
4722
4723
  */
4723
4724
  wysihtml5.dom.parse = (function() {
4724
-
4725
+
4725
4726
  /**
4726
4727
  * It's not possible to use a XMLParser/DOMParser as HTML5 is not always well-formed XML
4727
4728
  * new DOMParser().parseFromString('<img src="foo.gif">') will cause a parseError since the
@@ -4738,27 +4739,27 @@ wysihtml5.dom.parse = (function() {
4738
4739
  WHITE_SPACE_REG_EXP = /\s+/,
4739
4740
  defaultRules = { tags: {}, classes: {} },
4740
4741
  currentRules = {};
4741
-
4742
+
4742
4743
  /**
4743
4744
  * Iterates over all childs of the element, recreates them, appends them into a document fragment
4744
4745
  * which later replaces the entire body content
4745
4746
  */
4746
4747
  function parse(elementOrHtml, rules, context, cleanUp) {
4747
4748
  wysihtml5.lang.object(currentRules).merge(defaultRules).merge(rules).get();
4748
-
4749
+
4749
4750
  context = context || elementOrHtml.ownerDocument || document;
4750
4751
  var fragment = context.createDocumentFragment(),
4751
4752
  isString = typeof(elementOrHtml) === "string",
4752
4753
  element,
4753
4754
  newNode,
4754
4755
  firstChild;
4755
-
4756
+
4756
4757
  if (isString) {
4757
4758
  element = wysihtml5.dom.getAsDom(elementOrHtml, context);
4758
4759
  } else {
4759
4760
  element = elementOrHtml;
4760
4761
  }
4761
-
4762
+
4762
4763
  while (element.firstChild) {
4763
4764
  firstChild = element.firstChild;
4764
4765
  element.removeChild(firstChild);
@@ -4767,16 +4768,16 @@ wysihtml5.dom.parse = (function() {
4767
4768
  fragment.appendChild(newNode);
4768
4769
  }
4769
4770
  }
4770
-
4771
+
4771
4772
  // Clear element contents
4772
4773
  element.innerHTML = "";
4773
-
4774
+
4774
4775
  // Insert new DOM tree
4775
4776
  element.appendChild(fragment);
4776
-
4777
+
4777
4778
  return isString ? wysihtml5.quirks.getCorrectInnerHTML(element) : element;
4778
4779
  }
4779
-
4780
+
4780
4781
  function _convert(oldNode, cleanUp) {
4781
4782
  var oldNodeType = oldNode.nodeType,
4782
4783
  oldChilds = oldNode.childNodes,
@@ -4784,20 +4785,20 @@ wysihtml5.dom.parse = (function() {
4784
4785
  newNode,
4785
4786
  method = NODE_TYPE_MAPPING[oldNodeType],
4786
4787
  i = 0;
4787
-
4788
+
4788
4789
  newNode = method && method(oldNode);
4789
-
4790
+
4790
4791
  if (!newNode) {
4791
4792
  return null;
4792
4793
  }
4793
-
4794
+
4794
4795
  for (i=0; i<oldChildsLength; i++) {
4795
4796
  newChild = _convert(oldChilds[i], cleanUp);
4796
4797
  if (newChild) {
4797
4798
  newNode.appendChild(newChild);
4798
4799
  }
4799
4800
  }
4800
-
4801
+
4801
4802
  // Cleanup senseless <span> elements
4802
4803
  if (cleanUp &&
4803
4804
  newNode.childNodes.length <= 1 &&
@@ -4805,10 +4806,10 @@ wysihtml5.dom.parse = (function() {
4805
4806
  !newNode.attributes.length) {
4806
4807
  return newNode.firstChild;
4807
4808
  }
4808
-
4809
+
4809
4810
  return newNode;
4810
4811
  }
4811
-
4812
+
4812
4813
  function _handleElement(oldNode) {
4813
4814
  var rule,
4814
4815
  newNode,
@@ -4816,7 +4817,7 @@ wysihtml5.dom.parse = (function() {
4816
4817
  tagRules = currentRules.tags,
4817
4818
  nodeName = oldNode.nodeName.toLowerCase(),
4818
4819
  scopeName = oldNode.scopeName;
4819
-
4820
+
4820
4821
  /**
4821
4822
  * We already parsed that element
4822
4823
  * ignore it! (yes, this sometimes happens in IE8 when the html is invalid)
@@ -4825,11 +4826,11 @@ wysihtml5.dom.parse = (function() {
4825
4826
  return null;
4826
4827
  }
4827
4828
  oldNode._wysihtml5 = 1;
4828
-
4829
+
4829
4830
  if (oldNode.className === "wysihtml5-temp") {
4830
4831
  return null;
4831
4832
  }
4832
-
4833
+
4833
4834
  /**
4834
4835
  * IE is the only browser who doesn't include the namespace in the
4835
4836
  * nodeName, that's why we have to prepend it by ourselves
@@ -4839,7 +4840,7 @@ wysihtml5.dom.parse = (function() {
4839
4840
  if (scopeName && scopeName != "HTML") {
4840
4841
  nodeName = scopeName + ":" + nodeName;
4841
4842
  }
4842
-
4843
+
4843
4844
  /**
4844
4845
  * Repair node
4845
4846
  * IE is a bit bitchy when it comes to invalid nested markup which includes unclosed tags
@@ -4852,13 +4853,13 @@ wysihtml5.dom.parse = (function() {
4852
4853
  nodeName = "div";
4853
4854
  }
4854
4855
  }
4855
-
4856
+
4856
4857
  if (nodeName in tagRules) {
4857
4858
  rule = tagRules[nodeName];
4858
4859
  if (!rule || rule.remove) {
4859
4860
  return null;
4860
4861
  }
4861
-
4862
+
4862
4863
  rule = typeof(rule) === "string" ? { rename_tag: rule } : rule;
4863
4864
  } else if (oldNode.firstChild) {
4864
4865
  rule = { rename_tag: DEFAULT_NODE_NAME };
@@ -4866,14 +4867,14 @@ wysihtml5.dom.parse = (function() {
4866
4867
  // Remove empty unknown elements
4867
4868
  return null;
4868
4869
  }
4869
-
4870
+
4870
4871
  newNode = oldNode.ownerDocument.createElement(rule.rename_tag || nodeName);
4871
4872
  _handleAttributes(oldNode, newNode, rule);
4872
-
4873
+
4873
4874
  oldNode = null;
4874
4875
  return newNode;
4875
4876
  }
4876
-
4877
+
4877
4878
  function _handleAttributes(oldNode, newNode, rule) {
4878
4879
  var attributes = {}, // fresh new set of attributes to set on newNode
4879
4880
  setClass = rule.set_class, // classes to set
@@ -4893,11 +4894,11 @@ wysihtml5.dom.parse = (function() {
4893
4894
  attributeName,
4894
4895
  newAttributeValue,
4895
4896
  method;
4896
-
4897
+
4897
4898
  if (setAttributes) {
4898
4899
  attributes = wysihtml5.lang.object(setAttributes).clone();
4899
4900
  }
4900
-
4901
+
4901
4902
  if (checkAttributes) {
4902
4903
  for (attributeName in checkAttributes) {
4903
4904
  method = attributeCheckMethods[checkAttributes[attributeName]];
@@ -4910,11 +4911,11 @@ wysihtml5.dom.parse = (function() {
4910
4911
  }
4911
4912
  }
4912
4913
  }
4913
-
4914
+
4914
4915
  if (setClass) {
4915
4916
  classes.push(setClass);
4916
4917
  }
4917
-
4918
+
4918
4919
  if (addClass) {
4919
4920
  for (attributeName in addClass) {
4920
4921
  method = addClassMethods[addClass[attributeName]];
@@ -4927,10 +4928,10 @@ wysihtml5.dom.parse = (function() {
4927
4928
  }
4928
4929
  }
4929
4930
  }
4930
-
4931
+
4931
4932
  // make sure that wysihtml5 temp class doesn't get stripped out
4932
4933
  allowedClasses["_wysihtml5-temp-placeholder"] = 1;
4933
-
4934
+
4934
4935
  // add old classes last
4935
4936
  oldClasses = oldNode.getAttribute("class");
4936
4937
  if (oldClasses) {
@@ -4943,7 +4944,7 @@ wysihtml5.dom.parse = (function() {
4943
4944
  newClasses.push(currentClass);
4944
4945
  }
4945
4946
  }
4946
-
4947
+
4947
4948
  // remove duplicate entries and preserve class specificity
4948
4949
  newClassesLength = newClasses.length;
4949
4950
  while (newClassesLength--) {
@@ -4952,11 +4953,11 @@ wysihtml5.dom.parse = (function() {
4952
4953
  newUniqueClasses.unshift(currentClass);
4953
4954
  }
4954
4955
  }
4955
-
4956
+
4956
4957
  if (newUniqueClasses.length) {
4957
4958
  attributes["class"] = newUniqueClasses.join(" ");
4958
4959
  }
4959
-
4960
+
4960
4961
  // set attributes on newNode
4961
4962
  for (attributeName in attributes) {
4962
4963
  // Setting attributes can cause a js error in IE under certain circumstances
@@ -4966,7 +4967,7 @@ wysihtml5.dom.parse = (function() {
4966
4967
  newNode.setAttribute(attributeName, attributes[attributeName]);
4967
4968
  } catch(e) {}
4968
4969
  }
4969
-
4970
+
4970
4971
  // IE8 sometimes loses the width/height attributes when those are set before the "src"
4971
4972
  // so we make sure to set them again
4972
4973
  if (attributes.src) {
@@ -4978,7 +4979,7 @@ wysihtml5.dom.parse = (function() {
4978
4979
  }
4979
4980
  }
4980
4981
  }
4981
-
4982
+
4982
4983
  /**
4983
4984
  * IE gives wrong results for hasAttribute/getAttribute, for example:
4984
4985
  * var td = document.createElement("td");
@@ -5001,13 +5002,13 @@ wysihtml5.dom.parse = (function() {
5001
5002
  var outerHTML = node.outerHTML.toLowerCase(),
5002
5003
  // TODO: This might not work for attributes without value: <input disabled>
5003
5004
  hasAttribute = outerHTML.indexOf(" " + attributeName + "=") != -1;
5004
-
5005
+
5005
5006
  return hasAttribute ? node.getAttribute(attributeName) : null;
5006
5007
  } else{
5007
5008
  return node.getAttribute(attributeName);
5008
5009
  }
5009
5010
  }
5010
-
5011
+
5011
5012
  /**
5012
5013
  * Check whether the given node is a proper loaded image
5013
5014
  * FIXME: Returns undefined when unknown (Chrome, Safari)
@@ -5021,12 +5022,12 @@ wysihtml5.dom.parse = (function() {
5021
5022
  }
5022
5023
  }
5023
5024
  }
5024
-
5025
+
5025
5026
  function _handleText(oldNode) {
5026
5027
  return oldNode.ownerDocument.createTextNode(oldNode.data);
5027
5028
  }
5028
-
5029
-
5029
+
5030
+
5030
5031
  // ------------ attribute checks ------------ \\
5031
5032
  var attributeCheckMethods = {
5032
5033
  url: (function() {
@@ -5064,7 +5065,7 @@ wysihtml5.dom.parse = (function() {
5064
5065
  });
5065
5066
  };
5066
5067
  })(),
5067
-
5068
+
5068
5069
  alt: (function() {
5069
5070
  var REG_EXP = /[^ a-z0-9_\-]/gi;
5070
5071
  return function(attributeValue) {
@@ -5074,7 +5075,7 @@ wysihtml5.dom.parse = (function() {
5074
5075
  return attributeValue.replace(REG_EXP, "");
5075
5076
  };
5076
5077
  })(),
5077
-
5078
+
5078
5079
  numbers: (function() {
5079
5080
  var REG_EXP = /\D/g;
5080
5081
  return function(attributeValue) {
@@ -5083,7 +5084,7 @@ wysihtml5.dom.parse = (function() {
5083
5084
  };
5084
5085
  })()
5085
5086
  };
5086
-
5087
+
5087
5088
  // ------------ class converter (converts an html attribute to a class name) ------------ \\
5088
5089
  var addClassMethods = {
5089
5090
  align_img: (function() {
@@ -5095,7 +5096,7 @@ wysihtml5.dom.parse = (function() {
5095
5096
  return mapping[String(attributeValue).toLowerCase()];
5096
5097
  };
5097
5098
  })(),
5098
-
5099
+
5099
5100
  align_text: (function() {
5100
5101
  var mapping = {
5101
5102
  left: "wysiwyg-text-align-left",
@@ -5107,7 +5108,7 @@ wysihtml5.dom.parse = (function() {
5107
5108
  return mapping[String(attributeValue).toLowerCase()];
5108
5109
  };
5109
5110
  })(),
5110
-
5111
+
5111
5112
  clear_br: (function() {
5112
5113
  var mapping = {
5113
5114
  left: "wysiwyg-clear-left",
@@ -5119,7 +5120,7 @@ wysihtml5.dom.parse = (function() {
5119
5120
  return mapping[String(attributeValue).toLowerCase()];
5120
5121
  };
5121
5122
  })(),
5122
-
5123
+
5123
5124
  size_font: (function() {
5124
5125
  var mapping = {
5125
5126
  "1": "wysiwyg-font-size-xx-small",
@@ -5137,7 +5138,7 @@ wysihtml5.dom.parse = (function() {
5137
5138
  };
5138
5139
  })()
5139
5140
  };
5140
-
5141
+
5141
5142
  return parse;
5142
5143
  })();
5143
5144
  /**
@@ -5195,7 +5196,7 @@ wysihtml5.dom.renameElement = function(element, newNodeName) {
5195
5196
  return newElement;
5196
5197
  };/**
5197
5198
  * Takes an element, removes it and replaces it with it's childs
5198
- *
5199
+ *
5199
5200
  * @param {Object} node The node which to replace with it's child nodes
5200
5201
  * @example
5201
5202
  * <div id="foo">
@@ -5210,12 +5211,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5210
5211
  if (!node.parentNode) {
5211
5212
  return;
5212
5213
  }
5213
-
5214
+
5214
5215
  if (!node.firstChild) {
5215
5216
  node.parentNode.removeChild(node);
5216
5217
  return;
5217
5218
  }
5218
-
5219
+
5219
5220
  var fragment = node.ownerDocument.createDocumentFragment();
5220
5221
  while (node.firstChild) {
5221
5222
  fragment.appendChild(node.firstChild);
@@ -5249,21 +5250,21 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5249
5250
  function _isBlockElement(node) {
5250
5251
  return dom.getStyle("display").from(node) === "block";
5251
5252
  }
5252
-
5253
+
5253
5254
  function _isLineBreak(node) {
5254
5255
  return node.nodeName === "BR";
5255
5256
  }
5256
-
5257
+
5257
5258
  function _appendLineBreak(element) {
5258
5259
  var lineBreak = element.ownerDocument.createElement("br");
5259
5260
  element.appendChild(lineBreak);
5260
5261
  }
5261
-
5262
+
5262
5263
  function resolveList(list) {
5263
5264
  if (list.nodeName !== "MENU" && list.nodeName !== "UL" && list.nodeName !== "OL") {
5264
5265
  return;
5265
5266
  }
5266
-
5267
+
5267
5268
  var doc = list.ownerDocument,
5268
5269
  fragment = doc.createDocumentFragment(),
5269
5270
  previousSibling = list.previousElementSibling || list.previousSibling,
@@ -5272,11 +5273,11 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5272
5273
  isLastChild,
5273
5274
  shouldAppendLineBreak,
5274
5275
  listItem;
5275
-
5276
+
5276
5277
  if (previousSibling && !_isBlockElement(previousSibling)) {
5277
5278
  _appendLineBreak(fragment);
5278
5279
  }
5279
-
5280
+
5280
5281
  while (listItem = list.firstChild) {
5281
5282
  lastChild = listItem.lastChild;
5282
5283
  while (firstChild = listItem.firstChild) {
@@ -5288,12 +5289,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5288
5289
  _appendLineBreak(fragment);
5289
5290
  }
5290
5291
  }
5291
-
5292
+
5292
5293
  listItem.parentNode.removeChild(listItem);
5293
5294
  }
5294
5295
  list.parentNode.replaceChild(fragment, list);
5295
5296
  }
5296
-
5297
+
5297
5298
  dom.resolveList = resolveList;
5298
5299
  })(wysihtml5.dom);/**
5299
5300
  * Sandbox for executing javascript, parsing css styles and doing dom operations in a secure way
@@ -5345,7 +5346,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5345
5346
  "referrer",
5346
5347
  "write", "open", "close"
5347
5348
  ];
5348
-
5349
+
5349
5350
  wysihtml5.dom.Sandbox = Base.extend(
5350
5351
  /** @scope wysihtml5.dom.Sandbox.prototype */ {
5351
5352
 
@@ -5354,12 +5355,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5354
5355
  this.config = wysihtml5.lang.object({}).merge(config).get();
5355
5356
  this.iframe = this._createIframe();
5356
5357
  },
5357
-
5358
+
5358
5359
  insertInto: function(element) {
5359
5360
  if (typeof(element) === "string") {
5360
5361
  element = doc.getElementById(element);
5361
5362
  }
5362
-
5363
+
5363
5364
  element.appendChild(this.iframe);
5364
5365
  },
5365
5366
 
@@ -5395,7 +5396,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5395
5396
  * In order to make this happen we need to set the "allow-scripts" flag.
5396
5397
  * A combination of allow-scripts and allow-same-origin is almost the same as setting no sandbox attribute at all.
5397
5398
  * - Chrome & Safari, doesn't seem to support sandboxing correctly when the iframe's html is inlined (no physical document)
5398
- * - IE needs to have the security="restricted" attribute set before the iframe is
5399
+ * - IE needs to have the security="restricted" attribute set before the iframe is
5399
5400
  * inserted into the dom tree
5400
5401
  * - Believe it or not but in IE "security" in document.createElement("iframe") is false, even
5401
5402
  * though it supports it
@@ -5472,7 +5473,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5472
5473
 
5473
5474
  if (!wysihtml5.browser.supportsSandboxedIframes()) {
5474
5475
  // Unset a bunch of sensitive variables
5475
- // Please note: This isn't hack safe!
5476
+ // Please note: This isn't hack safe!
5476
5477
  // It more or less just takes care of basic attacks and prevents accidental theft of sensitive information
5477
5478
  // IE is secure though, which is the most important thing, since IE is the only browser, who
5478
5479
  // takes over scripts & styles into contentEditable elements when copied from external websites
@@ -5487,7 +5488,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
5487
5488
  for (i=0, length=documentProperties.length; i<length; i++) {
5488
5489
  this._unset(iframeDocument, documentProperties[i]);
5489
5490
  }
5490
- // This doesn't work in Safari 5
5491
+ // This doesn't work in Safari 5
5491
5492
  // See http://stackoverflow.com/questions/992461/is-it-possible-to-override-document-cookie-in-webkit
5492
5493
  this._unset(iframeDocument, "cookie", "", true);
5493
5494
  }
@@ -5661,11 +5662,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5661
5662
  // When pasting underlined links <a> into a contentEditable, IE thinks, it has to insert <u> to keep the styling
5662
5663
  "a u": wysihtml5.dom.replaceWithChildNodes
5663
5664
  };
5664
-
5665
+
5665
5666
  function cleanPastedHTML(elementOrHtml, rules, context) {
5666
5667
  rules = rules || defaultRules;
5667
5668
  context = context || elementOrHtml.ownerDocument || document;
5668
-
5669
+
5669
5670
  var element,
5670
5671
  isString = typeof(elementOrHtml) === "string",
5671
5672
  method,
@@ -5678,7 +5679,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5678
5679
  } else {
5679
5680
  element = elementOrHtml;
5680
5681
  }
5681
-
5682
+
5682
5683
  for (i in rules) {
5683
5684
  matches = element.querySelectorAll(i);
5684
5685
  method = rules[i];
@@ -5687,12 +5688,12 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5687
5688
  method(matches[j]);
5688
5689
  }
5689
5690
  }
5690
-
5691
+
5691
5692
  matches = elementOrHtml = rules = null;
5692
-
5693
+
5693
5694
  return isString ? element.innerHTML : element;
5694
5695
  }
5695
-
5696
+
5696
5697
  return cleanPastedHTML;
5697
5698
  })();/**
5698
5699
  * IE and Opera leave an empty paragraph in the contentEditable element after clearing it
@@ -5703,7 +5704,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5703
5704
  */
5704
5705
  (function(wysihtml5) {
5705
5706
  var dom = wysihtml5.dom;
5706
-
5707
+
5707
5708
  wysihtml5.quirks.ensureProperClearing = (function() {
5708
5709
  var clearIfNecessary = function(event) {
5709
5710
  var element = this;
@@ -5790,7 +5791,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5790
5791
  if (innerHTML.indexOf(TILDE_ESCAPED) === -1) {
5791
5792
  return innerHTML;
5792
5793
  }
5793
-
5794
+
5794
5795
  var elementsWithTilde = element.querySelectorAll("[href*='~'], [src*='~']"),
5795
5796
  url,
5796
5797
  urlToSearch,
@@ -5818,7 +5819,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5818
5819
  var dom = wysihtml5.dom,
5819
5820
  USE_NATIVE_LINE_BREAK_WHEN_CARET_INSIDE_TAGS = ["LI", "P", "H1", "H2", "H3", "H4", "H5", "H6"],
5820
5821
  LIST_TAGS = ["UL", "OL", "MENU"];
5821
-
5822
+
5822
5823
  wysihtml5.quirks.insertLineBreakOnReturn = function(composer) {
5823
5824
  function unwrap(selectedNode) {
5824
5825
  var parentElement = dom.getParentElement(selectedNode, { nodeName: ["P", "DIV"] }, 2);
@@ -5867,7 +5868,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5867
5868
  setTimeout(function() {
5868
5869
  unwrap(composer.selection.getSelectedNode());
5869
5870
  }, 0);
5870
- }
5871
+ }
5871
5872
  return;
5872
5873
  }
5873
5874
 
@@ -5876,7 +5877,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5876
5877
  event.preventDefault();
5877
5878
  }
5878
5879
  }
5879
-
5880
+
5880
5881
  // keypress doesn't fire when you hit backspace
5881
5882
  dom.observe(composer.element.ownerDocument, "keydown", keyDown);
5882
5883
  };
@@ -5890,11 +5891,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5890
5891
  */
5891
5892
  (function(wysihtml5) {
5892
5893
  var CLASS_NAME = "wysihtml5-quirks-redraw";
5893
-
5894
+
5894
5895
  wysihtml5.quirks.redraw = function(element) {
5895
5896
  wysihtml5.dom.addClass(element, CLASS_NAME);
5896
5897
  wysihtml5.dom.removeClass(element, CLASS_NAME);
5897
-
5898
+
5898
5899
  // Following hack is needed for firefox to make sure that image resize handles are properly removed
5899
5900
  try {
5900
5901
  var doc = element.ownerDocument;
@@ -5910,7 +5911,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5910
5911
  */
5911
5912
  (function(wysihtml5) {
5912
5913
  var dom = wysihtml5.dom;
5913
-
5914
+
5914
5915
  function _getCumulativeOffsetTop(element) {
5915
5916
  var top = 0;
5916
5917
  if (element.parentNode) {
@@ -5921,18 +5922,18 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
5921
5922
  }
5922
5923
  return top;
5923
5924
  }
5924
-
5925
+
5925
5926
  wysihtml5.Selection = Base.extend(
5926
5927
  /** @scope wysihtml5.Selection.prototype */ {
5927
5928
  constructor: function(editor) {
5928
5929
  // Make sure that our external range library is initialized
5929
5930
  window.rangy.init();
5930
-
5931
+
5931
5932
  this.editor = editor;
5932
5933
  this.composer = editor.composer;
5933
5934
  this.doc = this.composer.doc;
5934
5935
  },
5935
-
5936
+
5936
5937
  /**
5937
5938
  * Get the current selection as a bookmark to be able to later restore it
5938
5939
  *
@@ -6057,23 +6058,23 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6057
6058
  placeholderHTML = '<span class="' + className + '">' + wysihtml5.INVISIBLE_SPACE + '</span>',
6058
6059
  range = this.getRange(this.doc),
6059
6060
  newRange;
6060
-
6061
+
6061
6062
  // Nothing selected, execute and say goodbye
6062
6063
  if (!range) {
6063
6064
  method(body, body);
6064
6065
  return;
6065
6066
  }
6066
-
6067
+
6067
6068
  var node = range.createContextualFragment(placeholderHTML);
6068
6069
  range.insertNode(node);
6069
-
6070
+
6070
6071
  // Make sure that a potential error doesn't cause our placeholder element to be left as a placeholder
6071
6072
  try {
6072
6073
  method(range.startContainer, range.endContainer);
6073
6074
  } catch(e3) {
6074
6075
  setTimeout(function() { throw e3; }, 0);
6075
6076
  }
6076
-
6077
+
6077
6078
  caretPlaceholder = this.doc.querySelector("." + className);
6078
6079
  if (caretPlaceholder) {
6079
6080
  newRange = rangy.createRange(this.doc);
@@ -6138,13 +6139,13 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6138
6139
  try { newRange.setEnd(rangeBackup.endContainer, rangeBackup.endOffset); } catch(e2) {}
6139
6140
  try { this.setSelection(newRange); } catch(e3) {}
6140
6141
  },
6141
-
6142
+
6142
6143
  set: function(node, offset) {
6143
6144
  var newRange = rangy.createRange(this.doc);
6144
6145
  newRange.setStart(node, offset || 0);
6145
6146
  this.setSelection(newRange);
6146
6147
  },
6147
-
6148
+
6148
6149
  /**
6149
6150
  * Insert html at the caret position and move the cursor after the inserted html
6150
6151
  *
@@ -6309,7 +6310,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6309
6310
  return [];
6310
6311
  }
6311
6312
  },
6312
-
6313
+
6313
6314
  getRange: function() {
6314
6315
  var selection = this.getSelection();
6315
6316
  return selection && selection.rangeCount && selection.getRangeAt(0);
@@ -6325,7 +6326,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6325
6326
  return selection.setSingleRange(range);
6326
6327
  }
6327
6328
  });
6328
-
6329
+
6329
6330
  })(wysihtml5);
6330
6331
  /**
6331
6332
  * Inspired by the rangy CSS Applier module written by Tim Down and licensed under the MIT license.
@@ -6337,14 +6338,14 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6337
6338
  */
6338
6339
  (function(wysihtml5, rangy) {
6339
6340
  var defaultTagName = "span";
6340
-
6341
+
6341
6342
  var REG_EXP_WHITE_SPACE = /\s+/g;
6342
-
6343
+
6343
6344
  function hasClass(el, cssClass, regExp) {
6344
6345
  if (!el.className) {
6345
6346
  return false;
6346
6347
  }
6347
-
6348
+
6348
6349
  var matchingClassNames = el.className.match(regExp) || [];
6349
6350
  return matchingClassNames[matchingClassNames.length - 1] === cssClass;
6350
6351
  }
@@ -6363,7 +6364,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6363
6364
  el.className = el.className.replace(regExp, "");
6364
6365
  }
6365
6366
  }
6366
-
6367
+
6367
6368
  function hasSameClasses(el1, el2) {
6368
6369
  return el1.className.replace(REG_EXP_WHITE_SPACE, " ") == el2.className.replace(REG_EXP_WHITE_SPACE, " ");
6369
6370
  }
@@ -6436,7 +6437,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6436
6437
  }
6437
6438
  return (descendantNode == node) ? newNode : splitNodeAt(node, newNode.parentNode, rangy.dom.getNodeIndex(newNode));
6438
6439
  }
6439
-
6440
+
6440
6441
  function Merge(firstNode) {
6441
6442
  this.isElementMerge = (firstNode.nodeType == wysihtml5.ELEMENT_NODE);
6442
6443
  this.firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;
@@ -6552,7 +6553,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6552
6553
  range.setEnd(rangeEndNode, rangeEndOffset);
6553
6554
  }
6554
6555
  },
6555
-
6556
+
6556
6557
  getAdjacentMergeableTextNode: function(node, forward) {
6557
6558
  var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
6558
6559
  var el = isTextNode ? node.parentNode : node;
@@ -6573,7 +6574,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6573
6574
  }
6574
6575
  return null;
6575
6576
  },
6576
-
6577
+
6577
6578
  areElementsMergeable: function(el1, el2) {
6578
6579
  return rangy.dom.arrayContains(this.tagNames, (el1.tagName || "").toLowerCase())
6579
6580
  && rangy.dom.arrayContains(this.tagNames, (el2.tagName || "").toLowerCase())
@@ -6620,7 +6621,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6620
6621
  ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset);
6621
6622
  }
6622
6623
  }
6623
-
6624
+
6624
6625
  if (this.similarClassRegExp) {
6625
6626
  removeClass(ancestorWithClass, this.similarClassRegExp);
6626
6627
  }
@@ -6639,10 +6640,10 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6639
6640
  return;
6640
6641
  } catch(e) {}
6641
6642
  }
6642
-
6643
+
6643
6644
  range.splitBoundaries();
6644
6645
  textNodes = range.getNodes([wysihtml5.TEXT_NODE]);
6645
-
6646
+
6646
6647
  if (textNodes.length) {
6647
6648
  var textNode;
6648
6649
 
@@ -6652,11 +6653,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6652
6653
  this.applyToTextNode(textNode);
6653
6654
  }
6654
6655
  }
6655
-
6656
+
6656
6657
  range.setStart(textNodes[0], 0);
6657
6658
  textNode = textNodes[textNodes.length - 1];
6658
6659
  range.setEnd(textNode, textNode.length);
6659
-
6660
+
6660
6661
  if (this.normalize) {
6661
6662
  this.postApply(textNodes, range);
6662
6663
  }
@@ -6675,7 +6676,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6675
6676
  range.selectNode(node);
6676
6677
  textNodes = [node];
6677
6678
  }
6678
-
6679
+
6679
6680
  for (var i = 0, len = textNodes.length; i < len; ++i) {
6680
6681
  textNode = textNodes[i];
6681
6682
  ancestorWithClass = this.getAncestorWithClass(textNode);
@@ -6683,7 +6684,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6683
6684
  this.undoToTextNode(textNode, range, ancestorWithClass);
6684
6685
  }
6685
6686
  }
6686
-
6687
+
6687
6688
  if (len == 1) {
6688
6689
  this.selectNode(range, textNodes[0]);
6689
6690
  } else {
@@ -6696,7 +6697,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6696
6697
  }
6697
6698
  }
6698
6699
  },
6699
-
6700
+
6700
6701
  selectNode: function(range, node) {
6701
6702
  var isElement = node.nodeType === wysihtml5.ELEMENT_NODE,
6702
6703
  canHaveHTML = "canHaveHTML" in node ? node.canHaveHTML : true,
@@ -6715,7 +6716,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6715
6716
  range.setEndAfter(node);
6716
6717
  }
6717
6718
  },
6718
-
6719
+
6719
6720
  getTextSelectedByRange: function(textNode, range) {
6720
6721
  var textRange = range.cloneRange();
6721
6722
  textRange.selectNodeContents(textNode);
@@ -6735,7 +6736,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6735
6736
  ancestor = this.getAncestorWithClass(range.startContainer);
6736
6737
  return ancestor ? [ancestor] : false;
6737
6738
  }
6738
-
6739
+
6739
6740
  for (var i = 0, len = textNodes.length, selectedText; i < len; ++i) {
6740
6741
  selectedText = this.getTextSelectedByRange(textNodes[i], range);
6741
6742
  ancestor = this.getAncestorWithClass(textNodes[i]);
@@ -6758,10 +6759,10 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
6758
6759
  };
6759
6760
 
6760
6761
  wysihtml5.selection.HTMLApplier = HTMLApplier;
6761
-
6762
+
6762
6763
  })(wysihtml5, rangy);/**
6763
6764
  * Rich Text Query/Formatting Commands
6764
- *
6765
+ *
6765
6766
  * @example
6766
6767
  * var commands = new wysihtml5.Commands(editor);
6767
6768
  */
@@ -6772,7 +6773,7 @@ wysihtml5.Commands = Base.extend(
6772
6773
  this.composer = editor.composer;
6773
6774
  this.doc = this.composer.doc;
6774
6775
  },
6775
-
6776
+
6776
6777
  /**
6777
6778
  * Check whether the browser supports the given command
6778
6779
  *
@@ -6783,7 +6784,7 @@ wysihtml5.Commands = Base.extend(
6783
6784
  support: function(command) {
6784
6785
  return wysihtml5.browser.supportsCommand(this.doc, command);
6785
6786
  },
6786
-
6787
+
6787
6788
  /**
6788
6789
  * Check whether the browser supports the given command
6789
6790
  *
@@ -6797,9 +6798,9 @@ wysihtml5.Commands = Base.extend(
6797
6798
  args = wysihtml5.lang.array(arguments).get(),
6798
6799
  method = obj && obj.exec,
6799
6800
  result = null;
6800
-
6801
+
6801
6802
  this.editor.fire("beforecommand:composer");
6802
-
6803
+
6803
6804
  if (method) {
6804
6805
  args.unshift(this.composer);
6805
6806
  result = method.apply(obj, args);
@@ -6809,11 +6810,11 @@ wysihtml5.Commands = Base.extend(
6809
6810
  result = this.doc.execCommand(command, false, value);
6810
6811
  } catch(e) {}
6811
6812
  }
6812
-
6813
+
6813
6814
  this.editor.fire("aftercommand:composer");
6814
6815
  return result;
6815
6816
  },
6816
-
6817
+
6817
6818
  /**
6818
6819
  * Check whether the current command is active
6819
6820
  * If the caret is within a bold text, then calling this with command "bold" should return true
@@ -6860,7 +6861,7 @@ wysihtml5.commands.bold = {
6860
6861
  var undef,
6861
6862
  NODE_NAME = "A",
6862
6863
  dom = wysihtml5.dom;
6863
-
6864
+
6864
6865
  function _removeFormat(composer, anchors) {
6865
6866
  var length = anchors.length,
6866
6867
  i = 0,
@@ -6923,7 +6924,7 @@ wysihtml5.commands.bold = {
6923
6924
  }
6924
6925
  composer.selection.setAfter(elementToSetCaretAfter);
6925
6926
  }
6926
-
6927
+
6927
6928
  wysihtml5.commands.createLink = {
6928
6929
  /**
6929
6930
  * TODO: Use HTMLApplier or formatInline here
@@ -6931,7 +6932,7 @@ wysihtml5.commands.bold = {
6931
6932
  * Turns selection into a link
6932
6933
  * If selection is already a link, it removes the link and wraps it with a <code> element
6933
6934
  * The <code> element is needed to avoid auto linking
6934
- *
6935
+ *
6935
6936
  * @example
6936
6937
  * // either ...
6937
6938
  * wysihtml5.commands.createLink.exec(composer, "createLink", "http://www.google.de");
@@ -6964,7 +6965,7 @@ wysihtml5.commands.bold = {
6964
6965
  (function(wysihtml5) {
6965
6966
  var undef,
6966
6967
  REG_EXP = /wysiwyg-font-size-[0-9a-z\-]+/g;
6967
-
6968
+
6968
6969
  wysihtml5.commands.fontSize = {
6969
6970
  exec: function(composer, command, size) {
6970
6971
  return wysihtml5.commands.formatInline.exec(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
@@ -6986,7 +6987,7 @@ wysihtml5.commands.bold = {
6986
6987
  */
6987
6988
  (function(wysihtml5) {
6988
6989
  var REG_EXP = /wysiwyg-color-[0-9a-z]+/g;
6989
-
6990
+
6990
6991
  wysihtml5.commands.foreColor = {
6991
6992
  exec: function(composer, command, color) {
6992
6993
  return wysihtml5.commands.formatInline.exec(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
@@ -7003,7 +7004,7 @@ wysihtml5.commands.bold = {
7003
7004
  // when the caret is within a H1 and the H4 is invoked, the H1 should turn into H4
7004
7005
  // instead of creating a H4 within a H1 which would result in semantically invalid html
7005
7006
  BLOCK_ELEMENTS_GROUP = ["H1", "H2", "H3", "H4", "H5", "H6", "P", "BLOCKQUOTE", DEFAULT_NODE_NAME];
7006
-
7007
+
7007
7008
  /**
7008
7009
  * Remove similiar classes (based on classRegExp)
7009
7010
  * and add the desired class name
@@ -7145,7 +7146,7 @@ wysihtml5.commands.bold = {
7145
7146
  function _hasClasses(element) {
7146
7147
  return !!wysihtml5.lang.string(element.className).trim();
7147
7148
  }
7148
-
7149
+
7149
7150
  wysihtml5.commands.formatBlock = {
7150
7151
  exec: function(composer, command, nodeName, className, classRegExp) {
7151
7152
  var doc = composer.doc,
@@ -7223,12 +7224,12 @@ wysihtml5.commands.bold = {
7223
7224
  * abcdefg|
7224
7225
  * output:
7225
7226
  * abcdefg<b>|</b>
7226
- *
7227
+ *
7227
7228
  * #2 unformatted text selected:
7228
7229
  * abc|deg|h
7229
7230
  * output:
7230
7231
  * abc<b>|deg|</b>h
7231
- *
7232
+ *
7232
7233
  * #3 unformatted text selected across boundaries:
7233
7234
  * ab|c <span>defg|h</span>
7234
7235
  * output:
@@ -7258,12 +7259,12 @@ wysihtml5.commands.bold = {
7258
7259
  "i": "em"
7259
7260
  },
7260
7261
  htmlApplier = {};
7261
-
7262
+
7262
7263
  function _getTagNames(tagName) {
7263
7264
  var alias = ALIAS_MAPPING[tagName];
7264
7265
  return alias ? [tagName.toLowerCase(), alias.toLowerCase()] : [tagName.toLowerCase()];
7265
7266
  }
7266
-
7267
+
7267
7268
  function _getApplier(tagName, className, classRegExp) {
7268
7269
  var identifier = tagName + ":" + className;
7269
7270
  if (!htmlApplier[identifier]) {
@@ -7271,7 +7272,7 @@ wysihtml5.commands.bold = {
7271
7272
  }
7272
7273
  return htmlApplier[identifier];
7273
7274
  }
7274
-
7275
+
7275
7276
  wysihtml5.commands.formatInline = {
7276
7277
  exec: function(composer, command, tagName, className, classRegExp) {
7277
7278
  var range = composer.selection.getRange();
@@ -7321,12 +7322,12 @@ wysihtml5.commands.bold = {
7321
7322
  };
7322
7323
  (function(wysihtml5) {
7323
7324
  var NODE_NAME = "IMG";
7324
-
7325
+
7325
7326
  wysihtml5.commands.insertImage = {
7326
7327
  /**
7327
7328
  * Inserts an <img>
7328
7329
  * If selection is already an image link, it removes it
7329
- *
7330
+ *
7330
7331
  * @example
7331
7332
  * // either ...
7332
7333
  * wysihtml5.commands.insertImage.exec(composer, "insertImage", "http://www.google.de/logo.jpg");
@@ -7361,7 +7362,7 @@ wysihtml5.commands.bold = {
7361
7362
  }
7362
7363
 
7363
7364
  image = doc.createElement(NODE_NAME);
7364
-
7365
+
7365
7366
  for (i in value) {
7366
7367
  if (i === "className") {
7367
7368
  i = "class";
@@ -7422,7 +7423,7 @@ wysihtml5.commands.bold = {
7422
7423
  };
7423
7424
  })(wysihtml5);(function(wysihtml5) {
7424
7425
  var LINE_BREAK = "<br>" + (wysihtml5.browser.needsSpaceAfterLineBreak() ? " " : "");
7425
-
7426
+
7426
7427
  wysihtml5.commands.insertLineBreak = {
7427
7428
  exec: function(composer, command) {
7428
7429
  if (composer.commands.support(command)) {
@@ -7448,12 +7449,12 @@ wysihtml5.commands.bold = {
7448
7449
  tempClassName = "_wysihtml5-temp-" + new Date().getTime(),
7449
7450
  isEmpty,
7450
7451
  tempElement;
7451
-
7452
+
7452
7453
  if (composer.commands.support(command)) {
7453
7454
  doc.execCommand(command, false, null);
7454
7455
  return;
7455
7456
  }
7456
-
7457
+
7457
7458
  if (list) {
7458
7459
  // Unwrap list
7459
7460
  // <ol><li>foo</li><li>bar</li></ol>
@@ -7483,7 +7484,7 @@ wysihtml5.commands.bold = {
7483
7484
  }
7484
7485
  }
7485
7486
  },
7486
-
7487
+
7487
7488
  state: function(composer) {
7488
7489
  var selectedNode = composer.selection.getSelectedNode();
7489
7490
  return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "OL" });
@@ -7497,12 +7498,12 @@ wysihtml5.commands.bold = {
7497
7498
  tempClassName = "_wysihtml5-temp-" + new Date().getTime(),
7498
7499
  isEmpty,
7499
7500
  tempElement;
7500
-
7501
+
7501
7502
  if (composer.commands.support(command)) {
7502
7503
  doc.execCommand(command, false, null);
7503
7504
  return;
7504
7505
  }
7505
-
7506
+
7506
7507
  if (list) {
7507
7508
  // Unwrap list
7508
7509
  // <ul><li>foo</li><li>bar</li></ul>
@@ -7532,7 +7533,7 @@ wysihtml5.commands.bold = {
7532
7533
  }
7533
7534
  }
7534
7535
  },
7535
-
7536
+
7536
7537
  state: function(composer) {
7537
7538
  var selectedNode = composer.selection.getSelectedNode();
7538
7539
  return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "UL" });
@@ -7553,7 +7554,7 @@ wysihtml5.commands.bold = {
7553
7554
  };(function(wysihtml5) {
7554
7555
  var CLASS_NAME = "wysiwyg-text-align-center",
7555
7556
  REG_EXP = /wysiwyg-text-align-[0-9a-z]+/g;
7556
-
7557
+
7557
7558
  wysihtml5.commands.justifyCenter = {
7558
7559
  exec: function(composer, command) {
7559
7560
  return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
@@ -7566,7 +7567,7 @@ wysihtml5.commands.bold = {
7566
7567
  })(wysihtml5);(function(wysihtml5) {
7567
7568
  var CLASS_NAME = "wysiwyg-text-align-left",
7568
7569
  REG_EXP = /wysiwyg-text-align-[0-9a-z]+/g;
7569
-
7570
+
7570
7571
  wysihtml5.commands.justifyLeft = {
7571
7572
  exec: function(composer, command) {
7572
7573
  return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
@@ -7579,7 +7580,7 @@ wysihtml5.commands.bold = {
7579
7580
  })(wysihtml5);(function(wysihtml5) {
7580
7581
  var CLASS_NAME = "wysiwyg-text-align-right",
7581
7582
  REG_EXP = /wysiwyg-text-align-[0-9a-z]+/g;
7582
-
7583
+
7583
7584
  wysihtml5.commands.justifyRight = {
7584
7585
  exec: function(composer, command) {
7585
7586
  return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
@@ -7592,7 +7593,7 @@ wysihtml5.commands.bold = {
7592
7593
  })(wysihtml5);(function(wysihtml5) {
7593
7594
  var CLASS_NAME = "wysiwyg-text-align-justify",
7594
7595
  REG_EXP = /wysiwyg-text-align-[0-9a-z]+/g;
7595
-
7596
+
7596
7597
  wysihtml5.commands.justifyFull = {
7597
7598
  exec: function(composer, command) {
7598
7599
  return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
@@ -7642,45 +7643,45 @@ wysihtml5.commands.redo = {
7642
7643
  UNDO_HTML = '<span id="_wysihtml5-undo" class="_wysihtml5-temp">' + wysihtml5.INVISIBLE_SPACE + '</span>',
7643
7644
  REDO_HTML = '<span id="_wysihtml5-redo" class="_wysihtml5-temp">' + wysihtml5.INVISIBLE_SPACE + '</span>',
7644
7645
  dom = wysihtml5.dom;
7645
-
7646
+
7646
7647
  function cleanTempElements(doc) {
7647
7648
  var tempElement;
7648
7649
  while (tempElement = doc.querySelector("._wysihtml5-temp")) {
7649
7650
  tempElement.parentNode.removeChild(tempElement);
7650
7651
  }
7651
7652
  }
7652
-
7653
+
7653
7654
  wysihtml5.UndoManager = wysihtml5.lang.Dispatcher.extend(
7654
7655
  /** @scope wysihtml5.UndoManager.prototype */ {
7655
7656
  constructor: function(editor) {
7656
7657
  this.editor = editor;
7657
7658
  this.composer = editor.composer;
7658
7659
  this.element = this.composer.element;
7659
-
7660
+
7660
7661
  this.position = 0;
7661
7662
  this.historyStr = [];
7662
7663
  this.historyDom = [];
7663
-
7664
+
7664
7665
  this.transact();
7665
-
7666
+
7666
7667
  this._observe();
7667
7668
  },
7668
-
7669
+
7669
7670
  _observe: function() {
7670
7671
  var that = this,
7671
7672
  doc = this.composer.sandbox.getDocument(),
7672
7673
  lastKey;
7673
-
7674
+
7674
7675
  // Catch CTRL+Z and CTRL+Y
7675
7676
  dom.observe(this.element, "keydown", function(event) {
7676
7677
  if (event.altKey || (!event.ctrlKey && !event.metaKey)) {
7677
7678
  return;
7678
7679
  }
7679
-
7680
+
7680
7681
  var keyCode = event.keyCode,
7681
7682
  isUndo = keyCode === Z_KEY && !event.shiftKey,
7682
7683
  isRedo = (keyCode === Z_KEY && event.shiftKey) || (keyCode === Y_KEY);
7683
-
7684
+
7684
7685
  if (isUndo) {
7685
7686
  that.undo();
7686
7687
  event.preventDefault();
@@ -7689,21 +7690,21 @@ wysihtml5.commands.redo = {
7689
7690
  event.preventDefault();
7690
7691
  }
7691
7692
  });
7692
-
7693
+
7693
7694
  // Catch delete and backspace
7694
7695
  dom.observe(this.element, "keydown", function(event) {
7695
7696
  var keyCode = event.keyCode;
7696
7697
  if (keyCode === lastKey) {
7697
7698
  return;
7698
7699
  }
7699
-
7700
+
7700
7701
  lastKey = keyCode;
7701
-
7702
+
7702
7703
  if (keyCode === BACKSPACE_KEY || keyCode === DELETE_KEY) {
7703
7704
  that.transact();
7704
7705
  }
7705
7706
  });
7706
-
7707
+
7707
7708
  // Now this is very hacky:
7708
7709
  // These days browsers don't offer a undo/redo event which we could hook into
7709
7710
  // to be notified when the user hits undo/redo in the contextmenu.
@@ -7716,7 +7717,7 @@ wysihtml5.commands.redo = {
7716
7717
  cleanTempElements(doc);
7717
7718
  clearInterval(interval);
7718
7719
  };
7719
-
7720
+
7720
7721
  dom.observe(this.element, "contextmenu", function() {
7721
7722
  cleanUp();
7722
7723
  that.composer.selection.executeAndRestoreSimple(function() {
@@ -7748,104 +7749,104 @@ wysihtml5.commands.redo = {
7748
7749
  }
7749
7750
  });
7750
7751
  }
7751
-
7752
+
7752
7753
  this.editor
7753
7754
  .observe("newword:composer", function() {
7754
7755
  that.transact();
7755
7756
  })
7756
-
7757
+
7757
7758
  .observe("beforecommand:composer", function() {
7758
7759
  that.transact();
7759
7760
  });
7760
7761
  },
7761
-
7762
+
7762
7763
  transact: function() {
7763
7764
  var previousHtml = this.historyStr[this.position - 1],
7764
7765
  currentHtml = this.composer.getValue();
7765
-
7766
+
7766
7767
  if (currentHtml === previousHtml) {
7767
7768
  return;
7768
7769
  }
7769
-
7770
+
7770
7771
  var length = this.historyStr.length = this.historyDom.length = this.position;
7771
7772
  if (length > MAX_HISTORY_ENTRIES) {
7772
7773
  this.historyStr.shift();
7773
7774
  this.historyDom.shift();
7774
7775
  this.position--;
7775
7776
  }
7776
-
7777
+
7777
7778
  this.position++;
7778
-
7779
+
7779
7780
  var range = this.composer.selection.getRange(),
7780
7781
  node = range.startContainer || this.element,
7781
7782
  offset = range.startOffset || 0,
7782
7783
  element,
7783
7784
  position;
7784
-
7785
+
7785
7786
  if (node.nodeType === wysihtml5.ELEMENT_NODE) {
7786
7787
  element = node;
7787
7788
  } else {
7788
7789
  element = node.parentNode;
7789
7790
  position = this.getChildNodeIndex(element, node);
7790
7791
  }
7791
-
7792
+
7792
7793
  element.setAttribute(DATA_ATTR_OFFSET, offset);
7793
7794
  if (typeof(position) !== "undefined") {
7794
7795
  element.setAttribute(DATA_ATTR_NODE, position);
7795
7796
  }
7796
-
7797
+
7797
7798
  var clone = this.element.cloneNode(!!currentHtml);
7798
7799
  this.historyDom.push(clone);
7799
7800
  this.historyStr.push(currentHtml);
7800
-
7801
+
7801
7802
  element.removeAttribute(DATA_ATTR_OFFSET);
7802
7803
  element.removeAttribute(DATA_ATTR_NODE);
7803
7804
  },
7804
-
7805
+
7805
7806
  undo: function() {
7806
7807
  this.transact();
7807
-
7808
+
7808
7809
  if (!this.undoPossible()) {
7809
7810
  return;
7810
7811
  }
7811
-
7812
+
7812
7813
  this.set(this.historyDom[--this.position - 1]);
7813
7814
  this.editor.fire("undo:composer");
7814
7815
  },
7815
-
7816
+
7816
7817
  redo: function() {
7817
7818
  if (!this.redoPossible()) {
7818
7819
  return;
7819
7820
  }
7820
-
7821
+
7821
7822
  this.set(this.historyDom[++this.position - 1]);
7822
7823
  this.editor.fire("redo:composer");
7823
7824
  },
7824
-
7825
+
7825
7826
  undoPossible: function() {
7826
7827
  return this.position > 1;
7827
7828
  },
7828
-
7829
+
7829
7830
  redoPossible: function() {
7830
7831
  return this.position < this.historyStr.length;
7831
7832
  },
7832
-
7833
+
7833
7834
  set: function(historyEntry) {
7834
7835
  this.element.innerHTML = "";
7835
-
7836
+
7836
7837
  var i = 0,
7837
7838
  childNodes = historyEntry.childNodes,
7838
7839
  length = historyEntry.childNodes.length;
7839
-
7840
+
7840
7841
  for (; i<length; i++) {
7841
7842
  this.element.appendChild(childNodes[i].cloneNode(true));
7842
7843
  }
7843
-
7844
+
7844
7845
  // Restore selection
7845
7846
  var offset,
7846
7847
  node,
7847
7848
  position;
7848
-
7849
+
7849
7850
  if (historyEntry.hasAttribute(DATA_ATTR_OFFSET)) {
7850
7851
  offset = historyEntry.getAttribute(DATA_ATTR_OFFSET);
7851
7852
  position = historyEntry.getAttribute(DATA_ATTR_NODE);
@@ -7857,14 +7858,14 @@ wysihtml5.commands.redo = {
7857
7858
  node.removeAttribute(DATA_ATTR_OFFSET);
7858
7859
  node.removeAttribute(DATA_ATTR_NODE);
7859
7860
  }
7860
-
7861
+
7861
7862
  if (position !== null) {
7862
7863
  node = this.getChildNodeByIndex(node, +position);
7863
7864
  }
7864
-
7865
+
7865
7866
  this.composer.selection.set(node, offset);
7866
7867
  },
7867
-
7868
+
7868
7869
  getChildNodeIndex: function(parent, child) {
7869
7870
  var i = 0,
7870
7871
  childNodes = parent.childNodes,
@@ -7875,7 +7876,7 @@ wysihtml5.commands.redo = {
7875
7876
  }
7876
7877
  }
7877
7878
  },
7878
-
7879
+
7879
7880
  getChildNodeByIndex: function(parent, index) {
7880
7881
  return parent.childNodes[index];
7881
7882
  }
@@ -7890,10 +7891,10 @@ wysihtml5.views.View = Base.extend(
7890
7891
  this.parent = parent;
7891
7892
  this.element = textareaElement;
7892
7893
  this.config = config;
7893
-
7894
+
7894
7895
  this._observeViewChange();
7895
7896
  },
7896
-
7897
+
7897
7898
  _observeViewChange: function() {
7898
7899
  var that = this;
7899
7900
  this.parent.observe("beforeload", function() {
@@ -7909,34 +7910,34 @@ wysihtml5.views.View = Base.extend(
7909
7910
  });
7910
7911
  });
7911
7912
  },
7912
-
7913
+
7913
7914
  focus: function() {
7914
7915
  if (this.element.ownerDocument.querySelector(":focus") === this.element) {
7915
7916
  return;
7916
7917
  }
7917
-
7918
+
7918
7919
  try { this.element.focus(); } catch(e) {}
7919
7920
  },
7920
-
7921
+
7921
7922
  hide: function() {
7922
7923
  this.element.style.display = "none";
7923
7924
  },
7924
-
7925
+
7925
7926
  show: function() {
7926
7927
  this.element.style.display = "";
7927
7928
  },
7928
-
7929
+
7929
7930
  disable: function() {
7930
7931
  this.element.setAttribute("disabled", "disabled");
7931
7932
  },
7932
-
7933
+
7933
7934
  enable: function() {
7934
7935
  this.element.removeAttribute("disabled");
7935
7936
  }
7936
7937
  });(function(wysihtml5) {
7937
7938
  var dom = wysihtml5.dom,
7938
7939
  browser = wysihtml5.browser;
7939
-
7940
+
7940
7941
  wysihtml5.views.Composer = wysihtml5.views.View.extend(
7941
7942
  /** @scope wysihtml5.views.Composer.prototype */ {
7942
7943
  name: "composer",
@@ -7956,7 +7957,7 @@ wysihtml5.views.View = Base.extend(
7956
7957
 
7957
7958
  getValue: function(parse) {
7958
7959
  var value = this.isEmpty() ? "" : wysihtml5.quirks.getCorrectInnerHTML(this.element);
7959
-
7960
+
7960
7961
  if (parse) {
7961
7962
  value = this.parent.parse(value);
7962
7963
  }
@@ -7973,7 +7974,7 @@ wysihtml5.views.View = Base.extend(
7973
7974
  if (parse) {
7974
7975
  html = this.parent.parse(html);
7975
7976
  }
7976
-
7977
+
7977
7978
  try {
7978
7979
  this.element.innerHTML = html;
7979
7980
  } catch (e) {
@@ -8014,9 +8015,9 @@ wysihtml5.views.View = Base.extend(
8014
8015
  if (wysihtml5.browser.doesAsyncFocus() && this.hasPlaceholderSet()) {
8015
8016
  this.clear();
8016
8017
  }
8017
-
8018
+
8018
8019
  this.base();
8019
-
8020
+
8020
8021
  var lastChild = this.element.lastChild;
8021
8022
  if (setToEnd && lastChild) {
8022
8023
  if (lastChild.nodeName === "BR") {
@@ -8038,7 +8039,7 @@ wysihtml5.views.View = Base.extend(
8038
8039
  isEmpty: function() {
8039
8040
  var innerHTML = this.element.innerHTML,
8040
8041
  elementsWithVisualValue = "blockquote, ul, ol, img, embed, object, table, iframe, svg, video, audio, button, input, select, textarea";
8041
- return innerHTML === "" ||
8042
+ return innerHTML === "" ||
8042
8043
  innerHTML === this.CARET_HACK ||
8043
8044
  this.hasPlaceholderSet() ||
8044
8045
  (this.getTextContent() === "" && !this.element.querySelector(elementsWithVisualValue));
@@ -8046,17 +8047,17 @@ wysihtml5.views.View = Base.extend(
8046
8047
 
8047
8048
  _initSandbox: function() {
8048
8049
  var that = this;
8049
-
8050
+
8050
8051
  this.sandbox = new dom.Sandbox(function() {
8051
8052
  that._create();
8052
8053
  }, {
8053
8054
  stylesheets: this.config.stylesheets
8054
8055
  });
8055
8056
  this.iframe = this.sandbox.getIframe();
8056
-
8057
+
8057
8058
  var textareaElement = this.textarea.element;
8058
8059
  dom.insert(this.iframe).after(textareaElement);
8059
-
8060
+
8060
8061
  // Create hidden field which tells the server after submit, that the user used an wysiwyg editor
8061
8062
  if (textareaElement.form) {
8062
8063
  var hiddenField = document.createElement("input");
@@ -8069,23 +8070,23 @@ wysihtml5.views.View = Base.extend(
8069
8070
 
8070
8071
  _create: function() {
8071
8072
  var that = this;
8072
-
8073
+
8073
8074
  this.doc = this.sandbox.getDocument();
8074
8075
  this.element = this.doc.body;
8075
8076
  this.textarea = this.parent.textarea;
8076
8077
  this.element.innerHTML = this.textarea.getValue(true);
8077
8078
  this.enable();
8078
-
8079
+
8079
8080
  // Make sure our selection handler is ready
8080
8081
  this.selection = new wysihtml5.Selection(this.parent);
8081
-
8082
+
8082
8083
  // Make sure commands dispatcher is ready
8083
8084
  this.commands = new wysihtml5.Commands(this.parent);
8084
8085
 
8085
8086
  dom.copyAttributes([
8086
8087
  "className", "spellcheck", "title", "lang", "dir", "accessKey"
8087
8088
  ]).from(this.textarea.element).to(this.element);
8088
-
8089
+
8089
8090
  dom.addClass(this.element, this.config.composerClassName);
8090
8091
 
8091
8092
  // Make the editor look like the original textarea, by syncing styles
@@ -8108,7 +8109,7 @@ wysihtml5.views.View = Base.extend(
8108
8109
  if (placeholderText) {
8109
8110
  dom.simulatePlaceholder(this.parent, this, placeholderText);
8110
8111
  }
8111
-
8112
+
8112
8113
  // Make sure that the browser avoids using inline styles whenever possible
8113
8114
  this.commands.exec("styleWithCSS", false);
8114
8115
 
@@ -8164,7 +8165,7 @@ wysihtml5.views.View = Base.extend(
8164
8165
  dom.autoLink(endContainer.parentNode);
8165
8166
  });
8166
8167
  });
8167
-
8168
+
8168
8169
  dom.observe(this.element, "blur", function() {
8169
8170
  dom.autoLink(that.element);
8170
8171
  });
@@ -8225,11 +8226,11 @@ wysihtml5.views.View = Base.extend(
8225
8226
  style = target.style,
8226
8227
  i = 0,
8227
8228
  property;
8228
-
8229
+
8229
8230
  if (target.nodeName !== "IMG") {
8230
8231
  return;
8231
8232
  }
8232
-
8233
+
8233
8234
  for (; i<propertiesLength; i++) {
8234
8235
  property = properties[i];
8235
8236
  if (style[property]) {
@@ -8237,13 +8238,13 @@ wysihtml5.views.View = Base.extend(
8237
8238
  style[property] = "";
8238
8239
  }
8239
8240
  }
8240
-
8241
+
8241
8242
  // After resizing IE sometimes forgets to remove the old resize handles
8242
8243
  wysihtml5.quirks.redraw(element);
8243
8244
  };
8244
-
8245
+
8245
8246
  this.commands.exec("enableObjectResizing", true);
8246
-
8247
+
8247
8248
  // IE sets inline styles after resizing objects
8248
8249
  // The following lines make sure that the width/height css properties
8249
8250
  // are copied over to the width/height attributes
@@ -8253,7 +8254,7 @@ wysihtml5.views.View = Base.extend(
8253
8254
  dom.observe(element, "DOMAttrModified", adoptStyles);
8254
8255
  }
8255
8256
  },
8256
-
8257
+
8257
8258
  _initUndoManager: function() {
8258
8259
  this.undoManager = new wysihtml5.UndoManager(this.parent);
8259
8260
  }
@@ -8310,13 +8311,13 @@ wysihtml5.views.View = Base.extend(
8310
8311
  "body { min-height: 100%; padding: 0; margin: 0; margin-top: -1px; padding-top: 1px; }",
8311
8312
  "._wysihtml5-temp { display: none; }",
8312
8313
  wysihtml5.browser.isGecko ?
8313
- "body.placeholder { color: graytext !important; }" :
8314
+ "body.placeholder { color: graytext !important; }" :
8314
8315
  "body.placeholder { color: #a9a9a9 !important; }",
8315
8316
  "body[disabled] { background-color: #eee !important; color: #999 !important; cursor: default !important; }",
8316
8317
  // Ensure that user see's broken images and can delete them
8317
8318
  "img:-moz-broken { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }"
8318
8319
  ];
8319
-
8320
+
8320
8321
  /**
8321
8322
  * With "setActive" IE offers a smart way of focusing elements without scrolling them into view:
8322
8323
  * http://msdn.microsoft.com/en-us/library/ms536738(v=vs.85).aspx
@@ -8340,7 +8341,7 @@ wysihtml5.views.View = Base.extend(
8340
8341
  left: elementStyle.left,
8341
8342
  WebkitUserSelect: elementStyle.WebkitUserSelect
8342
8343
  };
8343
-
8344
+
8344
8345
  dom.setStyles({
8345
8346
  position: "absolute",
8346
8347
  top: "-99999px",
@@ -8348,11 +8349,11 @@ wysihtml5.views.View = Base.extend(
8348
8349
  // Don't ask why but temporarily setting -webkit-user-select to none makes the whole thing performing smoother
8349
8350
  WebkitUserSelect: "none"
8350
8351
  }).on(element);
8351
-
8352
+
8352
8353
  element.focus();
8353
-
8354
+
8354
8355
  dom.setStyles(originalStyles).on(element);
8355
-
8356
+
8356
8357
  if (win.scrollTo) {
8357
8358
  // Some browser extensions unset this method to prevent annoyances
8358
8359
  // "Better PopUp Blocker" for Chrome http://code.google.com/p/betterpopupblocker/source/browse/trunk/blockStart.js#100
@@ -8361,8 +8362,8 @@ wysihtml5.views.View = Base.extend(
8361
8362
  }
8362
8363
  }
8363
8364
  };
8364
-
8365
-
8365
+
8366
+
8366
8367
  wysihtml5.views.Composer.prototype.style = function() {
8367
8368
  var that = this,
8368
8369
  originalActiveElement = doc.querySelector(":focus"),
@@ -8371,47 +8372,47 @@ wysihtml5.views.View = Base.extend(
8371
8372
  originalPlaceholder = hasPlaceholder && textareaElement.getAttribute("placeholder");
8372
8373
  this.focusStylesHost = this.focusStylesHost || HOST_TEMPLATE.cloneNode(false);
8373
8374
  this.blurStylesHost = this.blurStylesHost || HOST_TEMPLATE.cloneNode(false);
8374
-
8375
+
8375
8376
  // Remove placeholder before copying (as the placeholder has an affect on the computed style)
8376
8377
  if (hasPlaceholder) {
8377
8378
  textareaElement.removeAttribute("placeholder");
8378
8379
  }
8379
-
8380
+
8380
8381
  if (textareaElement === originalActiveElement) {
8381
8382
  textareaElement.blur();
8382
8383
  }
8383
-
8384
+
8384
8385
  // --------- iframe styles (has to be set before editor styles, otherwise IE9 sets wrong fontFamily on blurStylesHost) ---------
8385
8386
  dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.iframe).andTo(this.blurStylesHost);
8386
-
8387
+
8387
8388
  // --------- editor styles ---------
8388
8389
  dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.element).andTo(this.blurStylesHost);
8389
-
8390
+
8390
8391
  // --------- apply standard rules ---------
8391
8392
  dom.insertCSS(ADDITIONAL_CSS_RULES).into(this.element.ownerDocument);
8392
-
8393
+
8393
8394
  // --------- :focus styles ---------
8394
8395
  focusWithoutScrolling(textareaElement);
8395
8396
  dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.focusStylesHost);
8396
8397
  dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.focusStylesHost);
8397
-
8398
+
8398
8399
  // Make sure that we don't change the display style of the iframe when copying styles oblur/onfocus
8399
8400
  // this is needed for when the change_view event is fired where the iframe is hidden and then
8400
8401
  // the blur event fires and re-displays it
8401
8402
  var boxFormattingStyles = wysihtml5.lang.array(BOX_FORMATTING).without(["display"]);
8402
-
8403
+
8403
8404
  // --------- restore focus ---------
8404
8405
  if (originalActiveElement) {
8405
8406
  originalActiveElement.focus();
8406
8407
  } else {
8407
8408
  textareaElement.blur();
8408
8409
  }
8409
-
8410
+
8410
8411
  // --------- restore placeholder ---------
8411
8412
  if (hasPlaceholder) {
8412
8413
  textareaElement.setAttribute("placeholder", originalPlaceholder);
8413
8414
  }
8414
-
8415
+
8415
8416
  // When copying styles, we only get the computed style which is never returned in percent unit
8416
8417
  // Therefore we've to recalculate style onresize
8417
8418
  if (!wysihtml5.browser.hasCurrentStyleProperty()) {
@@ -8434,7 +8435,7 @@ wysihtml5.views.View = Base.extend(
8434
8435
  textareaElement.style.display = originalTextareaDisplayStyle;
8435
8436
  });
8436
8437
  }
8437
-
8438
+
8438
8439
  // --------- Sync focus/blur styles ---------
8439
8440
  this.parent.observe("focus:composer", function() {
8440
8441
  dom.copyStyles(boxFormattingStyles) .from(that.focusStylesHost).to(that.iframe);
@@ -8445,7 +8446,7 @@ wysihtml5.views.View = Base.extend(
8445
8446
  dom.copyStyles(boxFormattingStyles) .from(that.blurStylesHost).to(that.iframe);
8446
8447
  dom.copyStyles(TEXT_FORMATTING) .from(that.blurStylesHost).to(that.element);
8447
8448
  });
8448
-
8449
+
8449
8450
  return this;
8450
8451
  };
8451
8452
  })(wysihtml5);/**
@@ -8467,7 +8468,7 @@ wysihtml5.views.View = Base.extend(
8467
8468
  "73": "italic", // I
8468
8469
  "85": "underline" // U
8469
8470
  };
8470
-
8471
+
8471
8472
  wysihtml5.views.Composer.prototype.observe = function() {
8472
8473
  var that = this,
8473
8474
  state = this.getValue(),
@@ -8506,7 +8507,7 @@ wysihtml5.views.View = Base.extend(
8506
8507
  }
8507
8508
  that.parent.fire("blur").fire("blur:composer");
8508
8509
  });
8509
-
8510
+
8510
8511
  if (browser.isIos()) {
8511
8512
  // When on iPad/iPhone/IPod after clicking outside of editor, the editor loses focus
8512
8513
  // but the UI still acts as if the editor has focus (blinking caret and onscreen keyboard visible)
@@ -8522,7 +8523,7 @@ wysihtml5.views.View = Base.extend(
8522
8523
  }
8523
8524
  input.focus();
8524
8525
  input.parentNode.removeChild(input);
8525
-
8526
+
8526
8527
  window.scrollTo(originalScrollLeft, originalScrollTop);
8527
8528
  });
8528
8529
  }
@@ -8560,17 +8561,17 @@ wysihtml5.views.View = Base.extend(
8560
8561
  }
8561
8562
  });
8562
8563
  }
8563
-
8564
+
8564
8565
  if (browser.hasHistoryIssue() && browser.supportsSelectionModify()) {
8565
8566
  dom.observe(element, "keydown", function(event) {
8566
8567
  if (!event.metaKey && !event.ctrlKey) {
8567
8568
  return;
8568
8569
  }
8569
-
8570
+
8570
8571
  var keyCode = event.keyCode,
8571
8572
  win = element.ownerDocument.defaultView,
8572
8573
  selection = win.getSelection();
8573
-
8574
+
8574
8575
  if (keyCode === 37 || keyCode === 39) {
8575
8576
  if (keyCode === 37) {
8576
8577
  selection.modify("extend", "left", "lineboundary");
@@ -8588,7 +8589,7 @@ wysihtml5.views.View = Base.extend(
8588
8589
  }
8589
8590
  });
8590
8591
  }
8591
-
8592
+
8592
8593
  // --------- Shortcut logic ---------
8593
8594
  dom.observe(element, "keydown", function(event) {
8594
8595
  var keyCode = event.keyCode,
@@ -8623,7 +8624,7 @@ wysihtml5.views.View = Base.extend(
8623
8624
  IMG: "Image: ",
8624
8625
  A: "Link: "
8625
8626
  };
8626
-
8627
+
8627
8628
  dom.observe(element, "mouseover", function(event) {
8628
8629
  var target = event.target,
8629
8630
  nodeName = target.nodeName,
@@ -8643,7 +8644,7 @@ wysihtml5.views.View = Base.extend(
8643
8644
  */
8644
8645
  (function(wysihtml5) {
8645
8646
  var INTERVAL = 400;
8646
-
8647
+
8647
8648
  wysihtml5.views.Synchronizer = Base.extend(
8648
8649
  /** @scope wysihtml5.views.Synchronizer.prototype */ {
8649
8650
 
@@ -8738,17 +8739,17 @@ wysihtml5.views.View = Base.extend(
8738
8739
  wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8739
8740
  /** @scope wysihtml5.views.Textarea.prototype */ {
8740
8741
  name: "textarea",
8741
-
8742
+
8742
8743
  constructor: function(parent, textareaElement, config) {
8743
8744
  this.base(parent, textareaElement, config);
8744
-
8745
+
8745
8746
  this._observe();
8746
8747
  },
8747
-
8748
+
8748
8749
  clear: function() {
8749
8750
  this.element.value = "";
8750
8751
  },
8751
-
8752
+
8752
8753
  getValue: function(parse) {
8753
8754
  var value = this.isEmpty() ? "" : this.element.value;
8754
8755
  if (parse) {
@@ -8756,14 +8757,14 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8756
8757
  }
8757
8758
  return value;
8758
8759
  },
8759
-
8760
+
8760
8761
  setValue: function(html, parse) {
8761
8762
  if (parse) {
8762
8763
  html = this.parent.parse(html);
8763
8764
  }
8764
8765
  this.element.value = html;
8765
8766
  },
8766
-
8767
+
8767
8768
  hasPlaceholderSet: function() {
8768
8769
  var supportsPlaceholder = wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),
8769
8770
  placeholderText = this.element.getAttribute("placeholder") || null,
@@ -8771,11 +8772,11 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8771
8772
  isEmpty = !value;
8772
8773
  return (supportsPlaceholder && isEmpty) || (value === placeholderText);
8773
8774
  },
8774
-
8775
+
8775
8776
  isEmpty: function() {
8776
8777
  return !wysihtml5.lang.string(this.element.value).trim() || this.hasPlaceholderSet();
8777
8778
  },
8778
-
8779
+
8779
8780
  _observe: function() {
8780
8781
  var element = this.element,
8781
8782
  parent = this.parent,
@@ -8788,13 +8789,13 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8788
8789
  * This is the case for focusin and focusout, so let's use them whenever possible, kkthxbai
8789
8790
  */
8790
8791
  events = wysihtml5.browser.supportsEvent("focusin") ? ["focusin", "focusout", "change"] : ["focus", "blur", "change"];
8791
-
8792
+
8792
8793
  parent.observe("beforeload", function() {
8793
8794
  wysihtml5.dom.observe(element, events, function(event) {
8794
8795
  var eventName = eventMapping[event.type] || event.type;
8795
8796
  parent.fire(eventName).fire(eventName + ":textarea");
8796
8797
  });
8797
-
8798
+
8798
8799
  wysihtml5.dom.observe(element, ["paste", "drop"], function() {
8799
8800
  setTimeout(function() { parent.fire("paste").fire("paste:textarea"); }, 0);
8800
8801
  });
@@ -8836,8 +8837,8 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8836
8837
  SELECTOR_FORM_ELEMENTS = "input, select, textarea",
8837
8838
  SELECTOR_FIELDS = "[data-wysihtml5-dialog-field]",
8838
8839
  ATTRIBUTE_FIELDS = "data-wysihtml5-dialog-field";
8839
-
8840
-
8840
+
8841
+
8841
8842
  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
8842
8843
  /** @scope wysihtml5.toolbar.Dialog.prototype */ {
8843
8844
  constructor: function(link, container) {
@@ -8849,7 +8850,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8849
8850
  if (this._observed) {
8850
8851
  return;
8851
8852
  }
8852
-
8853
+
8853
8854
  var that = this,
8854
8855
  callbackWrapper = function(event) {
8855
8856
  var attributes = that._serialize();
@@ -8917,14 +8918,14 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8917
8918
  /**
8918
8919
  * Takes the attributes of the "elementToChange"
8919
8920
  * and inserts them in their corresponding dialog input fields
8920
- *
8921
+ *
8921
8922
  * Assume the "elementToChange" looks like this:
8922
8923
  * <a href="http://www.google.com" target="_blank">foo</a>
8923
8924
  *
8924
8925
  * and we have the following dialog:
8925
8926
  * <input type="text" data-wysihtml5-dialog-field="href" value="">
8926
8927
  * <input type="text" data-wysihtml5-dialog-field="target" value="">
8927
- *
8928
+ *
8928
8929
  * after calling _interpolate() the dialog will look like this
8929
8930
  * <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
8930
8931
  * <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
@@ -8942,18 +8943,18 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8942
8943
  i = 0;
8943
8944
  for (; i<length; i++) {
8944
8945
  field = fields[i];
8945
-
8946
+
8946
8947
  // Never change elements where the user is currently typing in
8947
8948
  if (field === focusedElement) {
8948
8949
  continue;
8949
8950
  }
8950
-
8951
+
8951
8952
  // Don't update hidden fields
8952
8953
  // See https://github.com/xing/wysihtml5/pull/14
8953
8954
  if (avoidHiddenFields && field.type === "hidden") {
8954
8955
  continue;
8955
8956
  }
8956
-
8957
+
8957
8958
  fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
8958
8959
  newValue = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
8959
8960
  field.value = newValue;
@@ -8967,7 +8968,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
8967
8968
  if (dom.hasClass(this.link, CLASS_NAME_OPENED)) {
8968
8969
  return;
8969
8970
  }
8970
-
8971
+
8971
8972
  var that = this,
8972
8973
  firstField = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
8973
8974
  this.elementToChange = elementToChange;
@@ -9007,17 +9008,17 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9007
9008
  *
9008
9009
  * Current HTML5 draft can be found here
9009
9010
  * http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html
9010
- *
9011
+ *
9011
9012
  * "Accessing Google Speech API Chrome 11"
9012
9013
  * http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
9013
9014
  */
9014
9015
  (function(wysihtml5) {
9015
9016
  var dom = wysihtml5.dom;
9016
-
9017
+
9017
9018
  var linkStyles = {
9018
9019
  position: "relative"
9019
9020
  };
9020
-
9021
+
9021
9022
  var wrapperStyles = {
9022
9023
  left: 0,
9023
9024
  margin: 0,
@@ -9028,7 +9029,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9028
9029
  top: 0,
9029
9030
  zIndex: 1
9030
9031
  };
9031
-
9032
+
9032
9033
  var inputStyles = {
9033
9034
  cursor: "inherit",
9034
9035
  fontSize: "50px",
@@ -9040,12 +9041,12 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9040
9041
  right: "-4px",
9041
9042
  top: "50%"
9042
9043
  };
9043
-
9044
+
9044
9045
  var inputAttributes = {
9045
9046
  "x-webkit-speech": "",
9046
9047
  "speech": ""
9047
9048
  };
9048
-
9049
+
9049
9050
  wysihtml5.toolbar.Speech = function(parent, link) {
9050
9051
  var input = document.createElement("input");
9051
9052
  if (!wysihtml5.browser.supportsSpeechApiOn(input)) {
@@ -9058,32 +9059,32 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9058
9059
  }
9059
9060
 
9060
9061
  var wrapper = document.createElement("div");
9061
-
9062
+
9062
9063
  wysihtml5.lang.object(wrapperStyles).merge({
9063
9064
  width: link.offsetWidth + "px",
9064
9065
  height: link.offsetHeight + "px"
9065
9066
  });
9066
-
9067
+
9067
9068
  dom.insert(input).into(wrapper);
9068
9069
  dom.insert(wrapper).into(link);
9069
-
9070
+
9070
9071
  dom.setStyles(inputStyles).on(input);
9071
9072
  dom.setAttributes(inputAttributes).on(input);
9072
-
9073
+
9073
9074
  dom.setStyles(wrapperStyles).on(wrapper);
9074
9075
  dom.setStyles(linkStyles).on(link);
9075
-
9076
+
9076
9077
  var eventName = "onwebkitspeechchange" in input ? "webkitspeechchange" : "speechchange";
9077
9078
  dom.observe(input, eventName, function() {
9078
9079
  parent.execCommand("insertText", input.value);
9079
9080
  input.value = "";
9080
9081
  });
9081
-
9082
+
9082
9083
  dom.observe(input, "click", function(event) {
9083
9084
  if (dom.hasClass(link, "wysihtml5-command-disabled")) {
9084
9085
  event.preventDefault();
9085
9086
  }
9086
-
9087
+
9087
9088
  event.stopPropagation();
9088
9089
  });
9089
9090
  };
@@ -9109,7 +9110,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9109
9110
  CLASS_NAME_COMMAND_ACTIVE = "wysihtml5-command-active",
9110
9111
  CLASS_NAME_ACTION_ACTIVE = "wysihtml5-action-active",
9111
9112
  dom = wysihtml5.dom;
9112
-
9113
+
9113
9114
  wysihtml5.toolbar.Toolbar = Base.extend(
9114
9115
  /** @scope wysihtml5.toolbar.Toolbar.prototype */ {
9115
9116
  constructor: function(editor, container) {
@@ -9122,7 +9123,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9122
9123
 
9123
9124
  this._observe();
9124
9125
  this.show();
9125
-
9126
+
9126
9127
  var speechInputLinks = this.container.querySelectorAll("[data-wysihtml5-command=insertSpeech]"),
9127
9128
  length = speechInputLinks.length,
9128
9129
  i = 0;
@@ -9147,7 +9148,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9147
9148
  value = link.getAttribute("data-wysihtml5-" + type + "-value");
9148
9149
  group = this.container.querySelector("[data-wysihtml5-" + type + "-group='" + name + "']");
9149
9150
  dialog = this._getDialog(link, name);
9150
-
9151
+
9151
9152
  mapping[name + ":" + value] = {
9152
9153
  link: link,
9153
9154
  group: group,
@@ -9164,7 +9165,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9164
9165
  dialogElement = this.container.querySelector("[data-wysihtml5-dialog='" + command + "']"),
9165
9166
  dialog,
9166
9167
  caretBookmark;
9167
-
9168
+
9168
9169
  if (dialogElement) {
9169
9170
  dialog = new wysihtml5.toolbar.Dialog(link, dialogElement);
9170
9171
 
@@ -9179,7 +9180,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9179
9180
  that.composer.selection.setBookmark(caretBookmark);
9180
9181
  }
9181
9182
  that._execCommand(command, attributes);
9182
-
9183
+
9183
9184
  that.editor.fire("save:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
9184
9185
  });
9185
9186
 
@@ -9240,7 +9241,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9240
9241
  links = this.commandLinks.concat(this.actionLinks),
9241
9242
  length = links.length,
9242
9243
  i = 0;
9243
-
9244
+
9244
9245
  for (; i<length; i++) {
9245
9246
  // 'javascript:;' and unselectable=on Needed for IE, but done in all browsers to make sure that all get the same css applied
9246
9247
  // (you know, a:link { ... } doesn't match anchors with missing href attribute)
@@ -9252,7 +9253,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9252
9253
 
9253
9254
  // Needed for opera and chrome
9254
9255
  dom.delegate(container, "[data-wysihtml5-command], [data-wysihtml5-action]", "mousedown", function(event) { event.preventDefault(); });
9255
-
9256
+
9256
9257
  dom.delegate(container, "[data-wysihtml5-command]", "click", function(event) {
9257
9258
  var link = this,
9258
9259
  command = link.getAttribute("data-wysihtml5-command"),
@@ -9357,10 +9358,10 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9357
9358
  }
9358
9359
  }
9359
9360
  }
9360
-
9361
+
9361
9362
  for (i in actionMapping) {
9362
9363
  action = actionMapping[i];
9363
-
9364
+
9364
9365
  if (action.name === "change_view") {
9365
9366
  action.state = this.editor.currentView === this.editor.textarea;
9366
9367
  if (action.state) {
@@ -9380,7 +9381,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9380
9381
  this.container.style.display = "none";
9381
9382
  }
9382
9383
  });
9383
-
9384
+
9384
9385
  })(wysihtml5);
9385
9386
  /**
9386
9387
  * WYSIHTML5 Editor
@@ -9413,9 +9414,9 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9413
9414
  */
9414
9415
  (function(wysihtml5) {
9415
9416
  var undef;
9416
-
9417
+
9417
9418
  var defaultConfig = {
9418
- // Give the editor a name, the name will also be set as class name on the iframe and on the iframe's body
9419
+ // Give the editor a name, the name will also be set as class name on the iframe and on the iframe's body
9419
9420
  name: undef,
9420
9421
  // Whether the editor should look like the textarea (by adopting styles)
9421
9422
  style: true,
@@ -9439,7 +9440,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9439
9440
  // Whether the rich text editor should be rendered on touch devices (wysihtml5 >= 0.3.0 comes with basic support for iOS 5)
9440
9441
  supportTouchDevices: true
9441
9442
  };
9442
-
9443
+
9443
9444
  wysihtml5.Editor = wysihtml5.lang.Dispatcher.extend(
9444
9445
  /** @scope wysihtml5.Editor.prototype */ {
9445
9446
  constructor: function(textareaElement, config) {
@@ -9448,36 +9449,36 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9448
9449
  this.textarea = new wysihtml5.views.Textarea(this, this.textareaElement, this.config);
9449
9450
  this.currentView = this.textarea;
9450
9451
  this._isCompatible = wysihtml5.browser.supported();
9451
-
9452
+
9452
9453
  // Sort out unsupported/unwanted browsers here
9453
9454
  if (!this._isCompatible || (!this.config.supportTouchDevices && wysihtml5.browser.isTouchDevice())) {
9454
9455
  var that = this;
9455
9456
  setTimeout(function() { that.fire("beforeload").fire("load"); }, 0);
9456
9457
  return;
9457
9458
  }
9458
-
9459
+
9459
9460
  // Add class name to body, to indicate that the editor is supported
9460
9461
  wysihtml5.dom.addClass(document.body, this.config.bodyClassName);
9461
-
9462
+
9462
9463
  this.composer = new wysihtml5.views.Composer(this, this.textareaElement, this.config);
9463
9464
  this.currentView = this.composer;
9464
-
9465
+
9465
9466
  if (typeof(this.config.parser) === "function") {
9466
9467
  this._initParser();
9467
9468
  }
9468
-
9469
+
9469
9470
  this.observe("beforeload", function() {
9470
9471
  this.synchronizer = new wysihtml5.views.Synchronizer(this, this.textarea, this.composer);
9471
9472
  if (this.config.toolbar) {
9472
9473
  this.toolbar = new wysihtml5.toolbar.Toolbar(this, this.config.toolbar);
9473
9474
  }
9474
9475
  });
9475
-
9476
+
9476
9477
  try {
9477
9478
  console.log("Heya! This page is using wysihtml5 for rich text editing. Check out https://github.com/xing/wysihtml5");
9478
9479
  } catch(e) {}
9479
9480
  },
9480
-
9481
+
9481
9482
  isCompatible: function() {
9482
9483
  return this._isCompatible;
9483
9484
  },
@@ -9493,11 +9494,11 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9493
9494
 
9494
9495
  setValue: function(html, parse) {
9495
9496
  this.fire("unset_placeholder");
9496
-
9497
+
9497
9498
  if (!html) {
9498
9499
  return this.clear();
9499
9500
  }
9500
-
9501
+
9501
9502
  this.currentView.setValue(html, parse);
9502
9503
  return this;
9503
9504
  },
@@ -9514,7 +9515,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9514
9515
  this.currentView.disable();
9515
9516
  return this;
9516
9517
  },
9517
-
9518
+
9518
9519
  /**
9519
9520
  * Activate editor
9520
9521
  */
@@ -9522,15 +9523,15 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9522
9523
  this.currentView.enable();
9523
9524
  return this;
9524
9525
  },
9525
-
9526
+
9526
9527
  isEmpty: function() {
9527
9528
  return this.currentView.isEmpty();
9528
9529
  },
9529
-
9530
+
9530
9531
  hasPlaceholderSet: function() {
9531
9532
  return this.currentView.hasPlaceholderSet();
9532
9533
  },
9533
-
9534
+
9534
9535
  parse: function(htmlOrElement) {
9535
9536
  var returnValue = this.config.parser(htmlOrElement, this.config.parserRules, this.composer.sandbox.getDocument(), true);
9536
9537
  if (typeof(htmlOrElement) === "object") {
@@ -9538,7 +9539,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9538
9539
  }
9539
9540
  return returnValue;
9540
9541
  },
9541
-
9542
+
9542
9543
  /**
9543
9544
  * Prepare html parser logic
9544
9545
  * - Observes for paste and drop
@@ -9552,7 +9553,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9552
9553
  that.parse(that.composer.element);
9553
9554
  }, keepScrollPosition);
9554
9555
  });
9555
-
9556
+
9556
9557
  this.observe("paste:textarea", function() {
9557
9558
  var value = this.textarea.getValue(),
9558
9559
  newValue;
@@ -9561,4 +9562,4 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
9561
9562
  });
9562
9563
  }
9563
9564
  });
9564
- })(wysihtml5);
9565
+ })(wysihtml5);