wysia 0.0.3 → 0.0.4
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.
- data/README.md +8 -0
- data/lib/wysia/version.rb +1 -1
- data/lib/wysia/wysia_form_helper.rb +1 -1
- data/vendor/assets/javascripts/wysia.js +3 -2
- data/vendor/assets/javascripts/wysiwyg/simple.js +32 -0
- data/vendor/assets/javascripts/wysiwyg/wysihtml5-0.3.0.js +380 -380
- data/vendor/assets/stylesheets/wysiwyg/stylesheet.css.scss +8 -11
- metadata +5 -4
@@ -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
|
@@ -3255,7 +3255,7 @@ var Base = function() {
|
|
3255
3255
|
|
3256
3256
|
Base.extend = function(_instance, _static) { // subclass
|
3257
3257
|
var extend = Base.prototype.extend;
|
3258
|
-
|
3258
|
+
|
3259
3259
|
// build the prototype
|
3260
3260
|
Base._prototyping = true;
|
3261
3261
|
var proto = new this;
|
@@ -3264,7 +3264,7 @@ Base.extend = function(_instance, _static) { // subclass
|
|
3264
3264
|
// call this method from any other method to invoke that method's ancestor
|
3265
3265
|
};
|
3266
3266
|
delete Base._prototyping;
|
3267
|
-
|
3267
|
+
|
3268
3268
|
// create the wrapper for the constructor function
|
3269
3269
|
//var constructor = proto.constructor.valueOf(); //-dean
|
3270
3270
|
var constructor = proto.constructor;
|
@@ -3279,7 +3279,7 @@ Base.extend = function(_instance, _static) { // subclass
|
|
3279
3279
|
}
|
3280
3280
|
}
|
3281
3281
|
};
|
3282
|
-
|
3282
|
+
|
3283
3283
|
// build the class interface
|
3284
3284
|
klass.ancestor = this;
|
3285
3285
|
klass.extend = this.extend;
|
@@ -3297,7 +3297,7 @@ Base.extend = function(_instance, _static) { // subclass
|
|
3297
3297
|
return klass;
|
3298
3298
|
};
|
3299
3299
|
|
3300
|
-
Base.prototype = {
|
3300
|
+
Base.prototype = {
|
3301
3301
|
extend: function(source, value) {
|
3302
3302
|
if (arguments.length > 1) { // extending with a name/value pair
|
3303
3303
|
var ancestor = this[source];
|
@@ -3356,7 +3356,7 @@ Base = Base.extend({
|
|
3356
3356
|
}, {
|
3357
3357
|
ancestor: Object,
|
3358
3358
|
version: "1.1",
|
3359
|
-
|
3359
|
+
|
3360
3360
|
forEach: function(object, block, context) {
|
3361
3361
|
for (var key in object) {
|
3362
3362
|
if (this.prototype[key] === undefined) {
|
@@ -3364,7 +3364,7 @@ Base = Base.extend({
|
|
3364
3364
|
}
|
3365
3365
|
}
|
3366
3366
|
},
|
3367
|
-
|
3367
|
+
|
3368
3368
|
implement: function() {
|
3369
3369
|
for (var i = 0; i < arguments.length; i++) {
|
3370
3370
|
if (typeof arguments[i] == "function") {
|
@@ -3377,7 +3377,7 @@ Base = Base.extend({
|
|
3377
3377
|
}
|
3378
3378
|
return this;
|
3379
3379
|
},
|
3380
|
-
|
3380
|
+
|
3381
3381
|
toString: function() {
|
3382
3382
|
return String(this.valueOf());
|
3383
3383
|
}
|
@@ -3393,15 +3393,15 @@ wysihtml5.browser = (function() {
|
|
3393
3393
|
isWebKit = userAgent.indexOf("AppleWebKit/") !== -1,
|
3394
3394
|
isChrome = userAgent.indexOf("Chrome/") !== -1,
|
3395
3395
|
isOpera = userAgent.indexOf("Opera/") !== -1;
|
3396
|
-
|
3396
|
+
|
3397
3397
|
function iosVersion(userAgent) {
|
3398
3398
|
return ((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [, 0])[1];
|
3399
3399
|
}
|
3400
|
-
|
3400
|
+
|
3401
3401
|
return {
|
3402
3402
|
// Static variable needed, publicly accessible, to be able override it in unit tests
|
3403
3403
|
USER_AGENT: userAgent,
|
3404
|
-
|
3404
|
+
|
3405
3405
|
/**
|
3406
3406
|
* Exclude browsers that are not capable of displaying and handling
|
3407
3407
|
* contentEditable as desired:
|
@@ -3420,22 +3420,22 @@ wysihtml5.browser = (function() {
|
|
3420
3420
|
hasQuerySelectorSupport = document.querySelector && document.querySelectorAll,
|
3421
3421
|
// contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)
|
3422
3422
|
isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1;
|
3423
|
-
|
3423
|
+
|
3424
3424
|
return hasContentEditableSupport
|
3425
3425
|
&& hasEditingApiSupport
|
3426
3426
|
&& hasQuerySelectorSupport
|
3427
3427
|
&& !isIncompatibleMobileBrowser;
|
3428
3428
|
},
|
3429
|
-
|
3429
|
+
|
3430
3430
|
isTouchDevice: function() {
|
3431
3431
|
return this.supportsEvent("touchmove");
|
3432
3432
|
},
|
3433
|
-
|
3433
|
+
|
3434
3434
|
isIos: function() {
|
3435
3435
|
var userAgent = this.USER_AGENT.toLowerCase();
|
3436
3436
|
return userAgent.indexOf("webkit") !== -1 && userAgent.indexOf("mobile") !== -1;
|
3437
3437
|
},
|
3438
|
-
|
3438
|
+
|
3439
3439
|
/**
|
3440
3440
|
* Whether the browser supports sandboxed iframes
|
3441
3441
|
* Currently only IE 6+ offers such feature <iframe security="restricted">
|
@@ -3509,7 +3509,7 @@ wysihtml5.browser = (function() {
|
|
3509
3509
|
firesOnDropOnlyWhenOnDragOverIsCancelled: function() {
|
3510
3510
|
return isWebKit || isGecko;
|
3511
3511
|
},
|
3512
|
-
|
3512
|
+
|
3513
3513
|
/**
|
3514
3514
|
* Whether the browser supports the event.dataTransfer property in a proper way
|
3515
3515
|
*/
|
@@ -3560,7 +3560,7 @@ wysihtml5.browser = (function() {
|
|
3560
3560
|
"insertUnorderedList": isIE || isOpera || isWebKit,
|
3561
3561
|
"insertOrderedList": isIE || isOpera || isWebKit
|
3562
3562
|
};
|
3563
|
-
|
3563
|
+
|
3564
3564
|
// Firefox throws errors for queryCommandSupported, so we have to build up our own object of supported commands
|
3565
3565
|
var supported = {
|
3566
3566
|
"insertHTML": isGecko
|
@@ -3677,7 +3677,7 @@ wysihtml5.browser = (function() {
|
|
3677
3677
|
supportsSelectionModify: function() {
|
3678
3678
|
return "getSelection" in window && "modify" in window.getSelection();
|
3679
3679
|
},
|
3680
|
-
|
3680
|
+
|
3681
3681
|
/**
|
3682
3682
|
* Whether the browser supports the classList object for fast className manipulation
|
3683
3683
|
* See https://developer.mozilla.org/en/DOM/element.classList
|
@@ -3685,14 +3685,14 @@ wysihtml5.browser = (function() {
|
|
3685
3685
|
supportsClassList: function() {
|
3686
3686
|
return "classList" in testElement;
|
3687
3687
|
},
|
3688
|
-
|
3688
|
+
|
3689
3689
|
/**
|
3690
3690
|
* Opera needs a white space after a <br> in order to position the caret correctly
|
3691
3691
|
*/
|
3692
3692
|
needsSpaceAfterLineBreak: function() {
|
3693
3693
|
return isOpera;
|
3694
3694
|
},
|
3695
|
-
|
3695
|
+
|
3696
3696
|
/**
|
3697
3697
|
* Whether the browser supports the speech api on the given element
|
3698
3698
|
* See http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
|
@@ -3707,7 +3707,7 @@ wysihtml5.browser = (function() {
|
|
3707
3707
|
var chromeVersion = userAgent.match(/Chrome\/(\d+)/) || [, 0];
|
3708
3708
|
return chromeVersion[1] >= 11 && ("onwebkitspeechchange" in input || "speech" in input);
|
3709
3709
|
},
|
3710
|
-
|
3710
|
+
|
3711
3711
|
/**
|
3712
3712
|
* IE9 crashes when setting a getter via Object.defineProperty on XMLHttpRequest or XDomainRequest
|
3713
3713
|
* See https://connect.microsoft.com/ie/feedback/details/650112
|
@@ -3716,21 +3716,21 @@ wysihtml5.browser = (function() {
|
|
3716
3716
|
crashesWhenDefineProperty: function(property) {
|
3717
3717
|
return isIE && (property === "XMLHttpRequest" || property === "XDomainRequest");
|
3718
3718
|
},
|
3719
|
-
|
3719
|
+
|
3720
3720
|
/**
|
3721
3721
|
* IE is the only browser who fires the "focus" event not immediately when .focus() is called on an element
|
3722
3722
|
*/
|
3723
3723
|
doesAsyncFocus: function() {
|
3724
3724
|
return isIE;
|
3725
3725
|
},
|
3726
|
-
|
3726
|
+
|
3727
3727
|
/**
|
3728
3728
|
* 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
|
3729
3729
|
*/
|
3730
3730
|
hasProblemsSettingCaretAfterImg: function() {
|
3731
3731
|
return isIE;
|
3732
3732
|
},
|
3733
|
-
|
3733
|
+
|
3734
3734
|
hasUndoInContextMenu: function() {
|
3735
3735
|
return isGecko || isChrome || isOpera;
|
3736
3736
|
}
|
@@ -3754,7 +3754,7 @@ wysihtml5.browser = (function() {
|
|
3754
3754
|
return false;
|
3755
3755
|
}
|
3756
3756
|
},
|
3757
|
-
|
3757
|
+
|
3758
3758
|
/**
|
3759
3759
|
* Substract one array from another
|
3760
3760
|
*
|
@@ -3774,10 +3774,10 @@ wysihtml5.browser = (function() {
|
|
3774
3774
|
}
|
3775
3775
|
return newArr;
|
3776
3776
|
},
|
3777
|
-
|
3777
|
+
|
3778
3778
|
/**
|
3779
3779
|
* Return a clean native array
|
3780
|
-
*
|
3780
|
+
*
|
3781
3781
|
* Following will convert a Live NodeList to a proper Array
|
3782
3782
|
* @example
|
3783
3783
|
* var childNodes = wysihtml5.lang.array(document.body.childNodes).get();
|
@@ -3848,11 +3848,11 @@ wysihtml5.browser = (function() {
|
|
3848
3848
|
}
|
3849
3849
|
return this;
|
3850
3850
|
},
|
3851
|
-
|
3851
|
+
|
3852
3852
|
get: function() {
|
3853
3853
|
return obj;
|
3854
3854
|
},
|
3855
|
-
|
3855
|
+
|
3856
3856
|
/**
|
3857
3857
|
* @example
|
3858
3858
|
* wysihtml5.lang.object({ foo: 1 }).clone();
|
@@ -3866,7 +3866,7 @@ wysihtml5.browser = (function() {
|
|
3866
3866
|
}
|
3867
3867
|
return newObj;
|
3868
3868
|
},
|
3869
|
-
|
3869
|
+
|
3870
3870
|
/**
|
3871
3871
|
* @example
|
3872
3872
|
* wysihtml5.lang.object([]).isArray();
|
@@ -3890,7 +3890,7 @@ wysihtml5.browser = (function() {
|
|
3890
3890
|
trim: function() {
|
3891
3891
|
return str.replace(WHITE_SPACE_START, "").replace(WHITE_SPACE_END, "");
|
3892
3892
|
},
|
3893
|
-
|
3893
|
+
|
3894
3894
|
/**
|
3895
3895
|
* @example
|
3896
3896
|
* wysihtml5.lang.string("Hello #{name}").interpolate({ name: "Christopher" });
|
@@ -3902,7 +3902,7 @@ wysihtml5.browser = (function() {
|
|
3902
3902
|
}
|
3903
3903
|
return str;
|
3904
3904
|
},
|
3905
|
-
|
3905
|
+
|
3906
3906
|
/**
|
3907
3907
|
* @example
|
3908
3908
|
* wysihtml5.lang.string("Hello Tom").replace("Tom").with("Hans");
|
@@ -3946,7 +3946,7 @@ wysihtml5.browser = (function() {
|
|
3946
3946
|
TRAILING_CHAR_REG_EXP = /([^\w\/\-](,?))$/i,
|
3947
3947
|
MAX_DISPLAY_LENGTH = 100,
|
3948
3948
|
BRACKETS = { ")": "(", "]": "[", "}": "{" };
|
3949
|
-
|
3949
|
+
|
3950
3950
|
function autoLink(element) {
|
3951
3951
|
if (_hasParentThatShouldBeIgnored(element)) {
|
3952
3952
|
return element;
|
@@ -3958,7 +3958,7 @@ wysihtml5.browser = (function() {
|
|
3958
3958
|
|
3959
3959
|
return _parseNode(element);
|
3960
3960
|
}
|
3961
|
-
|
3961
|
+
|
3962
3962
|
/**
|
3963
3963
|
* This is basically a rebuild of
|
3964
3964
|
* the rails auto_link_urls text helper
|
@@ -3982,11 +3982,11 @@ wysihtml5.browser = (function() {
|
|
3982
3982
|
if (realUrl.substr(0, 4) === "www.") {
|
3983
3983
|
realUrl = "http://" + realUrl;
|
3984
3984
|
}
|
3985
|
-
|
3985
|
+
|
3986
3986
|
return '<a href="' + realUrl + '">' + displayUrl + '</a>' + punctuation;
|
3987
3987
|
});
|
3988
3988
|
}
|
3989
|
-
|
3989
|
+
|
3990
3990
|
/**
|
3991
3991
|
* Creates or (if already cached) returns a temp element
|
3992
3992
|
* for the given document object
|
@@ -3998,26 +3998,26 @@ wysihtml5.browser = (function() {
|
|
3998
3998
|
}
|
3999
3999
|
return tempElement;
|
4000
4000
|
}
|
4001
|
-
|
4001
|
+
|
4002
4002
|
/**
|
4003
4003
|
* Replaces the original text nodes with the newly auto-linked dom tree
|
4004
4004
|
*/
|
4005
4005
|
function _wrapMatchesInNode(textNode) {
|
4006
4006
|
var parentNode = textNode.parentNode,
|
4007
4007
|
tempElement = _getTempElement(parentNode.ownerDocument);
|
4008
|
-
|
4008
|
+
|
4009
4009
|
// We need to insert an empty/temporary <span /> to fix IE quirks
|
4010
4010
|
// Elsewise IE would strip white space in the beginning
|
4011
4011
|
tempElement.innerHTML = "<span></span>" + _convertUrlsToLinks(textNode.data);
|
4012
4012
|
tempElement.removeChild(tempElement.firstChild);
|
4013
|
-
|
4013
|
+
|
4014
4014
|
while (tempElement.firstChild) {
|
4015
4015
|
// inserts tempElement.firstChild before textNode
|
4016
4016
|
parentNode.insertBefore(tempElement.firstChild, textNode);
|
4017
4017
|
}
|
4018
4018
|
parentNode.removeChild(textNode);
|
4019
4019
|
}
|
4020
|
-
|
4020
|
+
|
4021
4021
|
function _hasParentThatShouldBeIgnored(node) {
|
4022
4022
|
var nodeName;
|
4023
4023
|
while (node.parentNode) {
|
@@ -4031,36 +4031,36 @@ wysihtml5.browser = (function() {
|
|
4031
4031
|
}
|
4032
4032
|
return false;
|
4033
4033
|
}
|
4034
|
-
|
4034
|
+
|
4035
4035
|
function _parseNode(element) {
|
4036
4036
|
if (IGNORE_URLS_IN.contains(element.nodeName)) {
|
4037
4037
|
return;
|
4038
4038
|
}
|
4039
|
-
|
4039
|
+
|
4040
4040
|
if (element.nodeType === wysihtml5.TEXT_NODE && element.data.match(URL_REG_EXP)) {
|
4041
4041
|
_wrapMatchesInNode(element);
|
4042
4042
|
return;
|
4043
4043
|
}
|
4044
|
-
|
4044
|
+
|
4045
4045
|
var childNodes = wysihtml5.lang.array(element.childNodes).get(),
|
4046
4046
|
childNodesLength = childNodes.length,
|
4047
4047
|
i = 0;
|
4048
|
-
|
4048
|
+
|
4049
4049
|
for (; i<childNodesLength; i++) {
|
4050
4050
|
_parseNode(childNodes[i]);
|
4051
4051
|
}
|
4052
|
-
|
4052
|
+
|
4053
4053
|
return element;
|
4054
4054
|
}
|
4055
|
-
|
4055
|
+
|
4056
4056
|
wysihtml5.dom.autoLink = autoLink;
|
4057
|
-
|
4057
|
+
|
4058
4058
|
// Reveal url reg exp to the outside
|
4059
4059
|
wysihtml5.dom.autoLink.URL_REG_EXP = URL_REG_EXP;
|
4060
4060
|
})(wysihtml5);(function(wysihtml5) {
|
4061
4061
|
var supportsClassList = wysihtml5.browser.supportsClassList(),
|
4062
4062
|
api = wysihtml5.dom;
|
4063
|
-
|
4063
|
+
|
4064
4064
|
api.addClass = function(element, className) {
|
4065
4065
|
if (supportsClassList) {
|
4066
4066
|
return element.classList.add(className);
|
@@ -4070,20 +4070,20 @@ wysihtml5.browser = (function() {
|
|
4070
4070
|
}
|
4071
4071
|
element.className += " " + className;
|
4072
4072
|
};
|
4073
|
-
|
4073
|
+
|
4074
4074
|
api.removeClass = function(element, className) {
|
4075
4075
|
if (supportsClassList) {
|
4076
4076
|
return element.classList.remove(className);
|
4077
4077
|
}
|
4078
|
-
|
4078
|
+
|
4079
4079
|
element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ");
|
4080
4080
|
};
|
4081
|
-
|
4081
|
+
|
4082
4082
|
api.hasClass = function(element, className) {
|
4083
4083
|
if (supportsClassList) {
|
4084
4084
|
return element.classList.contains(className);
|
4085
4085
|
}
|
4086
|
-
|
4086
|
+
|
4087
4087
|
var elementClassName = element.className;
|
4088
4088
|
return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
|
4089
4089
|
};
|
@@ -4135,17 +4135,17 @@ wysihtml5.dom.convertToList = (function() {
|
|
4135
4135
|
list.appendChild(listItem);
|
4136
4136
|
return listItem;
|
4137
4137
|
}
|
4138
|
-
|
4138
|
+
|
4139
4139
|
function _createList(doc, type) {
|
4140
4140
|
return doc.createElement(type);
|
4141
4141
|
}
|
4142
|
-
|
4142
|
+
|
4143
4143
|
function convertToList(element, listType) {
|
4144
4144
|
if (element.nodeName === "UL" || element.nodeName === "OL" || element.nodeName === "MENU") {
|
4145
4145
|
// Already a list
|
4146
4146
|
return element;
|
4147
4147
|
}
|
4148
|
-
|
4148
|
+
|
4149
4149
|
var doc = element.ownerDocument,
|
4150
4150
|
list = _createList(doc, listType),
|
4151
4151
|
lineBreaks = element.querySelectorAll("br"),
|
@@ -4159,7 +4159,7 @@ wysihtml5.dom.convertToList = (function() {
|
|
4159
4159
|
isLineBreak,
|
4160
4160
|
currentListItem,
|
4161
4161
|
i;
|
4162
|
-
|
4162
|
+
|
4163
4163
|
// First find <br> at the end of inline elements and move them behind them
|
4164
4164
|
for (i=0; i<lineBreaksLength; i++) {
|
4165
4165
|
lineBreak = lineBreaks[i];
|
@@ -4171,16 +4171,16 @@ wysihtml5.dom.convertToList = (function() {
|
|
4171
4171
|
wysihtml5.dom.insert(lineBreak).after(lineBreak.parentNode);
|
4172
4172
|
}
|
4173
4173
|
}
|
4174
|
-
|
4174
|
+
|
4175
4175
|
childNodes = wysihtml5.lang.array(element.childNodes).get();
|
4176
4176
|
childNodesLength = childNodes.length;
|
4177
|
-
|
4177
|
+
|
4178
4178
|
for (i=0; i<childNodesLength; i++) {
|
4179
4179
|
currentListItem = currentListItem || _createListItem(doc, list);
|
4180
4180
|
childNode = childNodes[i];
|
4181
4181
|
isBlockElement = wysihtml5.dom.getStyle("display").from(childNode) === "block";
|
4182
4182
|
isLineBreak = childNode.nodeName === "BR";
|
4183
|
-
|
4183
|
+
|
4184
4184
|
if (isBlockElement) {
|
4185
4185
|
// Append blockElement to current <li> if empty, otherwise create a new one
|
4186
4186
|
currentListItem = currentListItem.firstChild ? _createListItem(doc, list) : currentListItem;
|
@@ -4188,27 +4188,27 @@ wysihtml5.dom.convertToList = (function() {
|
|
4188
4188
|
currentListItem = null;
|
4189
4189
|
continue;
|
4190
4190
|
}
|
4191
|
-
|
4191
|
+
|
4192
4192
|
if (isLineBreak) {
|
4193
4193
|
// Only create a new list item in the next iteration when the current one has already content
|
4194
4194
|
currentListItem = currentListItem.firstChild ? null : currentListItem;
|
4195
4195
|
continue;
|
4196
4196
|
}
|
4197
|
-
|
4197
|
+
|
4198
4198
|
currentListItem.appendChild(childNode);
|
4199
4199
|
}
|
4200
|
-
|
4200
|
+
|
4201
4201
|
element.parentNode.replaceChild(list, element);
|
4202
4202
|
return list;
|
4203
4203
|
}
|
4204
|
-
|
4204
|
+
|
4205
4205
|
return convertToList;
|
4206
4206
|
})();/**
|
4207
4207
|
* Copy a set of attributes from one element to another
|
4208
4208
|
*
|
4209
4209
|
* @param {Array} attributesToCopy List of attributes which should be copied
|
4210
4210
|
* @return {Object} Returns an object which offers the "from" method which can be invoked with the element where to
|
4211
|
-
* copy the attributes from., this again returns an object which provides a method named "to" which can be invoked
|
4211
|
+
* copy the attributes from., this again returns an object which provides a method named "to" which can be invoked
|
4212
4212
|
* with the element where to copy the attributes to (see example)
|
4213
4213
|
*
|
4214
4214
|
* @example
|
@@ -4246,7 +4246,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4246
4246
|
*
|
4247
4247
|
* @param {Array} stylesToCopy List of styles which should be copied
|
4248
4248
|
* @return {Object} Returns an object which offers the "from" method which can be invoked with the element where to
|
4249
|
-
* copy the styles from., this again returns an object which provides a method named "to" which can be invoked
|
4249
|
+
* copy the styles from., this again returns an object which provides a method named "to" which can be invoked
|
4250
4250
|
* with the element where to copy the styles to (see example)
|
4251
4251
|
*
|
4252
4252
|
* @example
|
@@ -4257,21 +4257,21 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4257
4257
|
*
|
4258
4258
|
*/
|
4259
4259
|
(function(dom) {
|
4260
|
-
|
4260
|
+
|
4261
4261
|
/**
|
4262
4262
|
* Mozilla, WebKit and Opera recalculate the computed width when box-sizing: boder-box; is set
|
4263
|
-
* So if an element has "width: 200px; -moz-box-sizing: border-box; border: 1px;" then
|
4263
|
+
* So if an element has "width: 200px; -moz-box-sizing: border-box; border: 1px;" then
|
4264
4264
|
* its computed css width will be 198px
|
4265
4265
|
*/
|
4266
4266
|
var BOX_SIZING_PROPERTIES = ["-webkit-box-sizing", "-moz-box-sizing", "-ms-box-sizing", "box-sizing"];
|
4267
|
-
|
4267
|
+
|
4268
4268
|
var shouldIgnoreBoxSizingBorderBox = function(element) {
|
4269
4269
|
if (hasBoxSizingBorderBox(element)) {
|
4270
4270
|
return parseInt(dom.getStyle("width").from(element), 10) < element.offsetWidth;
|
4271
4271
|
}
|
4272
4272
|
return false;
|
4273
4273
|
};
|
4274
|
-
|
4274
|
+
|
4275
4275
|
var hasBoxSizingBorderBox = function(element) {
|
4276
4276
|
var i = 0,
|
4277
4277
|
length = BOX_SIZING_PROPERTIES.length;
|
@@ -4281,14 +4281,14 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4281
4281
|
}
|
4282
4282
|
}
|
4283
4283
|
};
|
4284
|
-
|
4284
|
+
|
4285
4285
|
dom.copyStyles = function(stylesToCopy) {
|
4286
4286
|
return {
|
4287
4287
|
from: function(element) {
|
4288
4288
|
if (shouldIgnoreBoxSizingBorderBox(element)) {
|
4289
4289
|
stylesToCopy = wysihtml5.lang.array(stylesToCopy).without(BOX_SIZING_PROPERTIES);
|
4290
4290
|
}
|
4291
|
-
|
4291
|
+
|
4292
4292
|
var cssText = "",
|
4293
4293
|
length = stylesToCopy.length,
|
4294
4294
|
i = 0,
|
@@ -4297,7 +4297,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4297
4297
|
property = stylesToCopy[i];
|
4298
4298
|
cssText += property + ":" + dom.getStyle(property).from(element) + ";";
|
4299
4299
|
}
|
4300
|
-
|
4300
|
+
|
4301
4301
|
return {
|
4302
4302
|
to: function(element) {
|
4303
4303
|
dom.setStyles(cssText).on(element);
|
@@ -4316,12 +4316,12 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4316
4316
|
* });
|
4317
4317
|
*/
|
4318
4318
|
(function(wysihtml5) {
|
4319
|
-
|
4319
|
+
|
4320
4320
|
wysihtml5.dom.delegate = function(container, selector, eventName, handler) {
|
4321
4321
|
return wysihtml5.dom.observe(container, eventName, function(event) {
|
4322
4322
|
var target = event.target,
|
4323
4323
|
match = wysihtml5.lang.array(container.querySelectorAll(selector));
|
4324
|
-
|
4324
|
+
|
4325
4325
|
while (target && target !== container) {
|
4326
4326
|
if (match.contains(target)) {
|
4327
4327
|
handler.call(target, event);
|
@@ -4331,13 +4331,13 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4331
4331
|
}
|
4332
4332
|
});
|
4333
4333
|
};
|
4334
|
-
|
4334
|
+
|
4335
4335
|
})(wysihtml5);/**
|
4336
4336
|
* Returns the given html wrapped in a div element
|
4337
4337
|
*
|
4338
4338
|
* Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly
|
4339
4339
|
* when inserted via innerHTML
|
4340
|
-
*
|
4340
|
+
*
|
4341
4341
|
* @param {String} html The html which should be wrapped in a dom element
|
4342
4342
|
* @param {Obejct} [context] Document object of the context the html belongs to
|
4343
4343
|
*
|
@@ -4345,7 +4345,7 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
4345
4345
|
* wysihtml5.dom.getAsDom("<article>foo</article>");
|
4346
4346
|
*/
|
4347
4347
|
wysihtml5.dom.getAsDom = (function() {
|
4348
|
-
|
4348
|
+
|
4349
4349
|
var _innerHTMLShiv = function(html, context) {
|
4350
4350
|
var tempElement = context.createElement("div");
|
4351
4351
|
tempElement.style.display = "none";
|
@@ -4355,7 +4355,7 @@ wysihtml5.dom.getAsDom = (function() {
|
|
4355
4355
|
context.body.removeChild(tempElement);
|
4356
4356
|
return tempElement;
|
4357
4357
|
};
|
4358
|
-
|
4358
|
+
|
4359
4359
|
/**
|
4360
4360
|
* Make sure IE supports HTML5 tags, which is accomplished by simply creating one instance of each element
|
4361
4361
|
*/
|
@@ -4368,8 +4368,8 @@ wysihtml5.dom.getAsDom = (function() {
|
|
4368
4368
|
}
|
4369
4369
|
context._wysihtml5_supportsHTML5Tags = true;
|
4370
4370
|
};
|
4371
|
-
|
4372
|
-
|
4371
|
+
|
4372
|
+
|
4373
4373
|
/**
|
4374
4374
|
* List of html5 tags
|
4375
4375
|
* taken from http://simon.html5.org/html5-elements
|
@@ -4379,7 +4379,7 @@ wysihtml5.dom.getAsDom = (function() {
|
|
4379
4379
|
"figure", "footer", "header", "hgroup", "keygen", "mark", "meter", "nav", "output", "progress",
|
4380
4380
|
"rp", "rt", "ruby", "svg", "section", "source", "summary", "time", "track", "video", "wbr"
|
4381
4381
|
];
|
4382
|
-
|
4382
|
+
|
4383
4383
|
return function(html, context) {
|
4384
4384
|
context = context || document;
|
4385
4385
|
var tempElement;
|
@@ -4411,23 +4411,23 @@ wysihtml5.dom.getAsDom = (function() {
|
|
4411
4411
|
* var coloredElement = wysihtml5.dom.getParentElement(myTextNode, { nodeName: "SPAN", className: "wysiwyg-color-red", classRegExp: /wysiwyg-color-[a-z]/g });
|
4412
4412
|
*/
|
4413
4413
|
wysihtml5.dom.getParentElement = (function() {
|
4414
|
-
|
4414
|
+
|
4415
4415
|
function _isSameNodeName(nodeName, desiredNodeNames) {
|
4416
4416
|
if (!desiredNodeNames || !desiredNodeNames.length) {
|
4417
4417
|
return true;
|
4418
4418
|
}
|
4419
|
-
|
4419
|
+
|
4420
4420
|
if (typeof(desiredNodeNames) === "string") {
|
4421
4421
|
return nodeName === desiredNodeNames;
|
4422
4422
|
} else {
|
4423
4423
|
return wysihtml5.lang.array(desiredNodeNames).contains(nodeName);
|
4424
4424
|
}
|
4425
4425
|
}
|
4426
|
-
|
4426
|
+
|
4427
4427
|
function _isElement(node) {
|
4428
4428
|
return node.nodeType === wysihtml5.ELEMENT_NODE;
|
4429
4429
|
}
|
4430
|
-
|
4430
|
+
|
4431
4431
|
function _hasClassName(element, className, classRegExp) {
|
4432
4432
|
var classNames = (element.className || "").match(classRegExp) || [];
|
4433
4433
|
if (!className) {
|
@@ -4435,7 +4435,7 @@ wysihtml5.dom.getParentElement = (function() {
|
|
4435
4435
|
}
|
4436
4436
|
return classNames[classNames.length - 1] === className;
|
4437
4437
|
}
|
4438
|
-
|
4438
|
+
|
4439
4439
|
function _getParentElementWithNodeName(node, nodeName, levels) {
|
4440
4440
|
while (levels-- && node && node.nodeName !== "BODY") {
|
4441
4441
|
if (_isSameNodeName(node.nodeName, nodeName)) {
|
@@ -4445,7 +4445,7 @@ wysihtml5.dom.getParentElement = (function() {
|
|
4445
4445
|
}
|
4446
4446
|
return null;
|
4447
4447
|
}
|
4448
|
-
|
4448
|
+
|
4449
4449
|
function _getParentElementWithNodeNameAndClassName(node, nodeName, className, classRegExp, levels) {
|
4450
4450
|
while (levels-- && node && node.nodeName !== "BODY") {
|
4451
4451
|
if (_isElement(node) &&
|
@@ -4457,7 +4457,7 @@ wysihtml5.dom.getParentElement = (function() {
|
|
4457
4457
|
}
|
4458
4458
|
return null;
|
4459
4459
|
}
|
4460
|
-
|
4460
|
+
|
4461
4461
|
return function(node, matchingSet, levels) {
|
4462
4462
|
levels = levels || 50; // Go max 50 nodes upwards from current node
|
4463
4463
|
if (matchingSet.className || matchingSet.classRegExp) {
|
@@ -4486,20 +4486,20 @@ wysihtml5.dom.getStyle = (function() {
|
|
4486
4486
|
"float": ("styleFloat" in document.createElement("div").style) ? "styleFloat" : "cssFloat"
|
4487
4487
|
},
|
4488
4488
|
REG_EXP_CAMELIZE = /\-[a-z]/g;
|
4489
|
-
|
4489
|
+
|
4490
4490
|
function camelize(str) {
|
4491
4491
|
return str.replace(REG_EXP_CAMELIZE, function(match) {
|
4492
4492
|
return match.charAt(1).toUpperCase();
|
4493
4493
|
});
|
4494
4494
|
}
|
4495
|
-
|
4495
|
+
|
4496
4496
|
return function(property) {
|
4497
4497
|
return {
|
4498
4498
|
from: function(element) {
|
4499
4499
|
if (element.nodeType !== wysihtml5.ELEMENT_NODE) {
|
4500
4500
|
return;
|
4501
4501
|
}
|
4502
|
-
|
4502
|
+
|
4503
4503
|
var doc = element.ownerDocument,
|
4504
4504
|
camelizedProperty = stylePropertyMapping[property] || camelize(property),
|
4505
4505
|
style = element.style,
|
@@ -4508,7 +4508,7 @@ wysihtml5.dom.getStyle = (function() {
|
|
4508
4508
|
if (styleValue) {
|
4509
4509
|
return styleValue;
|
4510
4510
|
}
|
4511
|
-
|
4511
|
+
|
4512
4512
|
// currentStyle is no standard and only supported by Opera and IE but it has one important advantage over the standard-compliant
|
4513
4513
|
// window.getComputedStyle, since it returns css property values in their original unit:
|
4514
4514
|
// If you set an elements width to "50%", window.getComputedStyle will give you it's current width in px while currentStyle
|
@@ -4556,18 +4556,18 @@ wysihtml5.dom.getStyle = (function() {
|
|
4556
4556
|
wysihtml5.dom.hasElementWithTagName = (function() {
|
4557
4557
|
var LIVE_CACHE = {},
|
4558
4558
|
DOCUMENT_IDENTIFIER = 1;
|
4559
|
-
|
4559
|
+
|
4560
4560
|
function _getDocumentIdentifier(doc) {
|
4561
4561
|
return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);
|
4562
4562
|
}
|
4563
|
-
|
4563
|
+
|
4564
4564
|
return function(doc, tagName) {
|
4565
4565
|
var key = _getDocumentIdentifier(doc) + ":" + tagName,
|
4566
4566
|
cacheEntry = LIVE_CACHE[key];
|
4567
4567
|
if (!cacheEntry) {
|
4568
4568
|
cacheEntry = LIVE_CACHE[key] = doc.getElementsByTagName(tagName);
|
4569
4569
|
}
|
4570
|
-
|
4570
|
+
|
4571
4571
|
return cacheEntry.length > 0;
|
4572
4572
|
};
|
4573
4573
|
})();/**
|
@@ -4587,7 +4587,7 @@ wysihtml5.dom.hasElementWithTagName = (function() {
|
|
4587
4587
|
function _getDocumentIdentifier(doc) {
|
4588
4588
|
return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);
|
4589
4589
|
}
|
4590
|
-
|
4590
|
+
|
4591
4591
|
wysihtml5.dom.hasElementWithClassName = function(doc, className) {
|
4592
4592
|
// getElementsByClassName is not supported by IE<9
|
4593
4593
|
// but is sometimes mocked via library code (which then doesn't return live node lists)
|
@@ -4609,18 +4609,18 @@ wysihtml5.dom.insert = function(elementToInsert) {
|
|
4609
4609
|
after: function(element) {
|
4610
4610
|
element.parentNode.insertBefore(elementToInsert, element.nextSibling);
|
4611
4611
|
},
|
4612
|
-
|
4612
|
+
|
4613
4613
|
before: function(element) {
|
4614
4614
|
element.parentNode.insertBefore(elementToInsert, element);
|
4615
4615
|
},
|
4616
|
-
|
4616
|
+
|
4617
4617
|
into: function(element) {
|
4618
4618
|
element.appendChild(elementToInsert);
|
4619
4619
|
}
|
4620
4620
|
};
|
4621
4621
|
};wysihtml5.dom.insertCSS = function(rules) {
|
4622
4622
|
rules = rules.join("\n");
|
4623
|
-
|
4623
|
+
|
4624
4624
|
return {
|
4625
4625
|
into: function(doc) {
|
4626
4626
|
var head = doc.head || doc.getElementsByTagName("head")[0],
|
@@ -4647,12 +4647,12 @@ wysihtml5.dom.insert = function(elementToInsert) {
|
|
4647
4647
|
*/
|
4648
4648
|
wysihtml5.dom.observe = function(element, eventNames, handler) {
|
4649
4649
|
eventNames = typeof(eventNames) === "string" ? [eventNames] : eventNames;
|
4650
|
-
|
4650
|
+
|
4651
4651
|
var handlerWrapper,
|
4652
4652
|
eventName,
|
4653
4653
|
i = 0,
|
4654
4654
|
length = eventNames.length;
|
4655
|
-
|
4655
|
+
|
4656
4656
|
for (; i<length; i++) {
|
4657
4657
|
eventName = eventNames[i];
|
4658
4658
|
if (element.addEventListener) {
|
@@ -4673,7 +4673,7 @@ wysihtml5.dom.observe = function(element, eventNames, handler) {
|
|
4673
4673
|
element.attachEvent("on" + eventName, handlerWrapper);
|
4674
4674
|
}
|
4675
4675
|
}
|
4676
|
-
|
4676
|
+
|
4677
4677
|
return {
|
4678
4678
|
stop: function() {
|
4679
4679
|
var eventName,
|
@@ -4742,7 +4742,7 @@ wysihtml5.dom.observe = function(element, eventNames, handler) {
|
|
4742
4742
|
* // => '<p class="red">foo</p><p>bar</p>'
|
4743
4743
|
*/
|
4744
4744
|
wysihtml5.dom.parse = (function() {
|
4745
|
-
|
4745
|
+
|
4746
4746
|
/**
|
4747
4747
|
* It's not possible to use a XMLParser/DOMParser as HTML5 is not always well-formed XML
|
4748
4748
|
* new DOMParser().parseFromString('<img src="foo.gif">') will cause a parseError since the
|
@@ -4759,27 +4759,27 @@ wysihtml5.dom.parse = (function() {
|
|
4759
4759
|
WHITE_SPACE_REG_EXP = /\s+/,
|
4760
4760
|
defaultRules = { tags: {}, classes: {} },
|
4761
4761
|
currentRules = {};
|
4762
|
-
|
4762
|
+
|
4763
4763
|
/**
|
4764
4764
|
* Iterates over all childs of the element, recreates them, appends them into a document fragment
|
4765
4765
|
* which later replaces the entire body content
|
4766
4766
|
*/
|
4767
4767
|
function parse(elementOrHtml, rules, context, cleanUp) {
|
4768
4768
|
wysihtml5.lang.object(currentRules).merge(defaultRules).merge(rules).get();
|
4769
|
-
|
4769
|
+
|
4770
4770
|
context = context || elementOrHtml.ownerDocument || document;
|
4771
4771
|
var fragment = context.createDocumentFragment(),
|
4772
4772
|
isString = typeof(elementOrHtml) === "string",
|
4773
4773
|
element,
|
4774
4774
|
newNode,
|
4775
4775
|
firstChild;
|
4776
|
-
|
4776
|
+
|
4777
4777
|
if (isString) {
|
4778
4778
|
element = wysihtml5.dom.getAsDom(elementOrHtml, context);
|
4779
4779
|
} else {
|
4780
4780
|
element = elementOrHtml;
|
4781
4781
|
}
|
4782
|
-
|
4782
|
+
|
4783
4783
|
while (element.firstChild) {
|
4784
4784
|
firstChild = element.firstChild;
|
4785
4785
|
element.removeChild(firstChild);
|
@@ -4788,16 +4788,16 @@ wysihtml5.dom.parse = (function() {
|
|
4788
4788
|
fragment.appendChild(newNode);
|
4789
4789
|
}
|
4790
4790
|
}
|
4791
|
-
|
4791
|
+
|
4792
4792
|
// Clear element contents
|
4793
4793
|
element.innerHTML = "";
|
4794
|
-
|
4794
|
+
|
4795
4795
|
// Insert new DOM tree
|
4796
4796
|
element.appendChild(fragment);
|
4797
|
-
|
4797
|
+
|
4798
4798
|
return isString ? wysihtml5.quirks.getCorrectInnerHTML(element) : element;
|
4799
4799
|
}
|
4800
|
-
|
4800
|
+
|
4801
4801
|
function _convert(oldNode, cleanUp) {
|
4802
4802
|
var oldNodeType = oldNode.nodeType,
|
4803
4803
|
oldChilds = oldNode.childNodes,
|
@@ -4805,20 +4805,20 @@ wysihtml5.dom.parse = (function() {
|
|
4805
4805
|
newNode,
|
4806
4806
|
method = NODE_TYPE_MAPPING[oldNodeType],
|
4807
4807
|
i = 0;
|
4808
|
-
|
4808
|
+
|
4809
4809
|
newNode = method && method(oldNode);
|
4810
|
-
|
4810
|
+
|
4811
4811
|
if (!newNode) {
|
4812
4812
|
return null;
|
4813
4813
|
}
|
4814
|
-
|
4814
|
+
|
4815
4815
|
for (i=0; i<oldChildsLength; i++) {
|
4816
4816
|
newChild = _convert(oldChilds[i], cleanUp);
|
4817
4817
|
if (newChild) {
|
4818
4818
|
newNode.appendChild(newChild);
|
4819
4819
|
}
|
4820
4820
|
}
|
4821
|
-
|
4821
|
+
|
4822
4822
|
// Cleanup senseless <span> elements
|
4823
4823
|
if (cleanUp &&
|
4824
4824
|
newNode.childNodes.length <= 1 &&
|
@@ -4826,10 +4826,10 @@ wysihtml5.dom.parse = (function() {
|
|
4826
4826
|
!newNode.attributes.length) {
|
4827
4827
|
return newNode.firstChild;
|
4828
4828
|
}
|
4829
|
-
|
4829
|
+
|
4830
4830
|
return newNode;
|
4831
4831
|
}
|
4832
|
-
|
4832
|
+
|
4833
4833
|
function _handleElement(oldNode) {
|
4834
4834
|
var rule,
|
4835
4835
|
newNode,
|
@@ -4837,7 +4837,7 @@ wysihtml5.dom.parse = (function() {
|
|
4837
4837
|
tagRules = currentRules.tags,
|
4838
4838
|
nodeName = oldNode.nodeName.toLowerCase(),
|
4839
4839
|
scopeName = oldNode.scopeName;
|
4840
|
-
|
4840
|
+
|
4841
4841
|
/**
|
4842
4842
|
* We already parsed that element
|
4843
4843
|
* ignore it! (yes, this sometimes happens in IE8 when the html is invalid)
|
@@ -4846,11 +4846,11 @@ wysihtml5.dom.parse = (function() {
|
|
4846
4846
|
return null;
|
4847
4847
|
}
|
4848
4848
|
oldNode._wysihtml5 = 1;
|
4849
|
-
|
4849
|
+
|
4850
4850
|
if (oldNode.className === "wysihtml5-temp") {
|
4851
4851
|
return null;
|
4852
4852
|
}
|
4853
|
-
|
4853
|
+
|
4854
4854
|
/**
|
4855
4855
|
* IE is the only browser who doesn't include the namespace in the
|
4856
4856
|
* nodeName, that's why we have to prepend it by ourselves
|
@@ -4860,7 +4860,7 @@ wysihtml5.dom.parse = (function() {
|
|
4860
4860
|
if (scopeName && scopeName != "HTML") {
|
4861
4861
|
nodeName = scopeName + ":" + nodeName;
|
4862
4862
|
}
|
4863
|
-
|
4863
|
+
|
4864
4864
|
/**
|
4865
4865
|
* Repair node
|
4866
4866
|
* IE is a bit bitchy when it comes to invalid nested markup which includes unclosed tags
|
@@ -4873,13 +4873,13 @@ wysihtml5.dom.parse = (function() {
|
|
4873
4873
|
nodeName = "div";
|
4874
4874
|
}
|
4875
4875
|
}
|
4876
|
-
|
4876
|
+
|
4877
4877
|
if (nodeName in tagRules) {
|
4878
4878
|
rule = tagRules[nodeName];
|
4879
4879
|
if (!rule || rule.remove) {
|
4880
4880
|
return null;
|
4881
4881
|
}
|
4882
|
-
|
4882
|
+
|
4883
4883
|
rule = typeof(rule) === "string" ? { rename_tag: rule } : rule;
|
4884
4884
|
} else if (oldNode.firstChild) {
|
4885
4885
|
rule = { rename_tag: DEFAULT_NODE_NAME };
|
@@ -4887,14 +4887,14 @@ wysihtml5.dom.parse = (function() {
|
|
4887
4887
|
// Remove empty unknown elements
|
4888
4888
|
return null;
|
4889
4889
|
}
|
4890
|
-
|
4890
|
+
|
4891
4891
|
newNode = oldNode.ownerDocument.createElement(rule.rename_tag || nodeName);
|
4892
4892
|
_handleAttributes(oldNode, newNode, rule);
|
4893
|
-
|
4893
|
+
|
4894
4894
|
oldNode = null;
|
4895
4895
|
return newNode;
|
4896
4896
|
}
|
4897
|
-
|
4897
|
+
|
4898
4898
|
function _handleAttributes(oldNode, newNode, rule) {
|
4899
4899
|
var attributes = {}, // fresh new set of attributes to set on newNode
|
4900
4900
|
setClass = rule.set_class, // classes to set
|
@@ -4914,11 +4914,11 @@ wysihtml5.dom.parse = (function() {
|
|
4914
4914
|
attributeName,
|
4915
4915
|
newAttributeValue,
|
4916
4916
|
method;
|
4917
|
-
|
4917
|
+
|
4918
4918
|
if (setAttributes) {
|
4919
4919
|
attributes = wysihtml5.lang.object(setAttributes).clone();
|
4920
4920
|
}
|
4921
|
-
|
4921
|
+
|
4922
4922
|
if (checkAttributes) {
|
4923
4923
|
for (attributeName in checkAttributes) {
|
4924
4924
|
method = attributeCheckMethods[checkAttributes[attributeName]];
|
@@ -4931,11 +4931,11 @@ wysihtml5.dom.parse = (function() {
|
|
4931
4931
|
}
|
4932
4932
|
}
|
4933
4933
|
}
|
4934
|
-
|
4934
|
+
|
4935
4935
|
if (setClass) {
|
4936
4936
|
classes.push(setClass);
|
4937
4937
|
}
|
4938
|
-
|
4938
|
+
|
4939
4939
|
if (addClass) {
|
4940
4940
|
for (attributeName in addClass) {
|
4941
4941
|
method = addClassMethods[addClass[attributeName]];
|
@@ -4948,10 +4948,10 @@ wysihtml5.dom.parse = (function() {
|
|
4948
4948
|
}
|
4949
4949
|
}
|
4950
4950
|
}
|
4951
|
-
|
4951
|
+
|
4952
4952
|
// make sure that wysihtml5 temp class doesn't get stripped out
|
4953
4953
|
allowedClasses["_wysihtml5-temp-placeholder"] = 1;
|
4954
|
-
|
4954
|
+
|
4955
4955
|
// add old classes last
|
4956
4956
|
oldClasses = oldNode.getAttribute("class");
|
4957
4957
|
if (oldClasses) {
|
@@ -4964,7 +4964,7 @@ wysihtml5.dom.parse = (function() {
|
|
4964
4964
|
newClasses.push(currentClass);
|
4965
4965
|
}
|
4966
4966
|
}
|
4967
|
-
|
4967
|
+
|
4968
4968
|
// remove duplicate entries and preserve class specificity
|
4969
4969
|
newClassesLength = newClasses.length;
|
4970
4970
|
while (newClassesLength--) {
|
@@ -4973,11 +4973,11 @@ wysihtml5.dom.parse = (function() {
|
|
4973
4973
|
newUniqueClasses.unshift(currentClass);
|
4974
4974
|
}
|
4975
4975
|
}
|
4976
|
-
|
4976
|
+
|
4977
4977
|
if (newUniqueClasses.length) {
|
4978
4978
|
attributes["class"] = newUniqueClasses.join(" ");
|
4979
4979
|
}
|
4980
|
-
|
4980
|
+
|
4981
4981
|
// set attributes on newNode
|
4982
4982
|
for (attributeName in attributes) {
|
4983
4983
|
// Setting attributes can cause a js error in IE under certain circumstances
|
@@ -4987,7 +4987,7 @@ wysihtml5.dom.parse = (function() {
|
|
4987
4987
|
newNode.setAttribute(attributeName, attributes[attributeName]);
|
4988
4988
|
} catch(e) {}
|
4989
4989
|
}
|
4990
|
-
|
4990
|
+
|
4991
4991
|
// IE8 sometimes loses the width/height attributes when those are set before the "src"
|
4992
4992
|
// so we make sure to set them again
|
4993
4993
|
if (attributes.src) {
|
@@ -4999,7 +4999,7 @@ wysihtml5.dom.parse = (function() {
|
|
4999
4999
|
}
|
5000
5000
|
}
|
5001
5001
|
}
|
5002
|
-
|
5002
|
+
|
5003
5003
|
/**
|
5004
5004
|
* IE gives wrong results for hasAttribute/getAttribute, for example:
|
5005
5005
|
* var td = document.createElement("td");
|
@@ -5022,13 +5022,13 @@ wysihtml5.dom.parse = (function() {
|
|
5022
5022
|
var outerHTML = node.outerHTML.toLowerCase(),
|
5023
5023
|
// TODO: This might not work for attributes without value: <input disabled>
|
5024
5024
|
hasAttribute = outerHTML.indexOf(" " + attributeName + "=") != -1;
|
5025
|
-
|
5025
|
+
|
5026
5026
|
return hasAttribute ? node.getAttribute(attributeName) : null;
|
5027
5027
|
} else{
|
5028
5028
|
return node.getAttribute(attributeName);
|
5029
5029
|
}
|
5030
5030
|
}
|
5031
|
-
|
5031
|
+
|
5032
5032
|
/**
|
5033
5033
|
* Check whether the given node is a proper loaded image
|
5034
5034
|
* FIXME: Returns undefined when unknown (Chrome, Safari)
|
@@ -5042,12 +5042,12 @@ wysihtml5.dom.parse = (function() {
|
|
5042
5042
|
}
|
5043
5043
|
}
|
5044
5044
|
}
|
5045
|
-
|
5045
|
+
|
5046
5046
|
function _handleText(oldNode) {
|
5047
5047
|
return oldNode.ownerDocument.createTextNode(oldNode.data);
|
5048
5048
|
}
|
5049
|
-
|
5050
|
-
|
5049
|
+
|
5050
|
+
|
5051
5051
|
// ------------ attribute checks ------------ \\
|
5052
5052
|
var attributeCheckMethods = {
|
5053
5053
|
url: (function() {
|
@@ -5061,7 +5061,7 @@ wysihtml5.dom.parse = (function() {
|
|
5061
5061
|
});
|
5062
5062
|
};
|
5063
5063
|
})(),
|
5064
|
-
|
5064
|
+
|
5065
5065
|
alt: (function() {
|
5066
5066
|
var REG_EXP = /[^ a-z0-9_\-]/gi;
|
5067
5067
|
return function(attributeValue) {
|
@@ -5071,7 +5071,7 @@ wysihtml5.dom.parse = (function() {
|
|
5071
5071
|
return attributeValue.replace(REG_EXP, "");
|
5072
5072
|
};
|
5073
5073
|
})(),
|
5074
|
-
|
5074
|
+
|
5075
5075
|
numbers: (function() {
|
5076
5076
|
var REG_EXP = /\D/g;
|
5077
5077
|
return function(attributeValue) {
|
@@ -5080,7 +5080,7 @@ wysihtml5.dom.parse = (function() {
|
|
5080
5080
|
};
|
5081
5081
|
})()
|
5082
5082
|
};
|
5083
|
-
|
5083
|
+
|
5084
5084
|
// ------------ class converter (converts an html attribute to a class name) ------------ \\
|
5085
5085
|
var addClassMethods = {
|
5086
5086
|
align_img: (function() {
|
@@ -5092,7 +5092,7 @@ wysihtml5.dom.parse = (function() {
|
|
5092
5092
|
return mapping[String(attributeValue).toLowerCase()];
|
5093
5093
|
};
|
5094
5094
|
})(),
|
5095
|
-
|
5095
|
+
|
5096
5096
|
align_text: (function() {
|
5097
5097
|
var mapping = {
|
5098
5098
|
left: "wysiwyg-text-align-left",
|
@@ -5104,7 +5104,7 @@ wysihtml5.dom.parse = (function() {
|
|
5104
5104
|
return mapping[String(attributeValue).toLowerCase()];
|
5105
5105
|
};
|
5106
5106
|
})(),
|
5107
|
-
|
5107
|
+
|
5108
5108
|
clear_br: (function() {
|
5109
5109
|
var mapping = {
|
5110
5110
|
left: "wysiwyg-clear-left",
|
@@ -5116,7 +5116,7 @@ wysihtml5.dom.parse = (function() {
|
|
5116
5116
|
return mapping[String(attributeValue).toLowerCase()];
|
5117
5117
|
};
|
5118
5118
|
})(),
|
5119
|
-
|
5119
|
+
|
5120
5120
|
size_font: (function() {
|
5121
5121
|
var mapping = {
|
5122
5122
|
"1": "wysiwyg-font-size-xx-small",
|
@@ -5134,7 +5134,7 @@ wysihtml5.dom.parse = (function() {
|
|
5134
5134
|
};
|
5135
5135
|
})()
|
5136
5136
|
};
|
5137
|
-
|
5137
|
+
|
5138
5138
|
return parse;
|
5139
5139
|
})();/**
|
5140
5140
|
* Checks for empty text node childs and removes them
|
@@ -5191,7 +5191,7 @@ wysihtml5.dom.renameElement = function(element, newNodeName) {
|
|
5191
5191
|
return newElement;
|
5192
5192
|
};/**
|
5193
5193
|
* Takes an element, removes it and replaces it with it's childs
|
5194
|
-
*
|
5194
|
+
*
|
5195
5195
|
* @param {Object} node The node which to replace with it's child nodes
|
5196
5196
|
* @example
|
5197
5197
|
* <div id="foo">
|
@@ -5206,12 +5206,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5206
5206
|
if (!node.parentNode) {
|
5207
5207
|
return;
|
5208
5208
|
}
|
5209
|
-
|
5209
|
+
|
5210
5210
|
if (!node.firstChild) {
|
5211
5211
|
node.parentNode.removeChild(node);
|
5212
5212
|
return;
|
5213
5213
|
}
|
5214
|
-
|
5214
|
+
|
5215
5215
|
var fragment = node.ownerDocument.createDocumentFragment();
|
5216
5216
|
while (node.firstChild) {
|
5217
5217
|
fragment.appendChild(node.firstChild);
|
@@ -5245,21 +5245,21 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5245
5245
|
function _isBlockElement(node) {
|
5246
5246
|
return dom.getStyle("display").from(node) === "block";
|
5247
5247
|
}
|
5248
|
-
|
5248
|
+
|
5249
5249
|
function _isLineBreak(node) {
|
5250
5250
|
return node.nodeName === "BR";
|
5251
5251
|
}
|
5252
|
-
|
5252
|
+
|
5253
5253
|
function _appendLineBreak(element) {
|
5254
5254
|
var lineBreak = element.ownerDocument.createElement("br");
|
5255
5255
|
element.appendChild(lineBreak);
|
5256
5256
|
}
|
5257
|
-
|
5257
|
+
|
5258
5258
|
function resolveList(list) {
|
5259
5259
|
if (list.nodeName !== "MENU" && list.nodeName !== "UL" && list.nodeName !== "OL") {
|
5260
5260
|
return;
|
5261
5261
|
}
|
5262
|
-
|
5262
|
+
|
5263
5263
|
var doc = list.ownerDocument,
|
5264
5264
|
fragment = doc.createDocumentFragment(),
|
5265
5265
|
previousSibling = list.previousElementSibling || list.previousSibling,
|
@@ -5268,11 +5268,11 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5268
5268
|
isLastChild,
|
5269
5269
|
shouldAppendLineBreak,
|
5270
5270
|
listItem;
|
5271
|
-
|
5271
|
+
|
5272
5272
|
if (previousSibling && !_isBlockElement(previousSibling)) {
|
5273
5273
|
_appendLineBreak(fragment);
|
5274
5274
|
}
|
5275
|
-
|
5275
|
+
|
5276
5276
|
while (listItem = list.firstChild) {
|
5277
5277
|
lastChild = listItem.lastChild;
|
5278
5278
|
while (firstChild = listItem.firstChild) {
|
@@ -5284,12 +5284,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5284
5284
|
_appendLineBreak(fragment);
|
5285
5285
|
}
|
5286
5286
|
}
|
5287
|
-
|
5287
|
+
|
5288
5288
|
listItem.parentNode.removeChild(listItem);
|
5289
5289
|
}
|
5290
5290
|
list.parentNode.replaceChild(fragment, list);
|
5291
5291
|
}
|
5292
|
-
|
5292
|
+
|
5293
5293
|
dom.resolveList = resolveList;
|
5294
5294
|
})(wysihtml5.dom);/**
|
5295
5295
|
* Sandbox for executing javascript, parsing css styles and doing dom operations in a secure way
|
@@ -5341,7 +5341,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5341
5341
|
"referrer",
|
5342
5342
|
"write", "open", "close"
|
5343
5343
|
];
|
5344
|
-
|
5344
|
+
|
5345
5345
|
wysihtml5.dom.Sandbox = Base.extend(
|
5346
5346
|
/** @scope wysihtml5.dom.Sandbox.prototype */ {
|
5347
5347
|
|
@@ -5350,12 +5350,12 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5350
5350
|
this.config = wysihtml5.lang.object({}).merge(config).get();
|
5351
5351
|
this.iframe = this._createIframe();
|
5352
5352
|
},
|
5353
|
-
|
5353
|
+
|
5354
5354
|
insertInto: function(element) {
|
5355
5355
|
if (typeof(element) === "string") {
|
5356
5356
|
element = doc.getElementById(element);
|
5357
5357
|
}
|
5358
|
-
|
5358
|
+
|
5359
5359
|
element.appendChild(this.iframe);
|
5360
5360
|
},
|
5361
5361
|
|
@@ -5391,7 +5391,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5391
5391
|
* In order to make this happen we need to set the "allow-scripts" flag.
|
5392
5392
|
* A combination of allow-scripts and allow-same-origin is almost the same as setting no sandbox attribute at all.
|
5393
5393
|
* - Chrome & Safari, doesn't seem to support sandboxing correctly when the iframe's html is inlined (no physical document)
|
5394
|
-
* - IE needs to have the security="restricted" attribute set before the iframe is
|
5394
|
+
* - IE needs to have the security="restricted" attribute set before the iframe is
|
5395
5395
|
* inserted into the dom tree
|
5396
5396
|
* - Believe it or not but in IE "security" in document.createElement("iframe") is false, even
|
5397
5397
|
* though it supports it
|
@@ -5468,7 +5468,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5468
5468
|
|
5469
5469
|
if (!wysihtml5.browser.supportsSandboxedIframes()) {
|
5470
5470
|
// Unset a bunch of sensitive variables
|
5471
|
-
// Please note: This isn't hack safe!
|
5471
|
+
// Please note: This isn't hack safe!
|
5472
5472
|
// It more or less just takes care of basic attacks and prevents accidental theft of sensitive information
|
5473
5473
|
// IE is secure though, which is the most important thing, since IE is the only browser, who
|
5474
5474
|
// takes over scripts & styles into contentEditable elements when copied from external websites
|
@@ -5483,7 +5483,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
5483
5483
|
for (i=0, length=documentProperties.length; i<length; i++) {
|
5484
5484
|
this._unset(iframeDocument, documentProperties[i]);
|
5485
5485
|
}
|
5486
|
-
// This doesn't work in Safari 5
|
5486
|
+
// This doesn't work in Safari 5
|
5487
5487
|
// See http://stackoverflow.com/questions/992461/is-it-possible-to-override-document-cookie-in-webkit
|
5488
5488
|
this._unset(iframeDocument, "cookie", "", true);
|
5489
5489
|
}
|
@@ -5655,11 +5655,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5655
5655
|
// When pasting underlined links <a> into a contentEditable, IE thinks, it has to insert <u> to keep the styling
|
5656
5656
|
"a u": wysihtml5.dom.replaceWithChildNodes
|
5657
5657
|
};
|
5658
|
-
|
5658
|
+
|
5659
5659
|
function cleanPastedHTML(elementOrHtml, rules, context) {
|
5660
5660
|
rules = rules || defaultRules;
|
5661
5661
|
context = context || elementOrHtml.ownerDocument || document;
|
5662
|
-
|
5662
|
+
|
5663
5663
|
var element,
|
5664
5664
|
isString = typeof(elementOrHtml) === "string",
|
5665
5665
|
method,
|
@@ -5672,7 +5672,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5672
5672
|
} else {
|
5673
5673
|
element = elementOrHtml;
|
5674
5674
|
}
|
5675
|
-
|
5675
|
+
|
5676
5676
|
for (i in rules) {
|
5677
5677
|
matches = element.querySelectorAll(i);
|
5678
5678
|
method = rules[i];
|
@@ -5681,12 +5681,12 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5681
5681
|
method(matches[j]);
|
5682
5682
|
}
|
5683
5683
|
}
|
5684
|
-
|
5684
|
+
|
5685
5685
|
matches = elementOrHtml = rules = null;
|
5686
|
-
|
5686
|
+
|
5687
5687
|
return isString ? element.innerHTML : element;
|
5688
5688
|
}
|
5689
|
-
|
5689
|
+
|
5690
5690
|
return cleanPastedHTML;
|
5691
5691
|
})();/**
|
5692
5692
|
* IE and Opera leave an empty paragraph in the contentEditable element after clearing it
|
@@ -5697,7 +5697,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5697
5697
|
*/
|
5698
5698
|
(function(wysihtml5) {
|
5699
5699
|
var dom = wysihtml5.dom;
|
5700
|
-
|
5700
|
+
|
5701
5701
|
wysihtml5.quirks.ensureProperClearing = (function() {
|
5702
5702
|
var clearIfNecessary = function(event) {
|
5703
5703
|
var element = this;
|
@@ -5784,7 +5784,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5784
5784
|
if (innerHTML.indexOf(TILDE_ESCAPED) === -1) {
|
5785
5785
|
return innerHTML;
|
5786
5786
|
}
|
5787
|
-
|
5787
|
+
|
5788
5788
|
var elementsWithTilde = element.querySelectorAll("[href*='~'], [src*='~']"),
|
5789
5789
|
url,
|
5790
5790
|
urlToSearch,
|
@@ -5812,7 +5812,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5812
5812
|
var dom = wysihtml5.dom,
|
5813
5813
|
USE_NATIVE_LINE_BREAK_WHEN_CARET_INSIDE_TAGS = ["LI", "P", "H1", "H2", "H3", "H4", "H5", "H6"],
|
5814
5814
|
LIST_TAGS = ["UL", "OL", "MENU"];
|
5815
|
-
|
5815
|
+
|
5816
5816
|
wysihtml5.quirks.insertLineBreakOnReturn = function(composer) {
|
5817
5817
|
function unwrap(selectedNode) {
|
5818
5818
|
var parentElement = dom.getParentElement(selectedNode, { nodeName: ["P", "DIV"] }, 2);
|
@@ -5861,7 +5861,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5861
5861
|
setTimeout(function() {
|
5862
5862
|
unwrap(composer.selection.getSelectedNode());
|
5863
5863
|
}, 0);
|
5864
|
-
}
|
5864
|
+
}
|
5865
5865
|
return;
|
5866
5866
|
}
|
5867
5867
|
|
@@ -5870,7 +5870,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5870
5870
|
event.preventDefault();
|
5871
5871
|
}
|
5872
5872
|
}
|
5873
|
-
|
5873
|
+
|
5874
5874
|
// keypress doesn't fire when you hit backspace
|
5875
5875
|
dom.observe(composer.element.ownerDocument, "keydown", keyDown);
|
5876
5876
|
};
|
@@ -5884,11 +5884,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5884
5884
|
*/
|
5885
5885
|
(function(wysihtml5) {
|
5886
5886
|
var CLASS_NAME = "wysihtml5-quirks-redraw";
|
5887
|
-
|
5887
|
+
|
5888
5888
|
wysihtml5.quirks.redraw = function(element) {
|
5889
5889
|
wysihtml5.dom.addClass(element, CLASS_NAME);
|
5890
5890
|
wysihtml5.dom.removeClass(element, CLASS_NAME);
|
5891
|
-
|
5891
|
+
|
5892
5892
|
// Following hack is needed for firefox to make sure that image resize handles are properly removed
|
5893
5893
|
try {
|
5894
5894
|
var doc = element.ownerDocument;
|
@@ -5904,7 +5904,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5904
5904
|
*/
|
5905
5905
|
(function(wysihtml5) {
|
5906
5906
|
var dom = wysihtml5.dom;
|
5907
|
-
|
5907
|
+
|
5908
5908
|
function _getCumulativeOffsetTop(element) {
|
5909
5909
|
var top = 0;
|
5910
5910
|
if (element.parentNode) {
|
@@ -5915,18 +5915,18 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
5915
5915
|
}
|
5916
5916
|
return top;
|
5917
5917
|
}
|
5918
|
-
|
5918
|
+
|
5919
5919
|
wysihtml5.Selection = Base.extend(
|
5920
5920
|
/** @scope wysihtml5.Selection.prototype */ {
|
5921
5921
|
constructor: function(editor) {
|
5922
5922
|
// Make sure that our external range library is initialized
|
5923
5923
|
window.rangy.init();
|
5924
|
-
|
5924
|
+
|
5925
5925
|
this.editor = editor;
|
5926
5926
|
this.composer = editor.composer;
|
5927
5927
|
this.doc = this.composer.doc;
|
5928
5928
|
},
|
5929
|
-
|
5929
|
+
|
5930
5930
|
/**
|
5931
5931
|
* Get the current selection as a bookmark to be able to later restore it
|
5932
5932
|
*
|
@@ -6051,23 +6051,23 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6051
6051
|
placeholderHTML = '<span class="' + className + '">' + wysihtml5.INVISIBLE_SPACE + '</span>',
|
6052
6052
|
range = this.getRange(this.doc),
|
6053
6053
|
newRange;
|
6054
|
-
|
6054
|
+
|
6055
6055
|
// Nothing selected, execute and say goodbye
|
6056
6056
|
if (!range) {
|
6057
6057
|
method(body, body);
|
6058
6058
|
return;
|
6059
6059
|
}
|
6060
|
-
|
6060
|
+
|
6061
6061
|
var node = range.createContextualFragment(placeholderHTML);
|
6062
6062
|
range.insertNode(node);
|
6063
|
-
|
6063
|
+
|
6064
6064
|
// Make sure that a potential error doesn't cause our placeholder element to be left as a placeholder
|
6065
6065
|
try {
|
6066
6066
|
method(range.startContainer, range.endContainer);
|
6067
6067
|
} catch(e3) {
|
6068
6068
|
setTimeout(function() { throw e3; }, 0);
|
6069
6069
|
}
|
6070
|
-
|
6070
|
+
|
6071
6071
|
caretPlaceholder = this.doc.querySelector("." + className);
|
6072
6072
|
if (caretPlaceholder) {
|
6073
6073
|
newRange = rangy.createRange(this.doc);
|
@@ -6296,7 +6296,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6296
6296
|
return [];
|
6297
6297
|
}
|
6298
6298
|
},
|
6299
|
-
|
6299
|
+
|
6300
6300
|
getRange: function() {
|
6301
6301
|
var selection = this.getSelection();
|
6302
6302
|
return selection && selection.rangeCount && selection.getRangeAt(0);
|
@@ -6312,7 +6312,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6312
6312
|
return selection.setSingleRange(range);
|
6313
6313
|
}
|
6314
6314
|
});
|
6315
|
-
|
6315
|
+
|
6316
6316
|
})(wysihtml5);
|
6317
6317
|
/**
|
6318
6318
|
* Inspired by the rangy CSS Applier module written by Tim Down and licensed under the MIT license.
|
@@ -6324,14 +6324,14 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6324
6324
|
*/
|
6325
6325
|
(function(wysihtml5, rangy) {
|
6326
6326
|
var defaultTagName = "span";
|
6327
|
-
|
6327
|
+
|
6328
6328
|
var REG_EXP_WHITE_SPACE = /\s+/g;
|
6329
|
-
|
6329
|
+
|
6330
6330
|
function hasClass(el, cssClass, regExp) {
|
6331
6331
|
if (!el.className) {
|
6332
6332
|
return false;
|
6333
6333
|
}
|
6334
|
-
|
6334
|
+
|
6335
6335
|
var matchingClassNames = el.className.match(regExp) || [];
|
6336
6336
|
return matchingClassNames[matchingClassNames.length - 1] === cssClass;
|
6337
6337
|
}
|
@@ -6350,7 +6350,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6350
6350
|
el.className = el.className.replace(regExp, "");
|
6351
6351
|
}
|
6352
6352
|
}
|
6353
|
-
|
6353
|
+
|
6354
6354
|
function hasSameClasses(el1, el2) {
|
6355
6355
|
return el1.className.replace(REG_EXP_WHITE_SPACE, " ") == el2.className.replace(REG_EXP_WHITE_SPACE, " ");
|
6356
6356
|
}
|
@@ -6423,7 +6423,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6423
6423
|
}
|
6424
6424
|
return (descendantNode == node) ? newNode : splitNodeAt(node, newNode.parentNode, rangy.dom.getNodeIndex(newNode));
|
6425
6425
|
}
|
6426
|
-
|
6426
|
+
|
6427
6427
|
function Merge(firstNode) {
|
6428
6428
|
this.isElementMerge = (firstNode.nodeType == wysihtml5.ELEMENT_NODE);
|
6429
6429
|
this.firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;
|
@@ -6539,7 +6539,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6539
6539
|
range.setEnd(rangeEndNode, rangeEndOffset);
|
6540
6540
|
}
|
6541
6541
|
},
|
6542
|
-
|
6542
|
+
|
6543
6543
|
getAdjacentMergeableTextNode: function(node, forward) {
|
6544
6544
|
var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
|
6545
6545
|
var el = isTextNode ? node.parentNode : node;
|
@@ -6560,7 +6560,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6560
6560
|
}
|
6561
6561
|
return null;
|
6562
6562
|
},
|
6563
|
-
|
6563
|
+
|
6564
6564
|
areElementsMergeable: function(el1, el2) {
|
6565
6565
|
return rangy.dom.arrayContains(this.tagNames, (el1.tagName || "").toLowerCase())
|
6566
6566
|
&& rangy.dom.arrayContains(this.tagNames, (el2.tagName || "").toLowerCase())
|
@@ -6607,7 +6607,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6607
6607
|
ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset);
|
6608
6608
|
}
|
6609
6609
|
}
|
6610
|
-
|
6610
|
+
|
6611
6611
|
if (this.similarClassRegExp) {
|
6612
6612
|
removeClass(ancestorWithClass, this.similarClassRegExp);
|
6613
6613
|
}
|
@@ -6626,10 +6626,10 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6626
6626
|
return;
|
6627
6627
|
} catch(e) {}
|
6628
6628
|
}
|
6629
|
-
|
6629
|
+
|
6630
6630
|
range.splitBoundaries();
|
6631
6631
|
textNodes = range.getNodes([wysihtml5.TEXT_NODE]);
|
6632
|
-
|
6632
|
+
|
6633
6633
|
if (textNodes.length) {
|
6634
6634
|
var textNode;
|
6635
6635
|
|
@@ -6639,11 +6639,11 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6639
6639
|
this.applyToTextNode(textNode);
|
6640
6640
|
}
|
6641
6641
|
}
|
6642
|
-
|
6642
|
+
|
6643
6643
|
range.setStart(textNodes[0], 0);
|
6644
6644
|
textNode = textNodes[textNodes.length - 1];
|
6645
6645
|
range.setEnd(textNode, textNode.length);
|
6646
|
-
|
6646
|
+
|
6647
6647
|
if (this.normalize) {
|
6648
6648
|
this.postApply(textNodes, range);
|
6649
6649
|
}
|
@@ -6662,7 +6662,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6662
6662
|
range.selectNode(node);
|
6663
6663
|
textNodes = [node];
|
6664
6664
|
}
|
6665
|
-
|
6665
|
+
|
6666
6666
|
for (var i = 0, len = textNodes.length; i < len; ++i) {
|
6667
6667
|
textNode = textNodes[i];
|
6668
6668
|
ancestorWithClass = this.getAncestorWithClass(textNode);
|
@@ -6670,7 +6670,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6670
6670
|
this.undoToTextNode(textNode, range, ancestorWithClass);
|
6671
6671
|
}
|
6672
6672
|
}
|
6673
|
-
|
6673
|
+
|
6674
6674
|
if (len == 1) {
|
6675
6675
|
this.selectNode(range, textNodes[0]);
|
6676
6676
|
} else {
|
@@ -6683,7 +6683,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6683
6683
|
}
|
6684
6684
|
}
|
6685
6685
|
},
|
6686
|
-
|
6686
|
+
|
6687
6687
|
selectNode: function(range, node) {
|
6688
6688
|
var isElement = node.nodeType === wysihtml5.ELEMENT_NODE,
|
6689
6689
|
canHaveHTML = "canHaveHTML" in node ? node.canHaveHTML : true,
|
@@ -6702,7 +6702,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6702
6702
|
range.setEndAfter(node);
|
6703
6703
|
}
|
6704
6704
|
},
|
6705
|
-
|
6705
|
+
|
6706
6706
|
getTextSelectedByRange: function(textNode, range) {
|
6707
6707
|
var textRange = range.cloneRange();
|
6708
6708
|
textRange.selectNodeContents(textNode);
|
@@ -6722,7 +6722,7 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6722
6722
|
ancestor = this.getAncestorWithClass(range.startContainer);
|
6723
6723
|
return ancestor ? [ancestor] : false;
|
6724
6724
|
}
|
6725
|
-
|
6725
|
+
|
6726
6726
|
for (var i = 0, len = textNodes.length, selectedText; i < len; ++i) {
|
6727
6727
|
selectedText = this.getTextSelectedByRange(textNodes[i], range);
|
6728
6728
|
ancestor = this.getAncestorWithClass(textNodes[i]);
|
@@ -6745,10 +6745,10 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
|
|
6745
6745
|
};
|
6746
6746
|
|
6747
6747
|
wysihtml5.selection.HTMLApplier = HTMLApplier;
|
6748
|
-
|
6748
|
+
|
6749
6749
|
})(wysihtml5, rangy);/**
|
6750
6750
|
* Rich Text Query/Formatting Commands
|
6751
|
-
*
|
6751
|
+
*
|
6752
6752
|
* @example
|
6753
6753
|
* var commands = new wysihtml5.Commands(editor);
|
6754
6754
|
*/
|
@@ -6759,7 +6759,7 @@ wysihtml5.Commands = Base.extend(
|
|
6759
6759
|
this.composer = editor.composer;
|
6760
6760
|
this.doc = this.composer.doc;
|
6761
6761
|
},
|
6762
|
-
|
6762
|
+
|
6763
6763
|
/**
|
6764
6764
|
* Check whether the browser supports the given command
|
6765
6765
|
*
|
@@ -6770,7 +6770,7 @@ wysihtml5.Commands = Base.extend(
|
|
6770
6770
|
support: function(command) {
|
6771
6771
|
return wysihtml5.browser.supportsCommand(this.doc, command);
|
6772
6772
|
},
|
6773
|
-
|
6773
|
+
|
6774
6774
|
/**
|
6775
6775
|
* Check whether the browser supports the given command
|
6776
6776
|
*
|
@@ -6784,9 +6784,9 @@ wysihtml5.Commands = Base.extend(
|
|
6784
6784
|
args = wysihtml5.lang.array(arguments).get(),
|
6785
6785
|
method = obj && obj.exec,
|
6786
6786
|
result = null;
|
6787
|
-
|
6787
|
+
|
6788
6788
|
this.editor.fire("beforecommand:composer");
|
6789
|
-
|
6789
|
+
|
6790
6790
|
if (method) {
|
6791
6791
|
args.unshift(this.composer);
|
6792
6792
|
result = method.apply(obj, args);
|
@@ -6796,11 +6796,11 @@ wysihtml5.Commands = Base.extend(
|
|
6796
6796
|
result = this.doc.execCommand(command, false, value);
|
6797
6797
|
} catch(e) {}
|
6798
6798
|
}
|
6799
|
-
|
6799
|
+
|
6800
6800
|
this.editor.fire("aftercommand:composer");
|
6801
6801
|
return result;
|
6802
6802
|
},
|
6803
|
-
|
6803
|
+
|
6804
6804
|
/**
|
6805
6805
|
* Check whether the current command is active
|
6806
6806
|
* If the caret is within a bold text, then calling this with command "bold" should return true
|
@@ -6827,7 +6827,7 @@ wysihtml5.Commands = Base.extend(
|
|
6827
6827
|
}
|
6828
6828
|
}
|
6829
6829
|
},
|
6830
|
-
|
6830
|
+
|
6831
6831
|
/**
|
6832
6832
|
* Get the current command's value
|
6833
6833
|
*
|
@@ -6853,7 +6853,7 @@ wysihtml5.Commands = Base.extend(
|
|
6853
6853
|
});
|
6854
6854
|
(function(wysihtml5) {
|
6855
6855
|
var undef;
|
6856
|
-
|
6856
|
+
|
6857
6857
|
wysihtml5.commands.bold = {
|
6858
6858
|
exec: function(composer, command) {
|
6859
6859
|
return wysihtml5.commands.formatInline.exec(composer, command, "b");
|
@@ -6878,7 +6878,7 @@ wysihtml5.Commands = Base.extend(
|
|
6878
6878
|
var undef,
|
6879
6879
|
NODE_NAME = "A",
|
6880
6880
|
dom = wysihtml5.dom;
|
6881
|
-
|
6881
|
+
|
6882
6882
|
function _removeFormat(composer, anchors) {
|
6883
6883
|
var length = anchors.length,
|
6884
6884
|
i = 0,
|
@@ -6941,7 +6941,7 @@ wysihtml5.Commands = Base.extend(
|
|
6941
6941
|
}
|
6942
6942
|
composer.selection.setAfter(elementToSetCaretAfter);
|
6943
6943
|
}
|
6944
|
-
|
6944
|
+
|
6945
6945
|
wysihtml5.commands.createLink = {
|
6946
6946
|
/**
|
6947
6947
|
* TODO: Use HTMLApplier or formatInline here
|
@@ -6949,7 +6949,7 @@ wysihtml5.Commands = Base.extend(
|
|
6949
6949
|
* Turns selection into a link
|
6950
6950
|
* If selection is already a link, it removes the link and wraps it with a <code> element
|
6951
6951
|
* The <code> element is needed to avoid auto linking
|
6952
|
-
*
|
6952
|
+
*
|
6953
6953
|
* @example
|
6954
6954
|
* // either ...
|
6955
6955
|
* wysihtml5.commands.createLink.exec(composer, "createLink", "http://www.google.de");
|
@@ -6986,7 +6986,7 @@ wysihtml5.Commands = Base.extend(
|
|
6986
6986
|
(function(wysihtml5) {
|
6987
6987
|
var undef,
|
6988
6988
|
REG_EXP = /wysiwyg-font-size-[a-z\-]+/g;
|
6989
|
-
|
6989
|
+
|
6990
6990
|
wysihtml5.commands.fontSize = {
|
6991
6991
|
exec: function(composer, command, size) {
|
6992
6992
|
return wysihtml5.commands.formatInline.exec(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
|
@@ -7009,7 +7009,7 @@ wysihtml5.Commands = Base.extend(
|
|
7009
7009
|
(function(wysihtml5) {
|
7010
7010
|
var undef,
|
7011
7011
|
REG_EXP = /wysiwyg-color-[a-z]+/g;
|
7012
|
-
|
7012
|
+
|
7013
7013
|
wysihtml5.commands.foreColor = {
|
7014
7014
|
exec: function(composer, command, color) {
|
7015
7015
|
return wysihtml5.commands.formatInline.exec(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
|
@@ -7031,7 +7031,7 @@ wysihtml5.Commands = Base.extend(
|
|
7031
7031
|
// when the caret is within a H1 and the H4 is invoked, the H1 should turn into H4
|
7032
7032
|
// instead of creating a H4 within a H1 which would result in semantically invalid html
|
7033
7033
|
BLOCK_ELEMENTS_GROUP = ["H1", "H2", "H3", "H4", "H5", "H6", "P", "BLOCKQUOTE", DEFAULT_NODE_NAME];
|
7034
|
-
|
7034
|
+
|
7035
7035
|
/**
|
7036
7036
|
* Remove similiar classes (based on classRegExp)
|
7037
7037
|
* and add the desired class name
|
@@ -7173,7 +7173,7 @@ wysihtml5.Commands = Base.extend(
|
|
7173
7173
|
function _hasClasses(element) {
|
7174
7174
|
return !!wysihtml5.lang.string(element.className).trim();
|
7175
7175
|
}
|
7176
|
-
|
7176
|
+
|
7177
7177
|
wysihtml5.commands.formatBlock = {
|
7178
7178
|
exec: function(composer, command, nodeName, className, classRegExp) {
|
7179
7179
|
var doc = composer.doc,
|
@@ -7255,12 +7255,12 @@ wysihtml5.Commands = Base.extend(
|
|
7255
7255
|
* abcdefg|
|
7256
7256
|
* output:
|
7257
7257
|
* abcdefg<b>|</b>
|
7258
|
-
*
|
7258
|
+
*
|
7259
7259
|
* #2 unformatted text selected:
|
7260
7260
|
* abc|deg|h
|
7261
7261
|
* output:
|
7262
7262
|
* abc<b>|deg|</b>h
|
7263
|
-
*
|
7263
|
+
*
|
7264
7264
|
* #3 unformatted text selected across boundaries:
|
7265
7265
|
* ab|c <span>defg|h</span>
|
7266
7266
|
* output:
|
@@ -7291,12 +7291,12 @@ wysihtml5.Commands = Base.extend(
|
|
7291
7291
|
"i": "em"
|
7292
7292
|
},
|
7293
7293
|
htmlApplier = {};
|
7294
|
-
|
7294
|
+
|
7295
7295
|
function _getTagNames(tagName) {
|
7296
7296
|
var alias = ALIAS_MAPPING[tagName];
|
7297
7297
|
return alias ? [tagName.toLowerCase(), alias.toLowerCase()] : [tagName.toLowerCase()];
|
7298
7298
|
}
|
7299
|
-
|
7299
|
+
|
7300
7300
|
function _getApplier(tagName, className, classRegExp) {
|
7301
7301
|
var identifier = tagName + ":" + className;
|
7302
7302
|
if (!htmlApplier[identifier]) {
|
@@ -7304,7 +7304,7 @@ wysihtml5.Commands = Base.extend(
|
|
7304
7304
|
}
|
7305
7305
|
return htmlApplier[identifier];
|
7306
7306
|
}
|
7307
|
-
|
7307
|
+
|
7308
7308
|
wysihtml5.commands.formatInline = {
|
7309
7309
|
exec: function(composer, command, tagName, className, classRegExp) {
|
7310
7310
|
var range = composer.selection.getRange();
|
@@ -7345,7 +7345,7 @@ wysihtml5.Commands = Base.extend(
|
|
7345
7345
|
};
|
7346
7346
|
})(wysihtml5);(function(wysihtml5) {
|
7347
7347
|
var undef;
|
7348
|
-
|
7348
|
+
|
7349
7349
|
wysihtml5.commands.insertHTML = {
|
7350
7350
|
exec: function(composer, command, html) {
|
7351
7351
|
if (composer.commands.support(command)) {
|
@@ -7365,12 +7365,12 @@ wysihtml5.Commands = Base.extend(
|
|
7365
7365
|
};
|
7366
7366
|
})(wysihtml5);(function(wysihtml5) {
|
7367
7367
|
var NODE_NAME = "IMG";
|
7368
|
-
|
7368
|
+
|
7369
7369
|
wysihtml5.commands.insertImage = {
|
7370
7370
|
/**
|
7371
7371
|
* Inserts an <img>
|
7372
7372
|
* If selection is already an image link, it removes it
|
7373
|
-
*
|
7373
|
+
*
|
7374
7374
|
* @example
|
7375
7375
|
* // either ...
|
7376
7376
|
* wysihtml5.commands.insertImage.exec(composer, "insertImage", "http://www.google.de/logo.jpg");
|
@@ -7469,7 +7469,7 @@ wysihtml5.Commands = Base.extend(
|
|
7469
7469
|
})(wysihtml5);(function(wysihtml5) {
|
7470
7470
|
var undef,
|
7471
7471
|
LINE_BREAK = "<br>" + (wysihtml5.browser.needsSpaceAfterLineBreak() ? " " : "");
|
7472
|
-
|
7472
|
+
|
7473
7473
|
wysihtml5.commands.insertLineBreak = {
|
7474
7474
|
exec: function(composer, command) {
|
7475
7475
|
if (composer.commands.support(command)) {
|
@@ -7492,7 +7492,7 @@ wysihtml5.Commands = Base.extend(
|
|
7492
7492
|
};
|
7493
7493
|
})(wysihtml5);(function(wysihtml5) {
|
7494
7494
|
var undef;
|
7495
|
-
|
7495
|
+
|
7496
7496
|
wysihtml5.commands.insertOrderedList = {
|
7497
7497
|
exec: function(composer, command) {
|
7498
7498
|
var doc = composer.doc,
|
@@ -7502,12 +7502,12 @@ wysihtml5.Commands = Base.extend(
|
|
7502
7502
|
tempClassName = "_wysihtml5-temp-" + new Date().getTime(),
|
7503
7503
|
isEmpty,
|
7504
7504
|
tempElement;
|
7505
|
-
|
7505
|
+
|
7506
7506
|
if (composer.commands.support(command)) {
|
7507
7507
|
doc.execCommand(command, false, null);
|
7508
7508
|
return;
|
7509
7509
|
}
|
7510
|
-
|
7510
|
+
|
7511
7511
|
if (list) {
|
7512
7512
|
// Unwrap list
|
7513
7513
|
// <ol><li>foo</li><li>bar</li></ol>
|
@@ -7537,7 +7537,7 @@ wysihtml5.Commands = Base.extend(
|
|
7537
7537
|
}
|
7538
7538
|
}
|
7539
7539
|
},
|
7540
|
-
|
7540
|
+
|
7541
7541
|
state: function(composer) {
|
7542
7542
|
var selectedNode = composer.selection.getSelectedNode();
|
7543
7543
|
return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "OL" });
|
@@ -7549,7 +7549,7 @@ wysihtml5.Commands = Base.extend(
|
|
7549
7549
|
};
|
7550
7550
|
})(wysihtml5);(function(wysihtml5) {
|
7551
7551
|
var undef;
|
7552
|
-
|
7552
|
+
|
7553
7553
|
wysihtml5.commands.insertUnorderedList = {
|
7554
7554
|
exec: function(composer, command) {
|
7555
7555
|
var doc = composer.doc,
|
@@ -7559,12 +7559,12 @@ wysihtml5.Commands = Base.extend(
|
|
7559
7559
|
tempClassName = "_wysihtml5-temp-" + new Date().getTime(),
|
7560
7560
|
isEmpty,
|
7561
7561
|
tempElement;
|
7562
|
-
|
7562
|
+
|
7563
7563
|
if (composer.commands.support(command)) {
|
7564
7564
|
doc.execCommand(command, false, null);
|
7565
7565
|
return;
|
7566
7566
|
}
|
7567
|
-
|
7567
|
+
|
7568
7568
|
if (list) {
|
7569
7569
|
// Unwrap list
|
7570
7570
|
// <ul><li>foo</li><li>bar</li></ul>
|
@@ -7594,7 +7594,7 @@ wysihtml5.Commands = Base.extend(
|
|
7594
7594
|
}
|
7595
7595
|
}
|
7596
7596
|
},
|
7597
|
-
|
7597
|
+
|
7598
7598
|
state: function(composer) {
|
7599
7599
|
var selectedNode = composer.selection.getSelectedNode();
|
7600
7600
|
return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "UL" });
|
@@ -7606,7 +7606,7 @@ wysihtml5.Commands = Base.extend(
|
|
7606
7606
|
};
|
7607
7607
|
})(wysihtml5);(function(wysihtml5) {
|
7608
7608
|
var undef;
|
7609
|
-
|
7609
|
+
|
7610
7610
|
wysihtml5.commands.italic = {
|
7611
7611
|
exec: function(composer, command) {
|
7612
7612
|
return wysihtml5.commands.formatInline.exec(composer, command, "i");
|
@@ -7629,7 +7629,7 @@ wysihtml5.Commands = Base.extend(
|
|
7629
7629
|
var undef,
|
7630
7630
|
CLASS_NAME = "wysiwyg-text-align-center",
|
7631
7631
|
REG_EXP = /wysiwyg-text-align-[a-z]+/g;
|
7632
|
-
|
7632
|
+
|
7633
7633
|
wysihtml5.commands.justifyCenter = {
|
7634
7634
|
exec: function(composer, command) {
|
7635
7635
|
return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
|
@@ -7647,7 +7647,7 @@ wysihtml5.Commands = Base.extend(
|
|
7647
7647
|
var undef,
|
7648
7648
|
CLASS_NAME = "wysiwyg-text-align-left",
|
7649
7649
|
REG_EXP = /wysiwyg-text-align-[a-z]+/g;
|
7650
|
-
|
7650
|
+
|
7651
7651
|
wysihtml5.commands.justifyLeft = {
|
7652
7652
|
exec: function(composer, command) {
|
7653
7653
|
return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
|
@@ -7665,7 +7665,7 @@ wysihtml5.Commands = Base.extend(
|
|
7665
7665
|
var undef,
|
7666
7666
|
CLASS_NAME = "wysiwyg-text-align-right",
|
7667
7667
|
REG_EXP = /wysiwyg-text-align-[a-z]+/g;
|
7668
|
-
|
7668
|
+
|
7669
7669
|
wysihtml5.commands.justifyRight = {
|
7670
7670
|
exec: function(composer, command) {
|
7671
7671
|
return wysihtml5.commands.formatBlock.exec(composer, "formatBlock", null, CLASS_NAME, REG_EXP);
|
@@ -7707,14 +7707,14 @@ wysihtml5.Commands = Base.extend(
|
|
7707
7707
|
UNDO_HTML = '<span id="_wysihtml5-undo" class="_wysihtml5-temp">' + wysihtml5.INVISIBLE_SPACE + '</span>',
|
7708
7708
|
REDO_HTML = '<span id="_wysihtml5-redo" class="_wysihtml5-temp">' + wysihtml5.INVISIBLE_SPACE + '</span>',
|
7709
7709
|
dom = wysihtml5.dom;
|
7710
|
-
|
7710
|
+
|
7711
7711
|
function cleanTempElements(doc) {
|
7712
7712
|
var tempElement;
|
7713
7713
|
while (tempElement = doc.querySelector("._wysihtml5-temp")) {
|
7714
7714
|
tempElement.parentNode.removeChild(tempElement);
|
7715
7715
|
}
|
7716
7716
|
}
|
7717
|
-
|
7717
|
+
|
7718
7718
|
wysihtml5.UndoManager = wysihtml5.lang.Dispatcher.extend(
|
7719
7719
|
/** @scope wysihtml5.UndoManager.prototype */ {
|
7720
7720
|
constructor: function(editor) {
|
@@ -7723,28 +7723,28 @@ wysihtml5.Commands = Base.extend(
|
|
7723
7723
|
this.element = this.composer.element;
|
7724
7724
|
this.history = [this.composer.getValue()];
|
7725
7725
|
this.position = 1;
|
7726
|
-
|
7726
|
+
|
7727
7727
|
// Undo manager currently only supported in browsers who have the insertHTML command (not IE)
|
7728
7728
|
if (this.composer.commands.support("insertHTML")) {
|
7729
7729
|
this._observe();
|
7730
7730
|
}
|
7731
7731
|
},
|
7732
|
-
|
7732
|
+
|
7733
7733
|
_observe: function() {
|
7734
7734
|
var that = this,
|
7735
7735
|
doc = this.composer.sandbox.getDocument(),
|
7736
7736
|
lastKey;
|
7737
|
-
|
7737
|
+
|
7738
7738
|
// Catch CTRL+Z and CTRL+Y
|
7739
7739
|
dom.observe(this.element, "keydown", function(event) {
|
7740
7740
|
if (event.altKey || (!event.ctrlKey && !event.metaKey)) {
|
7741
7741
|
return;
|
7742
7742
|
}
|
7743
|
-
|
7743
|
+
|
7744
7744
|
var keyCode = event.keyCode,
|
7745
7745
|
isUndo = keyCode === Z_KEY && !event.shiftKey,
|
7746
7746
|
isRedo = (keyCode === Z_KEY && event.shiftKey) || (keyCode === Y_KEY);
|
7747
|
-
|
7747
|
+
|
7748
7748
|
if (isUndo) {
|
7749
7749
|
that.undo();
|
7750
7750
|
event.preventDefault();
|
@@ -7753,21 +7753,21 @@ wysihtml5.Commands = Base.extend(
|
|
7753
7753
|
event.preventDefault();
|
7754
7754
|
}
|
7755
7755
|
});
|
7756
|
-
|
7756
|
+
|
7757
7757
|
// Catch delete and backspace
|
7758
7758
|
dom.observe(this.element, "keydown", function(event) {
|
7759
7759
|
var keyCode = event.keyCode;
|
7760
7760
|
if (keyCode === lastKey) {
|
7761
7761
|
return;
|
7762
7762
|
}
|
7763
|
-
|
7763
|
+
|
7764
7764
|
lastKey = keyCode;
|
7765
|
-
|
7765
|
+
|
7766
7766
|
if (keyCode === BACKSPACE_KEY || keyCode === DELETE_KEY) {
|
7767
7767
|
that.transact();
|
7768
7768
|
}
|
7769
7769
|
});
|
7770
|
-
|
7770
|
+
|
7771
7771
|
// Now this is very hacky:
|
7772
7772
|
// These days browsers don't offer a undo/redo event which we could hook into
|
7773
7773
|
// to be notified when the user hits undo/redo in the contextmenu.
|
@@ -7780,7 +7780,7 @@ wysihtml5.Commands = Base.extend(
|
|
7780
7780
|
cleanTempElements(doc);
|
7781
7781
|
clearInterval(interval);
|
7782
7782
|
};
|
7783
|
-
|
7783
|
+
|
7784
7784
|
dom.observe(this.element, "contextmenu", function() {
|
7785
7785
|
cleanUp();
|
7786
7786
|
that.composer.selection.executeAndRestoreSimple(function() {
|
@@ -7812,55 +7812,55 @@ wysihtml5.Commands = Base.extend(
|
|
7812
7812
|
}
|
7813
7813
|
});
|
7814
7814
|
}
|
7815
|
-
|
7815
|
+
|
7816
7816
|
this.editor
|
7817
7817
|
.observe("newword:composer", function() {
|
7818
7818
|
that.transact();
|
7819
7819
|
})
|
7820
|
-
|
7820
|
+
|
7821
7821
|
.observe("beforecommand:composer", function() {
|
7822
7822
|
that.transact();
|
7823
7823
|
});
|
7824
7824
|
},
|
7825
|
-
|
7825
|
+
|
7826
7826
|
transact: function() {
|
7827
7827
|
var previousHtml = this.history[this.position - 1],
|
7828
7828
|
currentHtml = this.composer.getValue();
|
7829
|
-
|
7829
|
+
|
7830
7830
|
if (currentHtml == previousHtml) {
|
7831
7831
|
return;
|
7832
7832
|
}
|
7833
|
-
|
7833
|
+
|
7834
7834
|
var length = this.history.length = this.position;
|
7835
7835
|
if (length > MAX_HISTORY_ENTRIES) {
|
7836
7836
|
this.history.shift();
|
7837
7837
|
this.position--;
|
7838
7838
|
}
|
7839
|
-
|
7839
|
+
|
7840
7840
|
this.position++;
|
7841
7841
|
this.history.push(currentHtml);
|
7842
7842
|
},
|
7843
|
-
|
7843
|
+
|
7844
7844
|
undo: function() {
|
7845
7845
|
this.transact();
|
7846
|
-
|
7846
|
+
|
7847
7847
|
if (this.position <= 1) {
|
7848
7848
|
return;
|
7849
7849
|
}
|
7850
|
-
|
7850
|
+
|
7851
7851
|
this.set(this.history[--this.position - 1]);
|
7852
7852
|
this.editor.fire("undo:composer");
|
7853
7853
|
},
|
7854
|
-
|
7854
|
+
|
7855
7855
|
redo: function() {
|
7856
7856
|
if (this.position >= this.history.length) {
|
7857
7857
|
return;
|
7858
7858
|
}
|
7859
|
-
|
7859
|
+
|
7860
7860
|
this.set(this.history[++this.position - 1]);
|
7861
7861
|
this.editor.fire("redo:composer");
|
7862
7862
|
},
|
7863
|
-
|
7863
|
+
|
7864
7864
|
set: function(html) {
|
7865
7865
|
this.composer.setValue(html);
|
7866
7866
|
this.editor.focus(true);
|
@@ -7876,10 +7876,10 @@ wysihtml5.views.View = Base.extend(
|
|
7876
7876
|
this.parent = parent;
|
7877
7877
|
this.element = textareaElement;
|
7878
7878
|
this.config = config;
|
7879
|
-
|
7879
|
+
|
7880
7880
|
this._observeViewChange();
|
7881
7881
|
},
|
7882
|
-
|
7882
|
+
|
7883
7883
|
_observeViewChange: function() {
|
7884
7884
|
var that = this;
|
7885
7885
|
this.parent.observe("beforeload", function() {
|
@@ -7895,34 +7895,34 @@ wysihtml5.views.View = Base.extend(
|
|
7895
7895
|
});
|
7896
7896
|
});
|
7897
7897
|
},
|
7898
|
-
|
7898
|
+
|
7899
7899
|
focus: function() {
|
7900
7900
|
if (this.element.ownerDocument.querySelector(":focus") === this.element) {
|
7901
7901
|
return;
|
7902
7902
|
}
|
7903
|
-
|
7903
|
+
|
7904
7904
|
try { this.element.focus(); } catch(e) {}
|
7905
7905
|
},
|
7906
|
-
|
7906
|
+
|
7907
7907
|
hide: function() {
|
7908
7908
|
this.element.style.display = "none";
|
7909
7909
|
},
|
7910
|
-
|
7910
|
+
|
7911
7911
|
show: function() {
|
7912
7912
|
this.element.style.display = "";
|
7913
7913
|
},
|
7914
|
-
|
7914
|
+
|
7915
7915
|
disable: function() {
|
7916
7916
|
this.element.setAttribute("disabled", "disabled");
|
7917
7917
|
},
|
7918
|
-
|
7918
|
+
|
7919
7919
|
enable: function() {
|
7920
7920
|
this.element.removeAttribute("disabled");
|
7921
7921
|
}
|
7922
7922
|
});(function(wysihtml5) {
|
7923
7923
|
var dom = wysihtml5.dom,
|
7924
7924
|
browser = wysihtml5.browser;
|
7925
|
-
|
7925
|
+
|
7926
7926
|
wysihtml5.views.Composer = wysihtml5.views.View.extend(
|
7927
7927
|
/** @scope wysihtml5.views.Composer.prototype */ {
|
7928
7928
|
name: "composer",
|
@@ -7942,7 +7942,7 @@ wysihtml5.views.View = Base.extend(
|
|
7942
7942
|
|
7943
7943
|
getValue: function(parse) {
|
7944
7944
|
var value = this.isEmpty() ? "" : wysihtml5.quirks.getCorrectInnerHTML(this.element);
|
7945
|
-
|
7945
|
+
|
7946
7946
|
if (parse) {
|
7947
7947
|
value = this.parent.parse(value);
|
7948
7948
|
}
|
@@ -7995,9 +7995,9 @@ wysihtml5.views.View = Base.extend(
|
|
7995
7995
|
if (wysihtml5.browser.doesAsyncFocus() && this.hasPlaceholderSet()) {
|
7996
7996
|
this.clear();
|
7997
7997
|
}
|
7998
|
-
|
7998
|
+
|
7999
7999
|
this.base();
|
8000
|
-
|
8000
|
+
|
8001
8001
|
var lastChild = this.element.lastChild;
|
8002
8002
|
if (setToEnd && lastChild) {
|
8003
8003
|
if (lastChild.nodeName === "BR") {
|
@@ -8019,7 +8019,7 @@ wysihtml5.views.View = Base.extend(
|
|
8019
8019
|
isEmpty: function() {
|
8020
8020
|
var innerHTML = this.element.innerHTML,
|
8021
8021
|
elementsWithVisualValue = "blockquote, ul, ol, img, embed, object, table, iframe, svg, video, audio, button, input, select, textarea";
|
8022
|
-
return innerHTML === "" ||
|
8022
|
+
return innerHTML === "" ||
|
8023
8023
|
innerHTML === this.CARET_HACK ||
|
8024
8024
|
this.hasPlaceholderSet() ||
|
8025
8025
|
(this.getTextContent() === "" && !this.element.querySelector(elementsWithVisualValue));
|
@@ -8027,7 +8027,7 @@ wysihtml5.views.View = Base.extend(
|
|
8027
8027
|
|
8028
8028
|
_initSandbox: function() {
|
8029
8029
|
var that = this;
|
8030
|
-
|
8030
|
+
|
8031
8031
|
this.sandbox = new dom.Sandbox(function() {
|
8032
8032
|
that._create();
|
8033
8033
|
}, {
|
@@ -8049,23 +8049,23 @@ wysihtml5.views.View = Base.extend(
|
|
8049
8049
|
|
8050
8050
|
_create: function() {
|
8051
8051
|
var that = this;
|
8052
|
-
|
8052
|
+
|
8053
8053
|
this.doc = this.sandbox.getDocument();
|
8054
8054
|
this.element = this.doc.body;
|
8055
8055
|
this.textarea = this.parent.textarea;
|
8056
8056
|
this.element.innerHTML = this.textarea.getValue(true);
|
8057
8057
|
this.enable();
|
8058
|
-
|
8058
|
+
|
8059
8059
|
// Make sure our selection handler is ready
|
8060
8060
|
this.selection = new wysihtml5.Selection(this.parent);
|
8061
|
-
|
8061
|
+
|
8062
8062
|
// Make sure commands dispatcher is ready
|
8063
8063
|
this.commands = new wysihtml5.Commands(this.parent);
|
8064
8064
|
|
8065
8065
|
dom.copyAttributes([
|
8066
8066
|
"className", "spellcheck", "title", "lang", "dir", "accessKey"
|
8067
8067
|
]).from(this.textarea.element).to(this.element);
|
8068
|
-
|
8068
|
+
|
8069
8069
|
dom.addClass(this.element, this.config.composerClassName);
|
8070
8070
|
|
8071
8071
|
// Make the editor look like the original textarea, by syncing styles
|
@@ -8088,7 +8088,7 @@ wysihtml5.views.View = Base.extend(
|
|
8088
8088
|
if (placeholderText) {
|
8089
8089
|
dom.simulatePlaceholder(this.parent, this, placeholderText);
|
8090
8090
|
}
|
8091
|
-
|
8091
|
+
|
8092
8092
|
// Make sure that the browser avoids using inline styles whenever possible
|
8093
8093
|
this.commands.exec("styleWithCSS", false);
|
8094
8094
|
|
@@ -8196,9 +8196,9 @@ wysihtml5.views.View = Base.extend(
|
|
8196
8196
|
var properties = ["width", "height"],
|
8197
8197
|
propertiesLength = properties.length,
|
8198
8198
|
element = this.element;
|
8199
|
-
|
8199
|
+
|
8200
8200
|
this.commands.exec("enableObjectResizing", this.config.allowObjectResizing);
|
8201
|
-
|
8201
|
+
|
8202
8202
|
if (this.config.allowObjectResizing) {
|
8203
8203
|
// IE sets inline styles after resizing objects
|
8204
8204
|
// The following lines make sure that the width/height css properties
|
@@ -8226,7 +8226,7 @@ wysihtml5.views.View = Base.extend(
|
|
8226
8226
|
}
|
8227
8227
|
}
|
8228
8228
|
},
|
8229
|
-
|
8229
|
+
|
8230
8230
|
_initUndoManager: function() {
|
8231
8231
|
new wysihtml5.UndoManager(this.parent);
|
8232
8232
|
}
|
@@ -8283,13 +8283,13 @@ wysihtml5.views.View = Base.extend(
|
|
8283
8283
|
"body { min-height: 100%; padding: 0; margin: 0; margin-top: -1px; padding-top: 1px; }",
|
8284
8284
|
"._wysihtml5-temp { display: none; }",
|
8285
8285
|
wysihtml5.browser.isGecko ?
|
8286
|
-
"body.placeholder { color: graytext !important; }" :
|
8286
|
+
"body.placeholder { color: graytext !important; }" :
|
8287
8287
|
"body.placeholder { color: #a9a9a9 !important; }",
|
8288
8288
|
"body[disabled] { background-color: #eee !important; color: #999 !important; cursor: default !important; }",
|
8289
8289
|
// Ensure that user see's broken images and can delete them
|
8290
8290
|
"img:-moz-broken { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }"
|
8291
8291
|
];
|
8292
|
-
|
8292
|
+
|
8293
8293
|
/**
|
8294
8294
|
* With "setActive" IE offers a smart way of focusing elements without scrolling them into view:
|
8295
8295
|
* http://msdn.microsoft.com/en-us/library/ms536738(v=vs.85).aspx
|
@@ -8313,7 +8313,7 @@ wysihtml5.views.View = Base.extend(
|
|
8313
8313
|
left: elementStyle.left,
|
8314
8314
|
WebkitUserSelect: elementStyle.WebkitUserSelect
|
8315
8315
|
};
|
8316
|
-
|
8316
|
+
|
8317
8317
|
dom.setStyles({
|
8318
8318
|
position: "absolute",
|
8319
8319
|
top: "-99999px",
|
@@ -8321,11 +8321,11 @@ wysihtml5.views.View = Base.extend(
|
|
8321
8321
|
// Don't ask why but temporarily setting -webkit-user-select to none makes the whole thing performing smoother
|
8322
8322
|
WebkitUserSelect: "none"
|
8323
8323
|
}).on(element);
|
8324
|
-
|
8324
|
+
|
8325
8325
|
element.focus();
|
8326
|
-
|
8326
|
+
|
8327
8327
|
dom.setStyles(originalStyles).on(element);
|
8328
|
-
|
8328
|
+
|
8329
8329
|
if (win.scrollTo) {
|
8330
8330
|
// Some browser extensions unset this method to prevent annoyances
|
8331
8331
|
// "Better PopUp Blocker" for Chrome http://code.google.com/p/betterpopupblocker/source/browse/trunk/blockStart.js#100
|
@@ -8334,8 +8334,8 @@ wysihtml5.views.View = Base.extend(
|
|
8334
8334
|
}
|
8335
8335
|
}
|
8336
8336
|
};
|
8337
|
-
|
8338
|
-
|
8337
|
+
|
8338
|
+
|
8339
8339
|
wysihtml5.views.Composer.prototype.style = function() {
|
8340
8340
|
var that = this,
|
8341
8341
|
originalActiveElement = doc.querySelector(":focus"),
|
@@ -8344,47 +8344,47 @@ wysihtml5.views.View = Base.extend(
|
|
8344
8344
|
originalPlaceholder = hasPlaceholder && textareaElement.getAttribute("placeholder");
|
8345
8345
|
this.focusStylesHost = this.focusStylesHost || HOST_TEMPLATE.cloneNode(false);
|
8346
8346
|
this.blurStylesHost = this.blurStylesHost || HOST_TEMPLATE.cloneNode(false);
|
8347
|
-
|
8347
|
+
|
8348
8348
|
// Remove placeholder before copying (as the placeholder has an affect on the computed style)
|
8349
8349
|
if (hasPlaceholder) {
|
8350
8350
|
textareaElement.removeAttribute("placeholder");
|
8351
8351
|
}
|
8352
|
-
|
8352
|
+
|
8353
8353
|
if (textareaElement === originalActiveElement) {
|
8354
8354
|
textareaElement.blur();
|
8355
8355
|
}
|
8356
|
-
|
8356
|
+
|
8357
8357
|
// --------- iframe styles (has to be set before editor styles, otherwise IE9 sets wrong fontFamily on blurStylesHost) ---------
|
8358
8358
|
dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.iframe).andTo(this.blurStylesHost);
|
8359
|
-
|
8359
|
+
|
8360
8360
|
// --------- editor styles ---------
|
8361
8361
|
dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.element).andTo(this.blurStylesHost);
|
8362
|
-
|
8362
|
+
|
8363
8363
|
// --------- apply standard rules ---------
|
8364
8364
|
dom.insertCSS(ADDITIONAL_CSS_RULES).into(this.element.ownerDocument);
|
8365
|
-
|
8365
|
+
|
8366
8366
|
// --------- :focus styles ---------
|
8367
8367
|
focusWithoutScrolling(textareaElement);
|
8368
8368
|
dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.focusStylesHost);
|
8369
8369
|
dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.focusStylesHost);
|
8370
|
-
|
8370
|
+
|
8371
8371
|
// Make sure that we don't change the display style of the iframe when copying styles oblur/onfocus
|
8372
8372
|
// this is needed for when the change_view event is fired where the iframe is hidden and then
|
8373
8373
|
// the blur event fires and re-displays it
|
8374
8374
|
var boxFormattingStyles = wysihtml5.lang.array(BOX_FORMATTING).without(["display"]);
|
8375
|
-
|
8375
|
+
|
8376
8376
|
// --------- restore focus ---------
|
8377
8377
|
if (originalActiveElement) {
|
8378
8378
|
originalActiveElement.focus();
|
8379
8379
|
} else {
|
8380
8380
|
textareaElement.blur();
|
8381
8381
|
}
|
8382
|
-
|
8382
|
+
|
8383
8383
|
// --------- restore placeholder ---------
|
8384
8384
|
if (hasPlaceholder) {
|
8385
8385
|
textareaElement.setAttribute("placeholder", originalPlaceholder);
|
8386
8386
|
}
|
8387
|
-
|
8387
|
+
|
8388
8388
|
// When copying styles, we only get the computed style which is never returned in percent unit
|
8389
8389
|
// Therefore we've to recalculate style onresize
|
8390
8390
|
if (!wysihtml5.browser.hasCurrentStyleProperty()) {
|
@@ -8407,7 +8407,7 @@ wysihtml5.views.View = Base.extend(
|
|
8407
8407
|
textareaElement.style.display = originalTextareaDisplayStyle;
|
8408
8408
|
});
|
8409
8409
|
}
|
8410
|
-
|
8410
|
+
|
8411
8411
|
// --------- Sync focus/blur styles ---------
|
8412
8412
|
this.parent.observe("focus:composer", function() {
|
8413
8413
|
dom.copyStyles(boxFormattingStyles) .from(that.focusStylesHost).to(that.iframe);
|
@@ -8418,7 +8418,7 @@ wysihtml5.views.View = Base.extend(
|
|
8418
8418
|
dom.copyStyles(boxFormattingStyles) .from(that.blurStylesHost).to(that.iframe);
|
8419
8419
|
dom.copyStyles(TEXT_FORMATTING) .from(that.blurStylesHost).to(that.element);
|
8420
8420
|
});
|
8421
|
-
|
8421
|
+
|
8422
8422
|
return this;
|
8423
8423
|
};
|
8424
8424
|
})(wysihtml5);/**
|
@@ -8440,7 +8440,7 @@ wysihtml5.views.View = Base.extend(
|
|
8440
8440
|
"73": "italic", // I
|
8441
8441
|
"85": "underline" // U
|
8442
8442
|
};
|
8443
|
-
|
8443
|
+
|
8444
8444
|
wysihtml5.views.Composer.prototype.observe = function() {
|
8445
8445
|
var that = this,
|
8446
8446
|
state = this.getValue(),
|
@@ -8480,7 +8480,7 @@ wysihtml5.views.View = Base.extend(
|
|
8480
8480
|
}
|
8481
8481
|
that.parent.fire("blur").fire("blur:composer");
|
8482
8482
|
});
|
8483
|
-
|
8483
|
+
|
8484
8484
|
if (wysihtml5.browser.isIos()) {
|
8485
8485
|
// When on iPad/iPhone/IPod after clicking outside of editor, the editor loses focus
|
8486
8486
|
// but the UI still acts as if the editor has focus (blinking caret and onscreen keyboard visible)
|
@@ -8496,7 +8496,7 @@ wysihtml5.views.View = Base.extend(
|
|
8496
8496
|
}
|
8497
8497
|
input.focus();
|
8498
8498
|
input.parentNode.removeChild(input);
|
8499
|
-
|
8499
|
+
|
8500
8500
|
window.scrollTo(originalScrollLeft, originalScrollTop);
|
8501
8501
|
});
|
8502
8502
|
}
|
@@ -8554,7 +8554,7 @@ wysihtml5.views.View = Base.extend(
|
|
8554
8554
|
}
|
8555
8555
|
});
|
8556
8556
|
}
|
8557
|
-
|
8557
|
+
|
8558
8558
|
// --------- Shortcut logic ---------
|
8559
8559
|
dom.observe(element, "keydown", function(event) {
|
8560
8560
|
var keyCode = event.keyCode,
|
@@ -8589,7 +8589,7 @@ wysihtml5.views.View = Base.extend(
|
|
8589
8589
|
IMG: "Image: ",
|
8590
8590
|
A: "Link: "
|
8591
8591
|
};
|
8592
|
-
|
8592
|
+
|
8593
8593
|
dom.observe(element, "mouseover", function(event) {
|
8594
8594
|
var target = event.target,
|
8595
8595
|
nodeName = target.nodeName,
|
@@ -8609,7 +8609,7 @@ wysihtml5.views.View = Base.extend(
|
|
8609
8609
|
*/
|
8610
8610
|
(function(wysihtml5) {
|
8611
8611
|
var INTERVAL = 400;
|
8612
|
-
|
8612
|
+
|
8613
8613
|
wysihtml5.views.Synchronizer = Base.extend(
|
8614
8614
|
/** @scope wysihtml5.views.Synchronizer.prototype */ {
|
8615
8615
|
|
@@ -8704,17 +8704,17 @@ wysihtml5.views.View = Base.extend(
|
|
8704
8704
|
wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
8705
8705
|
/** @scope wysihtml5.views.Textarea.prototype */ {
|
8706
8706
|
name: "textarea",
|
8707
|
-
|
8707
|
+
|
8708
8708
|
constructor: function(parent, textareaElement, config) {
|
8709
8709
|
this.base(parent, textareaElement, config);
|
8710
|
-
|
8710
|
+
|
8711
8711
|
this._observe();
|
8712
8712
|
},
|
8713
|
-
|
8713
|
+
|
8714
8714
|
clear: function() {
|
8715
8715
|
this.element.value = "";
|
8716
8716
|
},
|
8717
|
-
|
8717
|
+
|
8718
8718
|
getValue: function(parse) {
|
8719
8719
|
var value = this.isEmpty() ? "" : this.element.value;
|
8720
8720
|
if (parse) {
|
@@ -8722,14 +8722,14 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8722
8722
|
}
|
8723
8723
|
return value;
|
8724
8724
|
},
|
8725
|
-
|
8725
|
+
|
8726
8726
|
setValue: function(html, parse) {
|
8727
8727
|
if (parse) {
|
8728
8728
|
html = this.parent.parse(html);
|
8729
8729
|
}
|
8730
8730
|
this.element.value = html;
|
8731
8731
|
},
|
8732
|
-
|
8732
|
+
|
8733
8733
|
hasPlaceholderSet: function() {
|
8734
8734
|
var supportsPlaceholder = wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),
|
8735
8735
|
placeholderText = this.element.getAttribute("placeholder") || null,
|
@@ -8737,11 +8737,11 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8737
8737
|
isEmpty = !value;
|
8738
8738
|
return (supportsPlaceholder && isEmpty) || (value === placeholderText);
|
8739
8739
|
},
|
8740
|
-
|
8740
|
+
|
8741
8741
|
isEmpty: function() {
|
8742
8742
|
return !wysihtml5.lang.string(this.element.value).trim() || this.hasPlaceholderSet();
|
8743
8743
|
},
|
8744
|
-
|
8744
|
+
|
8745
8745
|
_observe: function() {
|
8746
8746
|
var element = this.element,
|
8747
8747
|
parent = this.parent,
|
@@ -8754,13 +8754,13 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8754
8754
|
* This is the case for focusin and focusout, so let's use them whenever possible, kkthxbai
|
8755
8755
|
*/
|
8756
8756
|
events = wysihtml5.browser.supportsEvent("focusin") ? ["focusin", "focusout", "change"] : ["focus", "blur", "change"];
|
8757
|
-
|
8757
|
+
|
8758
8758
|
parent.observe("beforeload", function() {
|
8759
8759
|
wysihtml5.dom.observe(element, events, function(event) {
|
8760
8760
|
var eventName = eventMapping[event.type] || event.type;
|
8761
8761
|
parent.fire(eventName).fire(eventName + ":textarea");
|
8762
8762
|
});
|
8763
|
-
|
8763
|
+
|
8764
8764
|
wysihtml5.dom.observe(element, ["paste", "drop"], function() {
|
8765
8765
|
setTimeout(function() { parent.fire("paste").fire("paste:textarea"); }, 0);
|
8766
8766
|
});
|
@@ -8802,8 +8802,8 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8802
8802
|
SELECTOR_FORM_ELEMENTS = "input, select, textarea",
|
8803
8803
|
SELECTOR_FIELDS = "[data-wysihtml5-dialog-field]",
|
8804
8804
|
ATTRIBUTE_FIELDS = "data-wysihtml5-dialog-field";
|
8805
|
-
|
8806
|
-
|
8805
|
+
|
8806
|
+
|
8807
8807
|
wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
|
8808
8808
|
/** @scope wysihtml5.toolbar.Dialog.prototype */ {
|
8809
8809
|
constructor: function(link, container) {
|
@@ -8815,7 +8815,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8815
8815
|
if (this._observed) {
|
8816
8816
|
return;
|
8817
8817
|
}
|
8818
|
-
|
8818
|
+
|
8819
8819
|
var that = this,
|
8820
8820
|
callbackWrapper = function(event) {
|
8821
8821
|
var attributes = that._serialize();
|
@@ -8883,14 +8883,14 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8883
8883
|
/**
|
8884
8884
|
* Takes the attributes of the "elementToChange"
|
8885
8885
|
* and inserts them in their corresponding dialog input fields
|
8886
|
-
*
|
8886
|
+
*
|
8887
8887
|
* Assume the "elementToChange" looks like this:
|
8888
8888
|
* <a href="http://www.google.com" target="_blank">foo</a>
|
8889
8889
|
*
|
8890
8890
|
* and we have the following dialog:
|
8891
8891
|
* <input type="text" data-wysihtml5-dialog-field="href" value="">
|
8892
8892
|
* <input type="text" data-wysihtml5-dialog-field="target" value="">
|
8893
|
-
*
|
8893
|
+
*
|
8894
8894
|
* after calling _interpolate() the dialog will look like this
|
8895
8895
|
* <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
|
8896
8896
|
* <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
|
@@ -8908,18 +8908,18 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8908
8908
|
i = 0;
|
8909
8909
|
for (; i<length; i++) {
|
8910
8910
|
field = fields[i];
|
8911
|
-
|
8911
|
+
|
8912
8912
|
// Never change elements where the user is currently typing in
|
8913
8913
|
if (field === focusedElement) {
|
8914
8914
|
continue;
|
8915
8915
|
}
|
8916
|
-
|
8916
|
+
|
8917
8917
|
// Don't update hidden fields
|
8918
8918
|
// See https://github.com/xing/wysihtml5/pull/14
|
8919
8919
|
if (avoidHiddenFields && field.type === "hidden") {
|
8920
8920
|
continue;
|
8921
8921
|
}
|
8922
|
-
|
8922
|
+
|
8923
8923
|
fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
|
8924
8924
|
newValue = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
|
8925
8925
|
field.value = newValue;
|
@@ -8969,17 +8969,17 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8969
8969
|
*
|
8970
8970
|
* Current HTML5 draft can be found here
|
8971
8971
|
* http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html
|
8972
|
-
*
|
8972
|
+
*
|
8973
8973
|
* "Accessing Google Speech API Chrome 11"
|
8974
8974
|
* http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
|
8975
8975
|
*/
|
8976
8976
|
(function(wysihtml5) {
|
8977
8977
|
var dom = wysihtml5.dom;
|
8978
|
-
|
8978
|
+
|
8979
8979
|
var linkStyles = {
|
8980
8980
|
position: "relative"
|
8981
8981
|
};
|
8982
|
-
|
8982
|
+
|
8983
8983
|
var wrapperStyles = {
|
8984
8984
|
left: 0,
|
8985
8985
|
margin: 0,
|
@@ -8990,7 +8990,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
8990
8990
|
top: 0,
|
8991
8991
|
zIndex: 1
|
8992
8992
|
};
|
8993
|
-
|
8993
|
+
|
8994
8994
|
var inputStyles = {
|
8995
8995
|
cursor: "inherit",
|
8996
8996
|
fontSize: "50px",
|
@@ -9002,46 +9002,46 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9002
9002
|
right: "-4px",
|
9003
9003
|
top: "50%"
|
9004
9004
|
};
|
9005
|
-
|
9005
|
+
|
9006
9006
|
var inputAttributes = {
|
9007
9007
|
"x-webkit-speech": "",
|
9008
9008
|
"speech": ""
|
9009
9009
|
};
|
9010
|
-
|
9010
|
+
|
9011
9011
|
wysihtml5.toolbar.Speech = function(parent, link) {
|
9012
9012
|
var input = document.createElement("input");
|
9013
9013
|
if (!wysihtml5.browser.supportsSpeechApiOn(input)) {
|
9014
9014
|
link.style.display = "none";
|
9015
9015
|
return;
|
9016
9016
|
}
|
9017
|
-
|
9017
|
+
|
9018
9018
|
var wrapper = document.createElement("div");
|
9019
|
-
|
9019
|
+
|
9020
9020
|
wysihtml5.lang.object(wrapperStyles).merge({
|
9021
9021
|
width: link.offsetWidth + "px",
|
9022
9022
|
height: link.offsetHeight + "px"
|
9023
9023
|
});
|
9024
|
-
|
9024
|
+
|
9025
9025
|
dom.insert(input).into(wrapper);
|
9026
9026
|
dom.insert(wrapper).into(link);
|
9027
|
-
|
9027
|
+
|
9028
9028
|
dom.setStyles(inputStyles).on(input);
|
9029
9029
|
dom.setAttributes(inputAttributes).on(input)
|
9030
|
-
|
9030
|
+
|
9031
9031
|
dom.setStyles(wrapperStyles).on(wrapper);
|
9032
9032
|
dom.setStyles(linkStyles).on(link);
|
9033
|
-
|
9033
|
+
|
9034
9034
|
var eventName = "onwebkitspeechchange" in input ? "webkitspeechchange" : "speechchange";
|
9035
9035
|
dom.observe(input, eventName, function() {
|
9036
9036
|
parent.execCommand("insertText", input.value);
|
9037
9037
|
input.value = "";
|
9038
9038
|
});
|
9039
|
-
|
9039
|
+
|
9040
9040
|
dom.observe(input, "click", function(event) {
|
9041
9041
|
if (dom.hasClass(link, "wysihtml5-command-disabled")) {
|
9042
9042
|
event.preventDefault();
|
9043
9043
|
}
|
9044
|
-
|
9044
|
+
|
9045
9045
|
event.stopPropagation();
|
9046
9046
|
});
|
9047
9047
|
};
|
@@ -9067,7 +9067,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9067
9067
|
CLASS_NAME_COMMAND_ACTIVE = "wysihtml5-command-active",
|
9068
9068
|
CLASS_NAME_ACTION_ACTIVE = "wysihtml5-action-active",
|
9069
9069
|
dom = wysihtml5.dom;
|
9070
|
-
|
9070
|
+
|
9071
9071
|
wysihtml5.toolbar.Toolbar = Base.extend(
|
9072
9072
|
/** @scope wysihtml5.toolbar.Toolbar.prototype */ {
|
9073
9073
|
constructor: function(editor, container) {
|
@@ -9080,7 +9080,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9080
9080
|
|
9081
9081
|
this._observe();
|
9082
9082
|
this.show();
|
9083
|
-
|
9083
|
+
|
9084
9084
|
var speechInputLinks = this.container.querySelectorAll("[data-wysihtml5-command=insertSpeech]"),
|
9085
9085
|
length = speechInputLinks.length,
|
9086
9086
|
i = 0;
|
@@ -9105,7 +9105,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9105
9105
|
value = link.getAttribute("data-wysihtml5-" + type + "-value");
|
9106
9106
|
group = this.container.querySelector("[data-wysihtml5-" + type + "-group='" + name + "']");
|
9107
9107
|
dialog = this._getDialog(link, name);
|
9108
|
-
|
9108
|
+
|
9109
9109
|
mapping[name + ":" + value] = {
|
9110
9110
|
link: link,
|
9111
9111
|
group: group,
|
@@ -9122,7 +9122,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9122
9122
|
dialogElement = this.container.querySelector("[data-wysihtml5-dialog='" + command + "']"),
|
9123
9123
|
dialog,
|
9124
9124
|
caretBookmark;
|
9125
|
-
|
9125
|
+
|
9126
9126
|
if (dialogElement) {
|
9127
9127
|
dialog = new wysihtml5.toolbar.Dialog(link, dialogElement);
|
9128
9128
|
|
@@ -9137,7 +9137,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9137
9137
|
that.composer.selection.setBookmark(caretBookmark);
|
9138
9138
|
}
|
9139
9139
|
that._execCommand(command, attributes);
|
9140
|
-
|
9140
|
+
|
9141
9141
|
that.editor.fire("save:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
|
9142
9142
|
});
|
9143
9143
|
|
@@ -9198,7 +9198,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9198
9198
|
links = this.commandLinks.concat(this.actionLinks),
|
9199
9199
|
length = links.length,
|
9200
9200
|
i = 0;
|
9201
|
-
|
9201
|
+
|
9202
9202
|
for (; i<length; i++) {
|
9203
9203
|
// 'javascript:;' and unselectable=on Needed for IE, but done in all browsers to make sure that all get the same css applied
|
9204
9204
|
// (you know, a:link { ... } doesn't match anchors with missing href attribute)
|
@@ -9210,7 +9210,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9210
9210
|
|
9211
9211
|
// Needed for opera
|
9212
9212
|
dom.delegate(container, "[data-wysihtml5-command]", "mousedown", function(event) { event.preventDefault(); });
|
9213
|
-
|
9213
|
+
|
9214
9214
|
dom.delegate(container, "[data-wysihtml5-command]", "click", function(event) {
|
9215
9215
|
var link = this,
|
9216
9216
|
command = link.getAttribute("data-wysihtml5-command"),
|
@@ -9315,10 +9315,10 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9315
9315
|
}
|
9316
9316
|
}
|
9317
9317
|
}
|
9318
|
-
|
9318
|
+
|
9319
9319
|
for (i in actionMapping) {
|
9320
9320
|
action = actionMapping[i];
|
9321
|
-
|
9321
|
+
|
9322
9322
|
if (action.name === "change_view") {
|
9323
9323
|
action.state = this.editor.currentView === this.editor.textarea;
|
9324
9324
|
if (action.state) {
|
@@ -9338,7 +9338,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9338
9338
|
this.container.style.display = "none";
|
9339
9339
|
}
|
9340
9340
|
});
|
9341
|
-
|
9341
|
+
|
9342
9342
|
})(wysihtml5);
|
9343
9343
|
/**
|
9344
9344
|
* WYSIHTML5 Editor
|
@@ -9371,9 +9371,9 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9371
9371
|
*/
|
9372
9372
|
(function(wysihtml5) {
|
9373
9373
|
var undef;
|
9374
|
-
|
9374
|
+
|
9375
9375
|
var defaultConfig = {
|
9376
|
-
// Give the editor a name, the name will also be set as class name on the iframe and on the iframe's body
|
9376
|
+
// Give the editor a name, the name will also be set as class name on the iframe and on the iframe's body
|
9377
9377
|
name: undef,
|
9378
9378
|
// Whether the editor should look like the textarea (by adopting styles)
|
9379
9379
|
style: true,
|
@@ -9399,7 +9399,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9399
9399
|
// Whether the rich text editor should be rendered on touch devices (wysihtml5 >= 0.3.0 comes with basic support for iOS 5)
|
9400
9400
|
supportTouchDevices: true
|
9401
9401
|
};
|
9402
|
-
|
9402
|
+
|
9403
9403
|
wysihtml5.Editor = wysihtml5.lang.Dispatcher.extend(
|
9404
9404
|
/** @scope wysihtml5.Editor.prototype */ {
|
9405
9405
|
constructor: function(textareaElement, config) {
|
@@ -9408,36 +9408,36 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9408
9408
|
this.textarea = new wysihtml5.views.Textarea(this, this.textareaElement, this.config);
|
9409
9409
|
this.currentView = this.textarea;
|
9410
9410
|
this._isCompatible = wysihtml5.browser.supported();
|
9411
|
-
|
9411
|
+
|
9412
9412
|
// Sort out unsupported/unwanted browsers here
|
9413
9413
|
if (!this._isCompatible || (!this.config.supportTouchDevices && wysihtml5.browser.isTouchDevice())) {
|
9414
9414
|
var that = this;
|
9415
9415
|
setTimeout(function() { that.fire("beforeload").fire("load"); }, 0);
|
9416
9416
|
return;
|
9417
9417
|
}
|
9418
|
-
|
9418
|
+
|
9419
9419
|
// Add class name to body, to indicate that the editor is supported
|
9420
9420
|
wysihtml5.dom.addClass(document.body, this.config.bodyClassName);
|
9421
|
-
|
9421
|
+
|
9422
9422
|
this.composer = new wysihtml5.views.Composer(this, this.textareaElement, this.config);
|
9423
9423
|
this.currentView = this.composer;
|
9424
|
-
|
9424
|
+
|
9425
9425
|
if (typeof(this.config.parser) === "function") {
|
9426
9426
|
this._initParser();
|
9427
9427
|
}
|
9428
|
-
|
9428
|
+
|
9429
9429
|
this.observe("beforeload", function() {
|
9430
9430
|
this.synchronizer = new wysihtml5.views.Synchronizer(this, this.textarea, this.composer);
|
9431
9431
|
if (this.config.toolbar) {
|
9432
9432
|
this.toolbar = new wysihtml5.toolbar.Toolbar(this, this.config.toolbar);
|
9433
9433
|
}
|
9434
9434
|
});
|
9435
|
-
|
9435
|
+
|
9436
9436
|
try {
|
9437
9437
|
console.log("Heya! This page is using wysihtml5 for rich text editing. Check out https://github.com/xing/wysihtml5");
|
9438
9438
|
} catch(e) {}
|
9439
9439
|
},
|
9440
|
-
|
9440
|
+
|
9441
9441
|
isCompatible: function() {
|
9442
9442
|
return this._isCompatible;
|
9443
9443
|
},
|
@@ -9471,7 +9471,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9471
9471
|
this.currentView.disable();
|
9472
9472
|
return this;
|
9473
9473
|
},
|
9474
|
-
|
9474
|
+
|
9475
9475
|
/**
|
9476
9476
|
* Activate editor
|
9477
9477
|
*/
|
@@ -9479,15 +9479,15 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9479
9479
|
this.currentView.enable();
|
9480
9480
|
return this;
|
9481
9481
|
},
|
9482
|
-
|
9482
|
+
|
9483
9483
|
isEmpty: function() {
|
9484
9484
|
return this.currentView.isEmpty();
|
9485
9485
|
},
|
9486
|
-
|
9486
|
+
|
9487
9487
|
hasPlaceholderSet: function() {
|
9488
9488
|
return this.currentView.hasPlaceholderSet();
|
9489
9489
|
},
|
9490
|
-
|
9490
|
+
|
9491
9491
|
parse: function(htmlOrElement) {
|
9492
9492
|
var returnValue = this.config.parser(htmlOrElement, this.config.parserRules, this.composer.sandbox.getDocument(), true);
|
9493
9493
|
if (typeof(htmlOrElement) === "object") {
|
@@ -9495,7 +9495,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9495
9495
|
}
|
9496
9496
|
return returnValue;
|
9497
9497
|
},
|
9498
|
-
|
9498
|
+
|
9499
9499
|
/**
|
9500
9500
|
* Prepare html parser logic
|
9501
9501
|
* - Observes for paste and drop
|
@@ -9509,7 +9509,7 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9509
9509
|
that.parse(that.composer.element);
|
9510
9510
|
}, keepScrollPosition);
|
9511
9511
|
});
|
9512
|
-
|
9512
|
+
|
9513
9513
|
this.observe("paste:textarea", function() {
|
9514
9514
|
var value = this.textarea.getValue(),
|
9515
9515
|
newValue;
|
@@ -9518,4 +9518,4 @@ wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
|
9518
9518
|
});
|
9519
9519
|
}
|
9520
9520
|
});
|
9521
|
-
})(wysihtml5);
|
9521
|
+
})(wysihtml5);
|