bootsy 2.0.8 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);