wysihtml-rails 0.5.0.beta4 → 0.5.0.beta5

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.
@@ -1,418 +1,368 @@
1
- // TODO: in future try to replace most inline compability checks with polyfills for code readability
1
+ /**
2
+ * @license wysihtml5x v0.5.0-beta5
3
+ * https://github.com/Edicy/wysihtml5
4
+ *
5
+ * Author: Christopher Blum (https://github.com/tiff)
6
+ * Secondary author of extended features: Oliver Pulges (https://github.com/pulges)
7
+ *
8
+ * Copyright (C) 2012 XING AG
9
+ * Licensed under the MIT license (MIT)
10
+ *
11
+ */
12
+ var wysihtml5 = {
13
+ version: "0.5.0-beta5",
14
+
15
+ // namespaces
16
+ commands: {},
17
+ dom: {},
18
+ quirks: {},
19
+ toolbar: {},
20
+ lang: {},
21
+ selection: {},
22
+ views: {},
23
+
24
+ INVISIBLE_SPACE: "\uFEFF",
25
+ INVISIBLE_SPACE_REG_EXP: /\uFEFF/g,
26
+
27
+ EMPTY_FUNCTION: function() {},
28
+
29
+ ELEMENT_NODE: 1,
30
+ TEXT_NODE: 3,
2
31
 
3
- // IE8 SUPPORT BLOCK
4
- // You can compile without all this if IE8 is not needed
32
+ BACKSPACE_KEY: 8,
33
+ ENTER_KEY: 13,
34
+ ESCAPE_KEY: 27,
35
+ SPACE_KEY: 32,
36
+ TAB_KEY: 9,
37
+ DELETE_KEY: 46
38
+ };
39
+ ;wysihtml5.polyfills = function(win, doc) {
40
+
41
+ // TODO: in future try to replace most inline compability checks with polyfills for code readability
5
42
 
6
- // String trim for ie8
7
- if (!String.prototype.trim) {
43
+ // IE8 SUPPORT BLOCK
44
+ // You can compile without all this if IE8 is not needed
45
+
46
+ // String trim for ie8
47
+ if (!String.prototype.trim) {
48
+ (function() {
49
+ // Make sure we trim BOM and NBSP
50
+ var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
51
+ String.prototype.trim = function() {
52
+ return this.replace(rtrim, '');
53
+ };
54
+ })();
55
+ }
56
+
57
+ // addEventListener, removeEventListener
8
58
  (function() {
9
- // Make sure we trim BOM and NBSP
10
- var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
11
- String.prototype.trim = function() {
12
- return this.replace(rtrim, '');
59
+ var s_add = 'addEventListener',
60
+ s_rem = 'removeEventListener';
61
+ if( doc[s_add] ) return;
62
+ win.Element.prototype[ s_add ] = win[ s_add ] = doc[ s_add ] = function( on, fn, self ) {
63
+ return (self = this).attachEvent( 'on' + on, function(e){
64
+ var e = e || win.event;
65
+ e.target = e.target || e.srcElement;
66
+ e.preventDefault = e.preventDefault || function(){e.returnValue = false};
67
+ e.stopPropagation = e.stopPropagation || function(){e.cancelBubble = true};
68
+ e.which = e.button ? ( e.button === 2 ? 3 : e.button === 4 ? 2 : e.button ) : e.keyCode;
69
+ fn.call(self, e);
70
+ });
13
71
  };
14
- })();
15
- }
16
-
17
- // addEventListener, removeEventListener
18
- // TODO: make usage of wysihtml5.dom.observe obsolete
19
- (function() {
20
- if (!Event.prototype.preventDefault) {
21
- Event.prototype.preventDefault=function() {
22
- this.returnValue=false;
72
+ win.Element.prototype[ s_rem ] = win[ s_rem ] = doc[ s_rem ] = function( on, fn ) {
73
+ return this.detachEvent( 'on' + on, fn );
23
74
  };
75
+ })();
76
+
77
+ // element.textContent polyfill.
78
+ if (Object.defineProperty && Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(win.Element.prototype, "textContent") && !Object.getOwnPropertyDescriptor(win.Element.prototype, "textContent").get) {
79
+ (function() {
80
+ var innerText = Object.getOwnPropertyDescriptor(win.Element.prototype, "innerText");
81
+ Object.defineProperty(win.Element.prototype, "textContent",
82
+ {
83
+ get: function() {
84
+ return innerText.get.call(this);
85
+ },
86
+ set: function(s) {
87
+ return innerText.set.call(this, s);
88
+ }
89
+ }
90
+ );
91
+ })();
24
92
  }
25
- if (!Event.prototype.stopPropagation) {
26
- Event.prototype.stopPropagation=function() {
27
- this.cancelBubble=true;
93
+
94
+ // isArray polyfill for ie8
95
+ if(!Array.isArray) {
96
+ Array.isArray = function(arg) {
97
+ return Object.prototype.toString.call(arg) === '[object Array]';
28
98
  };
29
99
  }
30
- if (!Element.prototype.addEventListener) {
31
- var eventListeners=[];
32
-
33
- var addEventListener=function(type,listener /*, useCapture (will be ignored) */) {
34
- var self=this;
35
- var wrapper=function(e) {
36
- e.target=e.srcElement;
37
- e.currentTarget=self;
38
- if (listener.handleEvent) {
39
- listener.handleEvent(e);
40
- } else {
41
- listener.call(self,e);
42
- }
43
- };
44
- if (type=="DOMContentLoaded") {
45
- var wrapper2=function(e) {
46
- if (document.readyState=="complete") {
47
- wrapper(e);
48
- }
49
- };
50
- document.attachEvent("onreadystatechange",wrapper2);
51
- eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2});
52
-
53
- if (document.readyState=="complete") {
54
- var e=new Event();
55
- e.srcElement=window;
56
- wrapper2(e);
57
- }
58
- } else {
59
- this.attachEvent("on"+type,wrapper);
60
- eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper});
61
- }
100
+
101
+ // Array indexOf for ie8
102
+ if (!Array.prototype.indexOf) {
103
+ Array.prototype.indexOf = function(a,f) {
104
+ for(var c=this.length,r=-1,d=f>>>0; ~(c-d); r=this[--c]===a?c:r);
105
+ return r;
62
106
  };
63
- var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) {
64
- var counter=0;
65
- while (counter<eventListeners.length) {
66
- var eventListener=eventListeners[counter];
67
- if (eventListener.object==this && eventListener.type==type && eventListener.listener==listener) {
68
- if (type=="DOMContentLoaded") {
69
- this.detachEvent("onreadystatechange",eventListener.wrapper);
70
- } else {
71
- this.detachEvent("on"+type,eventListener.wrapper);
72
- }
73
- eventListeners.splice(counter, 1);
74
- break;
75
- }
76
- ++counter;
77
- }
107
+ }
108
+
109
+ // Function.prototype.bind()
110
+ // TODO: clean the code from variable 'that' as it can be confusing
111
+ if (!Function.prototype.bind) {
112
+ Function.prototype.bind = function(oThis) {
113
+ if (typeof this !== 'function') {
114
+ // closest thing possible to the ECMAScript 5
115
+ // internal IsCallable function
116
+ throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
117
+ }
118
+
119
+ var aArgs = Array.prototype.slice.call(arguments, 1),
120
+ fToBind = this,
121
+ fNOP = function() {},
122
+ fBound = function() {
123
+ return fToBind.apply(this instanceof fNOP && oThis
124
+ ? this
125
+ : oThis,
126
+ aArgs.concat(Array.prototype.slice.call(arguments)));
127
+ };
128
+
129
+ fNOP.prototype = this.prototype;
130
+ fBound.prototype = new fNOP();
131
+
132
+ return fBound;
78
133
  };
79
- Element.prototype.addEventListener=addEventListener;
80
- Element.prototype.removeEventListener=removeEventListener;
81
- if (HTMLDocument) {
82
- HTMLDocument.prototype.addEventListener=addEventListener;
83
- HTMLDocument.prototype.removeEventListener=removeEventListener;
84
- }
85
- if (Window) {
86
- Window.prototype.addEventListener=addEventListener;
87
- Window.prototype.removeEventListener=removeEventListener;
88
- }
89
134
  }
90
- })();
91
135
 
92
- // element.textContent polyfill.
93
- if (Object.defineProperty && Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
94
- (function() {
95
- var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
96
- Object.defineProperty(Element.prototype, "textContent",
97
- {
98
- get: function() {
99
- return innerText.get.call(this);
100
- },
101
- set: function(s) {
102
- return innerText.set.call(this, s);
103
- }
104
- }
105
- );
106
- })();
107
- }
108
-
109
- // isArray polyfill for ie8
110
- if(!Array.isArray) {
111
- Array.isArray = function(arg) {
112
- return Object.prototype.toString.call(arg) === '[object Array]';
113
- };
114
- }
136
+ // Element.matches Adds ie8 support and unifies nonstandard function names in other browsers
137
+ win.Element && function(ElementPrototype) {
138
+ ElementPrototype.matches = ElementPrototype.matches ||
139
+ ElementPrototype.matchesSelector ||
140
+ ElementPrototype.mozMatchesSelector ||
141
+ ElementPrototype.msMatchesSelector ||
142
+ ElementPrototype.oMatchesSelector ||
143
+ ElementPrototype.webkitMatchesSelector ||
144
+ function (selector) {
145
+ var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
146
+ while (nodes[++i] && nodes[i] != node);
147
+ return !!nodes[i];
148
+ };
149
+ }(win.Element.prototype);
115
150
 
116
- // Array indexOf for ie8
117
- if (!Array.prototype.indexOf) {
118
- Array.prototype.indexOf = function(a,f) {
119
- for(var c=this.length,r=-1,d=f>>>0; ~(c-d); r=this[--c]===a?c:r);
120
- return r;
121
- };
122
- }
123
-
124
- // Function.prototype.bind()
125
- // TODO: clean the code from variable 'that' as it can be confusing
126
- if (!Function.prototype.bind) {
127
- Function.prototype.bind = function(oThis) {
128
- if (typeof this !== 'function') {
129
- // closest thing possible to the ECMAScript 5
130
- // internal IsCallable function
131
- throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
132
- }
133
-
134
- var aArgs = Array.prototype.slice.call(arguments, 1),
135
- fToBind = this,
136
- fNOP = function() {},
137
- fBound = function() {
138
- return fToBind.apply(this instanceof fNOP && oThis
139
- ? this
140
- : oThis,
141
- aArgs.concat(Array.prototype.slice.call(arguments)));
142
- };
151
+ // Element.classList for ie8-9 (toggle all IE)
152
+ // source http://purl.eligrey.com/github/classList.js/blob/master/classList.js
143
153
 
144
- fNOP.prototype = this.prototype;
145
- fBound.prototype = new fNOP();
154
+ if ("document" in win) {
155
+ // Full polyfill for browsers with no classList support
156
+ if (!("classList" in doc.createElement("_"))) {
157
+ (function(view) {
158
+ "use strict";
159
+ if (!('Element' in view)) return;
146
160
 
147
- return fBound;
148
- };
149
- }
150
-
151
- // Element.matches Adds ie8 support and unifies nonstandard function names in other browsers
152
- this.Element && function(ElementPrototype) {
153
- ElementPrototype.matches = ElementPrototype.matches ||
154
- ElementPrototype.matchesSelector ||
155
- ElementPrototype.mozMatchesSelector ||
156
- ElementPrototype.msMatchesSelector ||
157
- ElementPrototype.oMatchesSelector ||
158
- ElementPrototype.webkitMatchesSelector ||
159
- function (selector) {
160
- var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
161
- while (nodes[++i] && nodes[i] != node);
162
- return !!nodes[i];
163
- };
164
- }(Element.prototype);
165
-
166
- // Element.classList for ie8-9 (toggle all IE)
167
- // source http://purl.eligrey.com/github/classList.js/blob/master/classList.js
168
-
169
- if ("document" in self) {
170
- // Full polyfill for browsers with no classList support
171
- if (!("classList" in document.createElement("_"))) {
172
- (function(view) {
173
- "use strict";
174
- if (!('Element' in view)) return;
175
-
176
- var
177
- classListProp = "classList",
178
- protoProp = "prototype",
179
- elemCtrProto = view.Element[protoProp],
180
- objCtr = Object,
181
- strTrim = String[protoProp].trim || function() {
182
- return this.replace(/^\s+|\s+$/g, "");
183
- },
184
- arrIndexOf = Array[protoProp].indexOf || function(item) {
161
+ var
162
+ classListProp = "classList",
163
+ protoProp = "prototype",
164
+ elemCtrProto = view.Element[protoProp],
165
+ objCtr = Object,
166
+ strTrim = String[protoProp].trim || function() {
167
+ return this.replace(/^\s+|\s+$/g, "");
168
+ },
169
+ arrIndexOf = Array[protoProp].indexOf || function(item) {
170
+ var
171
+ i = 0,
172
+ len = this.length;
173
+ for (; i < len; i++) {
174
+ if (i in this && this[i] === item) {
175
+ return i;
176
+ }
177
+ }
178
+ return -1;
179
+ }, // Vendors: please allow content code to instantiate DOMExceptions
180
+ DOMEx = function(type, message) {
181
+ this.name = type;
182
+ this.code = DOMException[type];
183
+ this.message = message;
184
+ },
185
+ checkTokenAndGetIndex = function(classList, token) {
186
+ if (token === "") {
187
+ throw new DOMEx(
188
+ "SYNTAX_ERR", "An invalid or illegal string was specified"
189
+ );
190
+ }
191
+ if (/\s/.test(token)) {
192
+ throw new DOMEx(
193
+ "INVALID_CHARACTER_ERR", "String contains an invalid character"
194
+ );
195
+ }
196
+ return arrIndexOf.call(classList, token);
197
+ },
198
+ ClassList = function(elem) {
199
+ var
200
+ trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
201
+ classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
202
+ i = 0,
203
+ len = classes.length;
204
+ for (; i < len; i++) {
205
+ this.push(classes[i]);
206
+ }
207
+ this._updateClassName = function() {
208
+ elem.setAttribute("class", this.toString());
209
+ };
210
+ },
211
+ classListProto = ClassList[protoProp] = [],
212
+ classListGetter = function() {
213
+ return new ClassList(this);
214
+ };
215
+ // Most DOMException implementations don't allow calling DOMException's toString()
216
+ // on non-DOMExceptions. Error's toString() is sufficient here.
217
+ DOMEx[protoProp] = Error[protoProp];
218
+ classListProto.item = function(i) {
219
+ return this[i] || null;
220
+ };
221
+ classListProto.contains = function(token) {
222
+ token += "";
223
+ return checkTokenAndGetIndex(this, token) !== -1;
224
+ };
225
+ classListProto.add = function() {
185
226
  var
227
+ tokens = arguments,
186
228
  i = 0,
187
- len = this.length;
188
- for (; i < len; i++) {
189
- if (i in this && this[i] === item) {
190
- return i;
229
+ l = tokens.length,
230
+ token, updated = false;
231
+ do {
232
+ token = tokens[i] + "";
233
+ if (checkTokenAndGetIndex(this, token) === -1) {
234
+ this.push(token);
235
+ updated = true;
191
236
  }
192
237
  }
193
- return -1;
194
- }, // Vendors: please allow content code to instantiate DOMExceptions
195
- DOMEx = function(type, message) {
196
- this.name = type;
197
- this.code = DOMException[type];
198
- this.message = message;
199
- },
200
- checkTokenAndGetIndex = function(classList, token) {
201
- if (token === "") {
202
- throw new DOMEx(
203
- "SYNTAX_ERR", "An invalid or illegal string was specified"
204
- );
205
- }
206
- if (/\s/.test(token)) {
207
- throw new DOMEx(
208
- "INVALID_CHARACTER_ERR", "String contains an invalid character"
209
- );
238
+ while (++i < l);
239
+
240
+ if (updated) {
241
+ this._updateClassName();
210
242
  }
211
- return arrIndexOf.call(classList, token);
212
- },
213
- ClassList = function(elem) {
243
+ };
244
+ classListProto.remove = function() {
214
245
  var
215
- trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
216
- classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
246
+ tokens = arguments,
217
247
  i = 0,
218
- len = classes.length;
219
- for (; i < len; i++) {
220
- this.push(classes[i]);
221
- }
222
- this._updateClassName = function() {
223
- elem.setAttribute("class", this.toString());
224
- };
225
- },
226
- classListProto = ClassList[protoProp] = [],
227
- classListGetter = function() {
228
- return new ClassList(this);
229
- };
230
- // Most DOMException implementations don't allow calling DOMException's toString()
231
- // on non-DOMExceptions. Error's toString() is sufficient here.
232
- DOMEx[protoProp] = Error[protoProp];
233
- classListProto.item = function(i) {
234
- return this[i] || null;
235
- };
236
- classListProto.contains = function(token) {
237
- token += "";
238
- return checkTokenAndGetIndex(this, token) !== -1;
239
- };
240
- classListProto.add = function() {
241
- var
242
- tokens = arguments,
243
- i = 0,
244
- l = tokens.length,
245
- token, updated = false;
246
- do {
247
- token = tokens[i] + "";
248
- if (checkTokenAndGetIndex(this, token) === -1) {
249
- this.push(token);
250
- updated = true;
251
- }
252
- }
253
- while (++i < l);
254
-
255
- if (updated) {
256
- this._updateClassName();
257
- }
258
- };
259
- classListProto.remove = function() {
260
- var
261
- tokens = arguments,
262
- i = 0,
263
- l = tokens.length,
264
- token, updated = false,
265
- index;
266
- do {
267
- token = tokens[i] + "";
268
- index = checkTokenAndGetIndex(this, token);
269
- while (index !== -1) {
270
- this.splice(index, 1);
271
- updated = true;
248
+ l = tokens.length,
249
+ token, updated = false,
250
+ index;
251
+ do {
252
+ token = tokens[i] + "";
272
253
  index = checkTokenAndGetIndex(this, token);
254
+ while (index !== -1) {
255
+ this.splice(index, 1);
256
+ updated = true;
257
+ index = checkTokenAndGetIndex(this, token);
258
+ }
273
259
  }
274
- }
275
- while (++i < l);
276
-
277
- if (updated) {
278
- this._updateClassName();
279
- }
280
- };
281
- classListProto.toggle = function(token, force) {
282
- token += "";
260
+ while (++i < l);
283
261
 
284
- var
285
- result = this.contains(token),
286
- method = result ?
287
- force !== true && "remove" :
288
- force !== false && "add";
262
+ if (updated) {
263
+ this._updateClassName();
264
+ }
265
+ };
266
+ classListProto.toggle = function(token, force) {
267
+ token += "";
289
268
 
290
- if (method) {
291
- this[method](token);
292
- }
269
+ var
270
+ result = this.contains(token),
271
+ method = result ?
272
+ force !== true && "remove" :
273
+ force !== false && "add";
293
274
 
294
- if (force === true || force === false) {
295
- return force;
296
- } else {
297
- return !result;
298
- }
299
- };
300
- classListProto.toString = function() {
301
- return this.join(" ");
302
- };
275
+ if (method) {
276
+ this[method](token);
277
+ }
303
278
 
304
- if (objCtr.defineProperty) {
305
- var classListPropDesc = {
306
- get: classListGetter,
307
- enumerable: true,
308
- configurable: true
279
+ if (force === true || force === false) {
280
+ return force;
281
+ } else {
282
+ return !result;
283
+ }
309
284
  };
310
- try {
311
- objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
312
- } catch (ex) { // IE 8 doesn't support enumerable:true
313
- if (ex.number === -0x7FF5EC54) {
314
- classListPropDesc.enumerable = false;
285
+ classListProto.toString = function() {
286
+ return this.join(" ");
287
+ };
288
+
289
+ if (objCtr.defineProperty) {
290
+ var classListPropDesc = {
291
+ get: classListGetter,
292
+ enumerable: true,
293
+ configurable: true
294
+ };
295
+ try {
315
296
  objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
297
+ } catch (ex) { // IE 8 doesn't support enumerable:true
298
+ if (ex.number === -0x7FF5EC54) {
299
+ classListPropDesc.enumerable = false;
300
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
301
+ }
316
302
  }
303
+ } else if (objCtr[protoProp].__defineGetter__) {
304
+ elemCtrProto.__defineGetter__(classListProp, classListGetter);
317
305
  }
318
- } else if (objCtr[protoProp].__defineGetter__) {
319
- elemCtrProto.__defineGetter__(classListProp, classListGetter);
320
- }
321
306
 
322
- }(self));
307
+ }(win));
323
308
 
324
- } else if ("DOMTokenList" in window) {
325
- // There is full or partial native classList support, so just check if we need
326
- // to normalize the add/remove and toggle APIs.
327
- // DOMTokenList is expected to exist (removes conflicts with multiple polyfills present on site)
309
+ } else if ("DOMTokenList" in win) {
310
+ // There is full or partial native classList support, so just check if we need
311
+ // to normalize the add/remove and toggle APIs.
312
+ // DOMTokenList is expected to exist (removes conflicts with multiple polyfills present on site)
328
313
 
329
- (function() {
330
- "use strict";
314
+ (function() {
315
+ "use strict";
331
316
 
332
- var testElement = document.createElement("_");
317
+ var testElement = doc.createElement("_");
333
318
 
334
- testElement.classList.add("c1", "c2");
319
+ testElement.classList.add("c1", "c2");
335
320
 
336
- // Polyfill for IE 10/11 and Firefox <26, where classList.add and
337
- // classList.remove exist but support only one argument at a time.
338
- if (!testElement.classList.contains("c2")) {
339
- var createMethod = function(method) {
340
- var original = DOMTokenList.prototype[method];
321
+ // Polyfill for IE 10/11 and Firefox <26, where classList.add and
322
+ // classList.remove exist but support only one argument at a time.
323
+ if (!testElement.classList.contains("c2")) {
324
+ var createMethod = function(method) {
325
+ var original = win.DOMTokenList.prototype[method];
341
326
 
342
- DOMTokenList.prototype[method] = function(token) {
343
- var i, len = arguments.length;
327
+ win.DOMTokenList.prototype[method] = function(token) {
328
+ var i, len = arguments.length;
344
329
 
345
- for (i = 0; i < len; i++) {
346
- token = arguments[i];
347
- original.call(this, token);
348
- }
330
+ for (i = 0; i < len; i++) {
331
+ token = arguments[i];
332
+ original.call(this, token);
333
+ }
334
+ };
349
335
  };
350
- };
351
- createMethod('add');
352
- createMethod('remove');
353
- }
354
-
355
- testElement.classList.toggle("c3", false);
356
-
357
- // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
358
- // support the second argument.
359
- if (testElement.classList.contains("c3")) {
360
- var _toggle = DOMTokenList.prototype.toggle;
361
-
362
- DOMTokenList.prototype.toggle = function(token, force) {
363
- if (1 in arguments && !this.contains(token) === !force) {
364
- return force;
365
- } else {
366
- return _toggle.call(this, token);
367
- }
368
- };
369
-
370
- }
336
+ createMethod('add');
337
+ createMethod('remove');
338
+ }
371
339
 
372
- testElement = null;
373
- }());
340
+ testElement.classList.toggle("c3", false);
374
341
 
375
- }
342
+ // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
343
+ // support the second argument.
344
+ if (testElement.classList.contains("c3")) {
345
+ var _toggle = win.DOMTokenList.prototype.toggle;
376
346
 
377
- }
378
- ;/**
379
- * @license wysihtml5x v0.5.0-beta4
380
- * https://github.com/Edicy/wysihtml5
381
- *
382
- * Author: Christopher Blum (https://github.com/tiff)
383
- * Secondary author of extended features: Oliver Pulges (https://github.com/pulges)
384
- *
385
- * Copyright (C) 2012 XING AG
386
- * Licensed under the MIT license (MIT)
387
- *
388
- */
389
- var wysihtml5 = {
390
- version: "0.5.0-beta4",
391
-
392
- // namespaces
393
- commands: {},
394
- dom: {},
395
- quirks: {},
396
- toolbar: {},
397
- lang: {},
398
- selection: {},
399
- views: {},
347
+ win.DOMTokenList.prototype.toggle = function(token, force) {
348
+ if (1 in arguments && !this.contains(token) === !force) {
349
+ return force;
350
+ } else {
351
+ return _toggle.call(this, token);
352
+ }
353
+ };
400
354
 
401
- INVISIBLE_SPACE: "\uFEFF",
402
- INVISIBLE_SPACE_REG_EXP: /\uFEFF/g,
355
+ }
403
356
 
404
- EMPTY_FUNCTION: function() {},
357
+ testElement = null;
358
+ }());
405
359
 
406
- ELEMENT_NODE: 1,
407
- TEXT_NODE: 3,
360
+ }
408
361
 
409
- BACKSPACE_KEY: 8,
410
- ENTER_KEY: 13,
411
- ESCAPE_KEY: 27,
412
- SPACE_KEY: 32,
413
- TAB_KEY: 9,
414
- DELETE_KEY: 46
362
+ }
415
363
  };
364
+
365
+ wysihtml5.polyfills(window, document);
416
366
  ;/**
417
367
  * Rangy, a cross-browser JavaScript range and selection library
418
368
  * https://github.com/timdown/rangy
@@ -7510,6 +7460,10 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
7510
7460
  this._unset(iframeDocument, "cookie", "", true);
7511
7461
  }
7512
7462
 
7463
+ if (wysihtml5.polyfills) {
7464
+ wysihtml5.polyfills(iframeWindow, iframeDocument);
7465
+ }
7466
+
7513
7467
  this.loaded = true;
7514
7468
 
7515
7469
  // Trigger the callback
@@ -7692,7 +7646,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
7692
7646
  dom.removeClass(view.element, CLASS_NAME);
7693
7647
  },
7694
7648
  set = function() {
7695
- if (view.isEmpty()) {
7649
+ if (view.isEmpty() && !view.placeholderSet) {
7696
7650
  view.placeholderSet = true;
7697
7651
  view.setValue(placeholderText);
7698
7652
  dom.addClass(view.element, CLASS_NAME);
@@ -9401,7 +9355,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9401
9355
  this.createTemporaryCaretSpaceAfter(node);
9402
9356
  }
9403
9357
  }
9404
- },
9358
+ }.bind(this),
9405
9359
  sel;
9406
9360
 
9407
9361
  range.setStartAfter(node);
@@ -14036,12 +13990,6 @@ wysihtml5.views.View = Base.extend(
14036
13990
  this.parent.fire("unset_placeholder");
14037
13991
  }).bind(this), false);
14038
13992
 
14039
- // --------- IE 8+9 focus the editor when the iframe is clicked (without actually firing the 'focus' event on the <body>) ---------
14040
- if (!this.config.contentEditableMode && browser.hasIframeFocusIssue()) {
14041
- container.addEventListener("focus", handleIframeFocus.bind(this), false);
14042
- container.addEventListener("blur", handleIframeBlur.bind(this), false);
14043
- }
14044
-
14045
13993
  };
14046
13994
  })(wysihtml5);
14047
13995
  ;/**