Comparing version 1.5.2 to 2.0.0-beta1
@@ -0,1 +1,73 @@ | ||
Version 2.0.0: | ||
Changed theme to use flexbox. Custom themes will need tweaking but otherwise | ||
this is backwards compatible. | ||
Updated pasting to normalize image pasting across browsers to paste images | ||
as Data URIs. | ||
Updated pasting to use clipboard API which stops the ugly flash caused by | ||
clearing the editor when paste filtering was enabled. As IE & Edge lack | ||
clipboard API support they still use the old behaviour. | ||
Added paste hooks for plugins. | ||
Fixed bug with tabs being stripped when switching between WYSIWYG and | ||
source mode. | ||
- Thanks to @spuds for reporting | ||
Fixed bug where emoticons that are subsets of others may prevent the longer | ||
key from being replaced when switching between WYSIWYG and source mode. | ||
- Thanks to @margarett for reporting | ||
Fixed issue with jQuery noConflict mode. | ||
- Thanks to @Globulopolis for reporting | ||
Changed from JSCS and JSHint to ESLint for linting | ||
Dropped support for IE <= 9 | ||
Updated default color palette to be smaller and increased color picker size. | ||
Added autoyoutube plugin that converts pasted Youtube links. | ||
- Thanks to @cyphix333 for suggesting | ||
Updated XHTML plugin to not remove tag with a size from style/class attribtue. | ||
- Thanks to @timint | ||
Fixed bug with XHTML plugin removing empty <td> tags. | ||
- Thanks to @derplakatankleber for reporting | ||
Added allowedEmptyTags to XHTML plugin. | ||
Fixed bug with BBCode plugin where email shows a second prompt even when the | ||
first is cancelled. | ||
- Thanks to @OlafvdSpek for reporting. | ||
Updated link dropdown to insert when enter is pressed. | ||
- Thanks to @q2apro for reporting | ||
Updated rangeHelper.replaceKeyword() to match start of lines when whitespace | ||
is required. Enables AYT emoticon conversion to convert emoticons at the | ||
start of lines. | ||
- Thanks to @barbuslex for reporting. | ||
Added plaintext plugin to remove formatting on paste. | ||
Fixed bug with FF lists adding extra lines. | ||
- Thanks to @OmarHawk for reporting | ||
Fixed bug with nested lists creating invalid BBCode and HTML. | ||
- Thanks to @naturalgeek for reporting | ||
Fixed bug with auto expand when maximised. | ||
- Thanks to @mjau-mjau for reporting. | ||
Improved autoexpand to shrink when content reduces. | ||
- Thanks to @Somnium7 for reporting. | ||
Added Indonesian translation. | ||
- Thanks to @sndbckt for translating. | ||
Switched to using ES6 modules. | ||
Fixed bug with cursor being placed in wrong position on first focus. | ||
- Thanks to @q2apro for reporting. | ||
Fixed BBCode parser bug with BBCodes opened or closed inside a tag which | ||
doesn't allow them as children (e.g. anything in [code] tags). | ||
- Thanks to @emanuele45 for reporting. | ||
Fixed whitespace edge case causing extra lines to be added in BBCode. | ||
- Thanks to @OmarHawk for reporting. | ||
Fixed issue placing cursor after custom block nodes. | ||
- Thanks to @cyphix333 for reporting. | ||
Improved editor to make sure inlines are wrapped in <p> tags. | ||
- Thanks to @q2apro for reporting. | ||
Prevent valueChanged event during composition. | ||
- Thanks to @martec for reporting. | ||
Update URL place holders to https:// from http:// | ||
- Thanks to @MyBB-Andro for reporting. | ||
Improved pasting and enabled paste filtering by default [can it be turned off?] | ||
Converted BBCode and XHTML plugins into formats | ||
Fixed issue with default emotions always being added. | ||
- Thanks to @compojoom for reporting | ||
Update famfamfam icons to have red text for super/subscript. | ||
- Thanks to @q2apro for updating | ||
Added support for SVG icon sets | ||
Moved jquery.sceditor.default.css to themes/content/default.css | ||
Version 1.5.2: | ||
@@ -2,0 +74,0 @@ Fixed BBCode parser bug that can cause content to be lost under certain |
@@ -0,0 +0,0 @@ Presenting, Nomicons: The Full Monty :o |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['ar'] = { | ||
sceditor.locale['ar'] = { | ||
'Bold': 'عريض', | ||
@@ -69,2 +69,2 @@ 'Italic': 'مائل', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['ca'] = { | ||
sceditor.locale['ca'] = { | ||
'Bold': 'Negrita', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Cursiva', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['cn'] = { | ||
sceditor.locale['cn'] = { | ||
'Bold': '粗体', | ||
@@ -69,2 +69,2 @@ 'Italic': '斜体', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['cs'] = { | ||
sceditor.locale['cs'] = { | ||
'Bold': 'Tučné', | ||
@@ -64,3 +64,3 @@ 'Italic': 'Kurzíva', | ||
'Enter the YouTube video URL or ID:': 'Vložte adresu YouTube videa nebo ID videa', | ||
'Insert a Quote':'Vložit citát', | ||
'Insert a Quote': 'Vložit citát', | ||
'Invalid YouTube video': 'Neplatné YouTube video', | ||
@@ -73,2 +73,2 @@ 'Add indent': 'Posunout na další úroveň', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['de'] = { | ||
sceditor.locale['de'] = { | ||
'Bold': 'Fett', | ||
@@ -59,2 +59,2 @@ 'Italic': 'Kursiv', | ||
}; | ||
})(jQuery); | ||
})(); |
/** | ||
* @author Nikos Aggelis nikosaggelis@hotmail.gr | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['el'] = { | ||
sceditor.locale['el'] = { | ||
'Bold': 'Έντονα', | ||
@@ -68,2 +68,2 @@ 'Italic': 'Πλάγια', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,7 +0,7 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['en-US'] = { | ||
sceditor.locale['en-US'] = { | ||
dateFormat: 'month/day/year' | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['en-GB'] = { | ||
sceditor.locale['en-GB'] = { | ||
'Font Color': 'Font Colour', | ||
@@ -11,3 +11,3 @@ 'Center': 'Centre', | ||
// set this as the default English locale | ||
$.sceditor.locale['en'] = $.sceditor.locale['en-GB']; | ||
})(jQuery); | ||
sceditor.locale['en'] = sceditor.locale['en-GB']; | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['es'] = { | ||
sceditor.locale['es'] = { | ||
'Bold': 'Negrita', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Cursiva', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['et'] = { | ||
sceditor.locale['et'] = { | ||
'Bold': 'Rasvane', | ||
@@ -57,2 +57,2 @@ 'Italic': 'Kaldkiri', | ||
}; | ||
})(jQuery); | ||
})(); |
// add locale:'fa', to your config options. | ||
// Translated By Ebad Ghafoory [info@ghafoory.com] | ||
// 2013/05/01 | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['fa'] = { | ||
sceditor.locale['fa'] = { | ||
'Bold': 'تیره', | ||
@@ -69,2 +69,2 @@ 'Italic': 'مورب', | ||
}; | ||
})(jQuery); | ||
})(); |
// add locale:'fr', to your config options. | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['fr-FR'] = { | ||
sceditor.locale['fr-FR'] = { | ||
'Bold': 'Gras', | ||
@@ -69,3 +69,3 @@ 'Italic': 'Italique', | ||
}; | ||
$.sceditor.locale['fr'] = $.sceditor.locale['fr-FR']; | ||
})(jQuery); | ||
sceditor.locale['fr'] = sceditor.locale['fr-FR']; | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['gl'] = { | ||
sceditor.locale['gl'] = { | ||
'Bold': 'Negrita', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Cursiva', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -6,6 +6,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['hu'] = { | ||
sceditor.locale['hu'] = { | ||
'Bold': 'Félkövér', | ||
@@ -70,2 +70,2 @@ 'Italic': 'Dőlt', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -6,6 +6,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['it-IT'] = { | ||
sceditor.locale['it-IT'] = { | ||
'Bold': 'Grassetto', | ||
@@ -72,3 +72,3 @@ 'Italic': 'Corsivo', | ||
// Set as the default Italian locale | ||
$.sceditor.locale['it'] = $.sceditor.locale['it-IT']; | ||
})(jQuery); | ||
sceditor.locale['it'] = sceditor.locale['it-IT']; | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['ja'] = { | ||
sceditor.locale['ja'] = { | ||
'Bold': '太字', | ||
@@ -72,2 +72,2 @@ 'Italic': '斜字', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['lt'] = { | ||
sceditor.locale['lt'] = { | ||
'Bold': 'Paryškintas', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Pasvirasis', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['nb-NO'] = { | ||
sceditor.locale['nb-NO'] = { | ||
'Bold': 'Fet', | ||
@@ -70,3 +70,3 @@ 'Italic': 'Kursiv', | ||
$.sceditor.locale['nb'] = $.sceditor.locale['nb-NO']; | ||
})(jQuery); | ||
sceditor.locale['nb'] = sceditor.locale['nb-NO']; | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['nl'] = { | ||
sceditor.locale['nl'] = { | ||
'Bold': 'Vet', | ||
@@ -57,2 +57,2 @@ 'Italic': 'Schuingedrukt', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['pl'] = { | ||
sceditor.locale['pl'] = { | ||
'Bold': 'Pogrubienie', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Kursywa', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['pt-BR'] = { | ||
sceditor.locale['pt-BR'] = { | ||
'Bold': 'Negrito', | ||
@@ -68,2 +68,2 @@ 'Italic': 'Itálico', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['pt-PT'] = { | ||
sceditor.locale['pt-PT'] = { | ||
'Bold': 'Negrito', | ||
@@ -69,3 +69,3 @@ 'Italic': 'Itálico', | ||
// Set as the default Portuguese locale | ||
$.sceditor.locale['pt'] = $.sceditor.locale['pt-PT']; | ||
})(jQuery); | ||
sceditor.locale['pt'] = sceditor.locale['pt-PT']; | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['ru'] = { | ||
sceditor.locale['ru'] = { | ||
'Bold': 'Жирный', | ||
@@ -57,2 +57,2 @@ 'Italic': 'Курсив', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['sv-SE'] = { | ||
sceditor.locale['sv-SE'] = { | ||
'Bold': 'Fet', | ||
@@ -57,3 +57,3 @@ 'Italic': 'Kursiv', | ||
$.sceditor.locale['sv'] = $.sceditor.locale['sv-SE']; | ||
})(jQuery); | ||
sceditor.locale['sv'] = sceditor.locale['sv-SE']; | ||
})(); |
@@ -5,7 +5,7 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
// Replace <code> with the language code, e.g. no, fr, en, ect. | ||
$.sceditor.locale['<code>'] = { | ||
sceditor.locale['<code>'] = { | ||
@@ -70,7 +70,8 @@ // Original string is on the left, place the translation between | ||
'Invalid YouTube video': '', | ||
'Drop files here': '', | ||
// month format, replace - with the date format seperator and order in the | ||
// month format, replace - with the date format separator and order in the | ||
// order used | ||
dateFormat: 'day-month-year' | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,5 +5,5 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['tr'] = { | ||
sceditor.locale['tr'] = { | ||
'Bold': 'Kalın', | ||
@@ -67,2 +67,2 @@ 'Italic': 'İtalik', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['tw'] = { | ||
sceditor.locale['tw'] = { | ||
'Bold': '粗體', | ||
@@ -69,2 +69,2 @@ 'Italic': '斜體', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['uk'] = { | ||
sceditor.locale['uk'] = { | ||
'Bold': 'Жирний', | ||
@@ -57,2 +57,2 @@ 'Italic': 'Курсив', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -5,6 +5,6 @@ /** | ||
*/ | ||
(function ($) { | ||
(function () { | ||
'use strict'; | ||
$.sceditor.locale['vi'] = { | ||
sceditor.locale['vi'] = { | ||
'Bold': 'Đậm', | ||
@@ -69,2 +69,2 @@ 'Italic': 'Nghiêng', | ||
}; | ||
})(jQuery); | ||
})(); |
@@ -1,3 +0,3 @@ | ||
/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ | ||
!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(2),e=c(3),f=c(6),g=c(7);b.sceditor=d,d.commands=c(9),d.defaultOptions=c(10),d.RangeHelper=c(4),d.dom=c(5),d.ie=f.ie,d.ios=f.ios,d.isWysiwygSupported=f.isWysiwygSupported,d.regexEscape=g.regex,d.escapeEntities=g.entities,d.escapeUriScheme=g.uriScheme,d.PluginManager=e,d.plugins=e.plugins,b.fn.sceditor=function(a){var c,e,g=[];if(a=a||{},a.runWithoutWysiwygSupport||f.isWysiwygSupported)return this.each(function(){c=this.jquery?this:b(this),e=c.data("sceditor"),c.parents(".sceditor-container").length>0||("state"===a?g.push(!!e):"instance"===a?g.push(e):e||new d(this,a))}),g.length?1===g.length?g[0]:b(g):this}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports=jQuery},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(3),e=c(4),f=c(5),g=c(7),h=c(6),i=c(8),j=window,k=document,l=b(j),m=b(k),n=h.ie,o=n&&n<11,p=function(a,c){var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua=this,va=a.get?a.get(0):a,wa=b(va),xa=[],ya=[],za=[],Aa={},Ba=[],Ca={};ua.commands=b.extend(!0,{},c.commands||p.commands),ua.opts=c=b.extend({},p.defaultOptions,c),K=function(){wa.data("sceditor",ua),b.each(c,function(a,d){b.isPlainObject(d)&&(c[a]=b.extend(!0,{},d))}),c.locale&&"en"!==c.locale&&Q(),q=b('<div class="sceditor-container" />').insertAfter(wa).css("z-index",c.zIndex),n&&q.addClass("ie ie"+n),H=!!wa.attr("required"),wa.removeAttr("required"),P(),W(),R(),O(!!c.startInSourceMode),U(),S(),T(),h.isWysiwygSupported||ua.toggleSourceMode(),ha();var a=function(){l.off("load",a),c.autofocus&&ma(),c.autoExpand&&ua.expandToContent(),fa(),C.call("ready")};l.on("load",a),k.readyState&&"complete"===k.readyState&&a()},P=function(){var a=c.plugins;a=a?a.toString().split(","):[],C=new d(ua),b.each(a,function(a,c){C.register(b.trim(c))})},Q=function(){var a;A=p.locale[c.locale],A||(a=c.locale.split("-"),A=p.locale[a[0]]),A&&A.dateFormat&&(c.dateFormat=A.dateFormat)},O=function(a){var d,f;w=b("<textarea></textarea>"),s=b('<iframe frameborder="0" allowfullscreen="true"></iframe>'),a?(q.addClass("sourceMode"),s.hide()):(q.addClass("wysiwygMode"),w.hide()),c.spellcheck||w.attr("spellcheck","false"),"https:"===j.location.protocol&&s.attr("src","javascript:false"),q.append(s).append(w),t=s[0],x=w[0],ua.dimensions(c.width||wa.width(),c.height||wa.height()),d=X(),d.open(),d.write(i("html",{attrs:n?' class="ie ie'+n+'"':"",spellcheck:c.spellcheck?"":'spellcheck="false"',charset:c.charset,style:c.style})),d.close(),v=b(d),u=b(d.body),ua.readOnly(!!c.readOnly),(h.ios||n)&&(u.height("100%"),n||u.on("touchend",ua.focus)),f=wa.attr("tabindex"),w.attr("tabindex",f),s.attr("tabindex",f),B=new e(t.contentWindow),ua.val(wa.hide().val())},S=function(){c.autoUpdate&&(u.on("blur",ta),w.on("blur",ta)),null===c.rtl&&(c.rtl="rtl"===w.css("direction")),ua.rtl(!!c.rtl),c.autoExpand&&v.on("keyup",ua.expandToContent),c.resizeEnabled&&V(),q.attr("id",c.id),ua.emoticons(c.emoticonsEnabled)},T=function(){var a=n?"selectionchange":"keyup focus blur contextmenu mouseup touchend click",d="keydown keyup keypress focus blur contextmenu";m.click(ea),b(va.form).on("reset",ba).submit(ua.updateOriginal),l.on("resize orientationChanged",fa),u.keypress(aa).keydown($).keydown(_).keyup(ja).blur(ra).keyup(sa).on("paste",Y).on(a,ka).on(d,da),c.emoticonsCompat&&j.getSelection&&u.keyup(oa),w.blur(ra).keyup(sa).keydown($).on(d,da),v.mousedown(ca).blur(ra).on(a,ka).on("beforedeactivate keyup mouseup",N).keyup(ja).focus(function(){z=null}),q.on("selectionchanged",la).on("selectionchanged",ha).on("selectionchanged valuechanged nodechanged",da)},R=function(){var a,d=ua.commands,e=(c.toolbarExclude||"").split(","),f=c.toolbar.split("|");r=b('<div class="sceditor-toolbar" unselectable="on" />'),b.each(f,function(c,f){a=b('<div class="sceditor-group" />'),b.each(f.split(","),function(c,f){var g,h,j=d[f];!j||b.inArray(f,e)>-1||(h=j.shortcut,g=i("toolbarButton",{name:f,dispName:ua._(j.name||j.tooltip||f)},!0),g.data("sceditor-txtmode",!!j.txtExec).data("sceditor-wysiwygmode",!!j.exec).toggleClass("disabled",!j.exec).mousedown(function(){(!n||n<9)&&(J=!0)}).click(function(){var a=b(this);return a.hasClass("disabled")||M(a,j),ha(),!1}),j.tooltip&&g.attr("title",ua._(j.tooltip)+(h?" ("+h+")":"")),h&&ua.addShortcut(h,f),j.state?za.push({name:f,state:j.state}):"string"==typeof j.exec&&za.push({name:f,state:j.exec}),a.append(g),Ca[f]=g)}),a[0].firstChild&&r.append(a)}),b(c.toolbarContainer||q).append(r)},U=function(){b.each(ua.commands,function(a,c){c.forceNewLineAfter&&b.isArray(c.forceNewLineAfter)&&(ya=b.merge(ya,c.forceNewLineAfter))}),ja()},V=function(){var a,d,e,f,g,h,i=b('<div class="sceditor-grip" />'),k=b('<div class="sceditor-resize-cover" />'),l="touchmove mousemove",o="touchcancel touchend mouseup",p=0,r=0,s=0,t=0,u=0,v=0,w=q.width(),x=q.height(),y=!1,z=ua.rtl();a=c.resizeMinHeight||x/1.5,d=c.resizeMaxHeight||2.5*x,e=c.resizeMinWidth||w/1.25,f=c.resizeMaxWidth||1.25*w,g=function(b){"touchmove"===b.type?(b=j.event,s=b.changedTouches[0].pageX,t=b.changedTouches[0].pageY):(s=b.pageX,t=b.pageY);var g=v+(t-r),h=z?u-(s-p):u+(s-p);f>0&&h>f&&(h=f),e>0&&h<e&&(h=e),c.resizeWidth||(h=!1),d>0&&g>d&&(g=d),a>0&&g<a&&(g=a),c.resizeHeight||(g=!1),(h||g)&&(ua.dimensions(h,g),n<7&&q.height(g)),b.preventDefault()},h=function(a){y&&(y=!1,k.hide(),q.removeClass("resizing").height("auto"),m.off(l,g),m.off(o,h),a.preventDefault())},q.append(i),q.append(k.hide()),i.on("touchstart mousedown",function(a){"touchstart"===a.type?(a=j.event,p=a.touches[0].pageX,r=a.touches[0].pageY):(p=a.pageX,r=a.pageY),u=q.width(),v=q.height(),y=!0,q.addClass("resizing"),k.show(),m.on(l,g),m.on(o,h),n<7&&q.height(v),a.preventDefault()})},W=function(){var a,d=c.emoticons,e=c.emoticonsRoot;b.isPlainObject(d)&&c.emoticonsEnabled&&b.each(d,function(c,f){b.each(f,function(b,f){e&&(f={url:e+(f.url||f),tooltip:f.tooltip||b},d[c][b]=f),a=k.createElement("img"),a.src=f.url||f,xa.push(a)})})},ma=function(){var a,d,e=v[0],g=u[0],h=g.firstChild,i=!!c.autofocusEnd;if(q.is(":visible")){if(ua.sourceMode())return d=i?x.value.length:0,void(x.setSelectionRange?x.setSelectionRange(d,d):(a=x.createTextRange(),a.moveEnd("character",d),a.collapse(!1),a.select()));if(f.removeWhiteSpace(g),i)for((h=g.lastChild)||(h=e.createElement("p"),u.append(h));h.lastChild;)h=h.lastChild,!o&&b(h).is("br")&&h.previousSibling&&(h=h.previousSibling);e.createRange?(a=e.createRange(),f.canHaveChildren(h)?a.selectNodeContents(h):(a.setStartBefore(h),i&&a.setStartAfter(h))):(a=g.createTextRange(),a.moveToElementText(3!==h.nodeType?h:h.parentNode)),a.collapse(!i),B.selectRange(a),F=a,i&&(v.scrollTop(g.scrollHeight),u.scrollTop(g.scrollHeight)),ua.focus()}},ua.readOnly=function(a){return"boolean"!=typeof a?"readonly"===w.attr("readonly"):(u[0].contentEditable=!a,a?w.attr("readonly","readonly"):w.removeAttr("readonly"),ga(a),ua)},ua.rtl=function(a){var b=a?"rtl":"ltr";return"boolean"!=typeof a?"rtl"===w.attr("dir"):(u.attr("dir",b),w.attr("dir",b),q.removeClass("rtl").removeClass("ltr").addClass(b),ua)},ga=function(a){var c=ua.inSourceMode()?"txtmode":"wysiwygmode";b.each(Ca,function(b,d){a!==!0&&d.data("sceditor-"+c)?d.removeClass("disabled"):d.addClass("disabled")})},ua.width=function(a,b){return a||0===a?(ua.dimensions(a,null,b),ua):q.width()},ua.dimensions=function(a,b,d){var e,f=n<8||k.documentMode<8?2:0;return a=!(!a&&0!==a)&&a,b=!(!b&&0!==b)&&b,a===!1&&b===!1?{width:ua.width(),height:ua.height()}:(s.data("outerWidthOffset")===e&&ua.updateStyleCache(),a!==!1&&(d!==!1&&(c.width=a),b===!1&&(b=q.height(),d=!1),q.width(a),a&&a.toString().indexOf("%")>-1&&(a=q.width()),s.width(a-s.data("outerWidthOffset")),w.width(a-w.data("outerWidthOffset")),h.ios&&u&&u.width(a-s.data("outerWidthOffset")-(u.outerWidth(!0)-u.width()))),b!==!1&&(d!==!1&&(c.height=b),b&&b.toString().indexOf("%")>-1&&(b=q.height(b).height(),q.height("auto")),b-=c.toolbarContainer?0:r.outerHeight(!0),s.height(b-s.data("outerHeightOffset")),w.height(b-f-w.data("outerHeightOffset"))),ua)},ua.updateStyleCache=function(){s.data("outerWidthOffset",s.outerWidth(!0)-s.width()),w.data("outerWidthOffset",w.outerWidth(!0)-w.width()),s.data("outerHeightOffset",s.outerHeight(!0)-s.height()),w.data("outerHeightOffset",w.outerHeight(!0)-w.height())},ua.height=function(a,b){return a||0===a?(ua.dimensions(null,a,b),ua):q.height()},ua.maximize=function(a){return"undefined"==typeof a?q.is(".sceditor-maximize"):(a=!!a,n<7&&b("html, body").toggleClass("sceditor-maximize",a),q.toggleClass("sceditor-maximize",a),ua.width(a?"100%":c.width,!1),ua.height(a?"100%":c.height,!1),ua)},ua.expandToContent=function(a){var b=q.height(),d=b-s.height(),e=u[0].scrollHeight||v[0].documentElement.scrollHeight,f=c.resizeMaxHeight||2*(c.height||wa.height());e+=d,(a===!0||e<=f)&&e>b&&ua.height(e)},ua.destroy=function(){C&&(C.destroy(),B=null,z=null,C=null,y&&y.off().remove(),m.off("click",ea),l.off("resize orientationChanged",fa),b(va.form).off("reset",ba).off("submit",ua.updateOriginal),u.off(),v.off().find("*").remove(),w.off().remove(),r.remove(),q.off().find("*").off().remove(),q.remove(),wa.removeData("sceditor").removeData("sceditorbbcode").show(),H&&wa.attr("required","required"))},ua.createDropDown=function(a,d,e,f){var g,h="sceditor-"+d,i=y&&y.is("."+h);ua.closeDropDown(!0),i||(f!==!1&&b(e).find(":not(input,textarea)").filter(function(){return 1===this.nodeType}).attr("unselectable","on"),g={top:a.offset().top,left:a.offset().left,marginTop:a.outerHeight()},b.extend(g,c.dropDownCss),y=b('<div class="sceditor-dropdown '+h+'" />').css(g).append(e).appendTo(b("body")).on("click focusin",function(a){a.stopPropagation()}),setTimeout(function(){y&&y.find("input,textarea").first().focus()}))},ea=function(a){3!==a.which&&y&&(ta(),ua.closeDropDown())},Y=function(a){var b,d,e,f=u[0],g=v[0],h=0,i=k.createElement("div"),j=g.createDocumentFragment(),l=!!a&&a.clipboardData;if(c.disablePasting)return!1;if(c.enablePasteFiltering){if(B.saveRange(),k.body.appendChild(i),l&&l.getData&&((b=l.getData("text/html"))||(b=l.getData("text/plain"))))return i.innerHTML=b,Z(f,i),!1;for(e=u.scrollTop()||v.scrollTop();f.firstChild;)j.appendChild(f.firstChild);return d=function(a,b){if(a.childNodes.length>0||h>25){for(;a.firstChild;)b.appendChild(a.firstChild);for(;j.firstChild;)a.appendChild(j.firstChild);u.scrollTop(e),v.scrollTop(e),b.childNodes.length>0?Z(a,b):B.restoreRange()}else h++,setTimeout(function(){d(a,b)},20)},d(f,i),ua.focus(),!0}},Z=function(a,c){f.fixNesting(c);var d=c.innerHTML;C.hasHandler("toSource")&&(d=C.callOnlyFirst("toSource",d,b(c))),c.parentNode.removeChild(c),C.hasHandler("toWysiwyg")&&(d=C.callOnlyFirst("toWysiwyg",d,!0)),B.restoreRange(),ua.wysiwygEditorInsertHtml(d,null,!0)},ua.closeDropDown=function(a){y&&(y.off().remove(),y=null),a===!0&&ua.focus()},X=function(){return t.contentDocument?t.contentDocument:t.contentWindow&&t.contentWindow.document?t.contentWindow.document:t.document},ua.wysiwygEditorInsertHtml=function(a,c,d){var e,g,h,i=s.height();ua.focus(),(d||!b(E).is("code")&&0===b(E).parents("code").length)&&(B.insertHTML(a,c),B.saveRange(),L(u[0]),e=u.find("#sceditor-end-marker").show(),g=u.scrollTop()||v.scrollTop(),h=f.getOffset(e[0]).top+1.5*e.outerHeight(!0)-i,e.hide(),(h>g||h+i<g)&&(u.scrollTop(h),v.scrollTop(h)),qa(!1),B.restoreRange(),ja())},ua.wysiwygEditorInsertText=function(a,b){ua.wysiwygEditorInsertHtml(g.entities(a),g.entities(b))},ua.insertText=function(a,b){return ua.inSourceMode()?ua.sourceEditorInsertText(a,b):ua.wysiwygEditorInsertText(a,b),ua},ua.sourceEditorInsertText=function(a,b){var c,d,e,f=x.selectionStart,g=x.selectionEnd;d=x.scrollTop,x.focus(),"undefined"!=typeof f?(e=x.value,b&&(a+=e.substring(f,g)+b),x.value=e.substring(0,f)+a+e.substring(g,e.length),x.selectionStart=f+a.length-(b?b.length:0),x.selectionEnd=x.selectionStart):(c=k.selection.createRange(),b&&(a+=c.text+b),c.text=a,b&&c.moveEnd("character",0-b.length),c.moveStart("character",c.End-c.Start),c.select()),x.scrollTop=d,x.focus(),qa()},ua.getRangeHelper=function(){return B},ua.sourceEditorCaret=function(a){var b,c={};return x.focus(),"undefined"!=typeof x.selectionStart?a?(x.selectionStart=a.start,x.selectionEnd=a.end):(c.start=x.selectionStart,c.end=x.selectionEnd):(b=k.selection.createRange(),a?(b.moveEnd("character",a.end),b.moveStart("character",a.start),b.select()):(c.start=b.Start,c.end=b.End)),a?this:c},ua.val=function(a,b){return"string"!=typeof a?ua.inSourceMode()?ua.getSourceEditorValue(!1):ua.getWysiwygEditorValue(b):(ua.inSourceMode()?ua.setSourceEditorValue(a):(b!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a)),ua.setWysiwygEditorValue(a)),ua)},ua.insert=function(a,c,d,e,f){if(ua.inSourceMode())return ua.sourceEditorInsertText(a,c),ua;if(c){var g=B.selectedHtml(),h=b("<div>").appendTo(b("body")).hide().html(g);d!==!1&&C.hasHandler("toSource")&&(g=C.callOnlyFirst("toSource",g,h)),h.remove(),a+=g+c}return d!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a,!0)),d!==!1&&f===!0&&(a=a.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),ua.wysiwygEditorInsertHtml(a),ua},ua.getWysiwygEditorValue=function(a){var c,d=b("<div>").appendTo(document.body).append(b(u[0].childNodes).clone());return f.fixNesting(d[0]),c=d.html(),a!==!1&&C.hasHandler("toSource")&&(c=C.callOnlyFirst("toSource",c,d)),d.remove(),c},ua.getBody=function(){return u},ua.getContentAreaContainer=function(){return s},ua.getSourceEditorValue=function(a){var b=w.val();return a!==!1&&C.hasHandler("toWysiwyg")&&(b=C.callOnlyFirst("toWysiwyg",b)),b},ua.setWysiwygEditorValue=function(a){a||(a="<p>"+(n?"":"<br />")+"</p>"),u[0].innerHTML=a,L(u[0]),ja(),qa()},ua.setSourceEditorValue=function(a){w.val(a),qa()},ua.updateOriginal=function(){wa.val(ua.val())},L=function(a){if(c.emoticonsEnabled&&!b(a).parents("code").length){var d=a.ownerDocument,e="\\s| | | | | ",h=[],j=[],k=b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden);b.each(k,function(a){c.emoticonsCompat&&(j[a]=new RegExp("(>|^|"+e+")"+g.regex(a)+"($|<|"+e+")")),h.push(a)});var l=function(a){for(a=a.firstChild;a;){var e,g,m,n,o,p,q,r=a.parentNode,s=a.nodeValue;if(3!==a.nodeType)b(a).is("code")||l(a);else if(s)for(o=h.length;o--;)g=h[o],q=c.emoticonsCompat?s.search(j[g]):s.indexOf(g),q>-1&&(p=a.nextSibling,m=k[g],e=s.substr(q).split(g),s=s.substr(0,q)+e.shift(),a.nodeValue=s,n=f.parseHTML(i("emoticon",{key:g,url:m.url||m,tooltip:m.tooltip||g}),d),r.insertBefore(n[0],p),r.insertBefore(d.createTextNode(e.join(g)),p));a=a.nextSibling}};l(a),c.emoticonsCompat&&(Ba=u.find("img[data-sceditor-emoticon]"))}},ua.inSourceMode=function(){return q.hasClass("sourceMode")},ua.sourceMode=function(a){var b=ua.inSourceMode();return"boolean"!=typeof a?b:((b&&!a||!b&&a)&&ua.toggleSourceMode(),ua)},ua.toggleSourceMode=function(){var a=ua.inSourceMode();!h.isWysiwygSupported&&a||(a||(B.saveRange(),B.clear()),ua.blur(),a?ua.setWysiwygEditorValue(ua.getSourceEditorValue()):ua.setSourceEditorValue(ua.getWysiwygEditorValue()),z=null,w.toggle(),s.toggle(),q.toggleClass("wysiwygMode",a).toggleClass("sourceMode",!a),ga(),ha())},ia=function(){return x.focus(),"undefined"!=typeof x.selectionStart?x.value.substring(x.selectionStart,x.selectionEnd):k.selection.createRange().text},M=function(a,c){ua.inSourceMode()?c.txtExec&&(b.isArray(c.txtExec)?ua.sourceEditorInsertText.apply(ua,c.txtExec):c.txtExec.call(ua,a,ia())):c.exec&&(b.isFunction(c.exec)?c.exec.call(ua,a):ua.execCommand(c.exec,c.hasOwnProperty("execParam")?c.execParam:null))},N=function(){n&&(z=B.selectedRange())},ua.execCommand=function(a,c){var d=!1,e=ua.commands[a],f=b(B.parentNode());if(ua.focus(),!f.is("code")&&0===f.parents("code").length){try{d=v[0].execCommand(a,!1,c)}catch(a){}!d&&e&&e.errorMessage&&alert(ua._(e.errorMessage)),ha()}},ka=function(){function a(){B&&!B.compare(F)&&(F=B.cloneSelected(),q.trigger(b.Event("selectionchanged"))),G=!1}G||(G=!0,n?a():setTimeout(a,100))},la=function(){var a,c=B.parentNode();D!==c&&(a=D,D=c,E=B.getFirstBlockParent(c),q.trigger(b.Event("nodechanged",{oldNode:a,newNode:D})))},ua.currentNode=function(){return D},ua.currentBlockNode=function(){return E},ha=function(a){var b,c,d="active",e=v[0],f=ua.sourceMode();if(ua.readOnly())return void r.find(d).removeClass(d);f||(c=a?a.newNode:B.parentNode(),b=B.getFirstBlockParent(c));for(var g=0;g<za.length;g++){var h=0,i=Ca[za[g].name],j=za[g].state,k=f&&!i.data("sceditor-txtmode")||!f&&!i.data("sceditor-wysiwygmode");if("string"==typeof j){if(!f)try{h=e.queryCommandEnabled(j)?0:-1,h>-1&&(h=e.queryCommandState(j)?1:0)}catch(a){}}else k||(h=j.call(ua,c,b));i.toggleClass("disabled",k||h<0).toggleClass(d,h>0)}},aa=function(a){var c,d,e,g,h="code,blockquote,pre",i="li,ul,ol";if(!a.originalEvent.defaultPrevented)return ua.closeDropDown(),c=b(E).closest(h+","+i).first(),13===a.which&&c.length&&!c.is(i)?(z=null,d=v[0].createElement("br"),B.insertNode(d),o||(e=d.parentNode,g=e.lastChild,g&&3===g.nodeType&&""===g.nodeValue&&(e.removeChild(g),g=e.lastChild),!f.isInline(e,!0)&&g===d&&f.isInline(d.previousSibling)&&B.insertHTML("<br>")),!1):void 0},ja=function(){var a,c,d,e=u[0];f.rTraverse(e,function(g){if(a=g.nodeName.toLowerCase(),b.inArray(a,ya)>-1&&(c=!0),3===g.nodeType&&!/^\s*$/.test(g.nodeValue)||"br"===a||o&&!g.firstChild&&!f.isInline(g,!1))return c&&(d=v[0].createElement("p"),d.className="sceditor-nlf",d.innerHTML=o?"":"<br />",e.appendChild(d)),!1})},ba=function(){ua.val(wa.val())},ca=function(){ua.closeDropDown(),z=null},fa=function(){var a=c.height,b=c.width;ua.maximize()?ua.dimensions("100%","100%",!1):(a&&a.toString().indexOf("%")>-1||b&&b.toString().indexOf("%")>-1)&&ua.dimensions(b,a)},ua._=function(){var a,b=arguments;return A&&A[b[0]]&&(b[0]=A[b[0]]),b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},da=function(a){C.call(a.type+"Event",a,ua);var c=a.target===x?"scesrc":"scewys",d=b.Event(a);d.type=c+a.type,q.trigger(d,ua)},ua.bind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.on("scewys"+a[f],c),e||q.on("scesrc"+a[f],c),"valuechanged"===a[f]&&(qa.hasHandler=!0));return ua},ua.unbind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.off("scewys"+a[f],c),e||q.off("scesrc"+a[f],c));return ua},ua.blur=function(a,c,d){return b.isFunction(a)?ua.bind("blur",a,c,d):ua.sourceMode()?w.blur():u.blur(),ua},ua.focus=function(a,c,d){if(b.isFunction(a))ua.bind("focus",a,c,d);else if(ua.inSourceMode())x.focus();else{var e,f=B.selectedRange();F||B.hasSelection()||ma(),!o&&f&&1===f.endOffset&&f.collapsed&&(e=f.endContainer,e&&1===e.childNodes.length&&b(e.firstChild).is("br")&&(f.setStartBefore(e.firstChild),f.collapse(!0),B.selectRange(f))),t.contentWindow.focus(),u[0].focus(),z&&(B.selectRange(z),z=null)}return ha(),ua},ua.keyDown=function(a,b,c){return ua.bind("keydown",a,b,c)},ua.keyPress=function(a,b,c){return ua.bind("keypress",a,b,c)},ua.keyUp=function(a,b,c){return ua.bind("keyup",a,b,c)},ua.nodeChanged=function(a){return ua.bind("nodechanged",a,!1,!0)},ua.selectionChanged=function(a){return ua.bind("selectionchanged",a,!1,!0)},ua.valueChanged=function(a,b,c){return ua.bind("valuechanged",a,b,c)},na=function(a){var d,e=0,f=ua.emoticonsCache,g=String.fromCharCode(a.which);if(!b(E).is("code")&&!b(E).parents("code").length)return f||(f=[],b.each(b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden),function(a,b){f[e++]=[a,i("emoticon",{key:a,url:b.url||b,tooltip:b.tooltip||a})]}),f.sort(function(a,b){return a[0].length-b[0].length}),ua.emoticonsCache=f,ua.longestEmoticonCode=f[f.length-1][0].length),d=B.replaceKeyword(ua.emoticonsCache,!0,!0,ua.longestEmoticonCode,c.emoticonsCompat,g),d&&c.emoticonsCompat?(Ba=u.find("img[data-sceditor-emoticon]"),/^\s$/.test(g)):!d},oa=function(){if(Ba.length){var a,c,d,e,f,g,h=ua.currentBlockNode(),i=!1,j=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/;Ba=b.map(Ba,function(k){return k&&k.parentNode?b.contains(h,k)?(a=k.previousSibling,c=k.nextSibling,f=a.nodeValue,null===f&&(f=a.innerText||""),a&&j.test(a.nodeValue.slice(-1))||c&&j.test((c.nodeValue||"")[0])?(d=k.parentNode,e=B.cloneSelected(),g=e.startContainer,f+=b(k).data("sceditor-emoticon"),g===c?i=f.length+e.startOffset:g===h&&h.childNodes[e.startOffset]===c?i=f.length:g===a&&(i=e.startOffset),c&&3===c.nodeType||(c=d.insertBefore(d.ownerDocument.createTextNode(""),c)),c.insertData(0,f),d.removeChild(a),d.removeChild(k),i!==!1&&(e.setStart(c,i),e.collapse(!0),B.selectRange(e)),null):k):k:null})}},ua.emoticons=function(a){return a||a===!1?(c.emoticonsEnabled=a,a?(u.keypress(na),ua.sourceMode()||(B.saveRange(),L(u[0]),Ba=u.find("img[data-sceditor-emoticon]"),qa(!1),B.restoreRange())):(u.find("img[data-sceditor-emoticon]").replaceWith(function(){return b(this).data("sceditor-emoticon")}),Ba=[],u.off("keypress",na),qa()),ua):c.emoticonsEnabled},ua.css=function(a){return I||(I=b('<style id="#inline" />',v[0]).appendTo(v.find("head"))[0]),"string"!=typeof a?I.styleSheet?I.styleSheet.cssText:I.innerHTML:(I.styleSheet?I.styleSheet.cssText=a:I.innerHTML=a,ua)},$=function(a){var b=[],c={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},d={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},e={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},f=a.which,g=d[f]||String.fromCharCode(f).toLowerCase();if((a.ctrlKey||a.metaKey)&&b.push("ctrl"),a.altKey&&b.push("alt"),a.shiftKey&&(b.push("shift"),e[f]?g=e[f]:c[g]&&(g=c[g])),g&&(f<16||f>18)&&b.push(g),b=b.join("+"),Aa[b])return Aa[b].call(ua)},ua.addShortcut=function(a,b){return a=a.toLowerCase(),"string"==typeof b?Aa[a]=function(){return M(Ca[b],ua.commands[b]),!1}:Aa[a]=b,ua},ua.removeShortcut=function(a){return delete Aa[a.toLowerCase()],ua},_=function(a){var d,e,f,g,h;if(!c.disableBlockRemove&&8===a.which&&(g=B.selectedRange())&&(j.getSelection?(d=g.startContainer,e=g.startOffset):(d=g.parentElement(),f=v[0].selection.createRange(),f.moveToElementText(d),f.setEndPoint("EndToStart",g),e=f.text.length),0===e&&(h=pa()))){for(;d!==h;){for(;d.previousSibling;)if(d=d.previousSibling,3!==d.nodeType||d.nodeValue)return;if(!(d=d.parentNode))return}if(h&&!b(h).is("body"))return ua.clearBlockFormatting(h),!1}},pa=function(){for(var a=E;!f.hasStyling(a)||f.isInline(a,!0);)if(!(a=a.parentNode)||b(a).is("body"))return;return a},ua.clearBlockFormatting=function(a){return a=a||pa(),!a||b(a).is("body")?ua:(B.saveRange(),a.className="",z=null,b(a).attr("style",""),b(a).is("p,div,td")||f.convertElement(a,"p"),B.restoreRange(),ua)},qa=function(a){if(C&&(C.hasHandler("valuechangedEvent")||qa.hasHandler)){var c,d=ua.sourceMode(),e=!d&&B.hasSelection();a=a!==!1&&!v[0].getElementById("sceditor-start-marker"),sa.timer&&(clearTimeout(sa.timer),sa.timer=!1),e&&a&&B.saveRange(),c=d?w.val():u.html(),c!==qa.lastHtmlValue&&(qa.lastHtmlValue=c,q.trigger(b.Event("valuechanged",{rawValue:d?ua.val():c}))),e&&a&&B.removeMarkers()}},ra=function(){sa.timer&&qa()},sa=function(a){var b=a.which,c=sa.lastChar,d=13===c||32===c,e=8===c||46===c;sa.lastChar=b,13===b||32===b?d?sa.triggerNextChar=!0:qa():8===b||46===b?e?sa.triggerNextChar=!0:qa():sa.triggerNextChar&&(qa(),sa.triggerNextChar=!1),sa.timer&&clearTimeout(sa.timer),sa.timer=setTimeout(function(){qa()},1500)},ta=function(){J||ua.updateOriginal(),J=!1},K()};return p.locale={},p.command={get:function(a){return p.commands[a]||null},set:function(a,c){return!(!a||!c)&&(c=b.extend(p.commands[a]||{},c),c.remove=function(){p.command.remove(a)},p.commands[a]=c,this)},remove:function(a){return p.commands[a]&&delete p.commands[a],this}},p}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={},b=function(b){var c=this,d=[],e=function(a){return"signal"+a.charAt(0).toUpperCase()+a.slice(1)},f=function(a,c){a=[].slice.call(a);var f,g,h=e(a.shift());for(f=0;f<d.length;f++)if(h in d[f]&&(g=d[f][h].apply(b,a),c))return g};c.call=function(){f(arguments,!1)},c.callOnlyFirst=function(){return f(arguments,!0)},c.hasHandler=function(a){var b=d.length;for(a=e(a);b--;)if(a in d[b])return!0;return!1},c.exists=function(b){return b in a&&(b=a[b],"function"==typeof b&&"object"==typeof b.prototype)},c.isRegistered=function(b){if(c.exists(b))for(var e=d.length;e--;)if(d[e]instanceof a[b])return!0;return!1},c.register=function(e){return!(!c.exists(e)||c.isRegistered(e))&&(e=new a[e],d.push(e),"init"in e&&e.init.call(b),!0)},c.deregister=function(e){var f,g=d.length,h=!1;if(!c.isRegistered(e))return h;for(;g--;)d[g]instanceof a[e]&&(f=d.splice(g,1)[0],h=!0,"destroy"in f&&f.destroy.call(b));return h},c.destroy=function(){for(var a=d.length;a--;)"destroy"in d[a]&&d[a].destroy.call(b);d=[],b=null}};return b.plugins=a,b}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(5),e=c(7),f=c(6),g=f.ie,h=g&&g<11,i=function(a){return b("<p>",a.ownerDocument).append(a).html()},j=function(a,b,c){var d,e,f,g,h,i="",j=a.startContainer,k=a.startOffset;for(j&&3!==j.nodeType&&(j=j.childNodes[k],k=0),f=g=k;c>i.length&&j&&3===j.nodeType;)d=j.nodeValue,e=c-i.length,h&&(g=d.length,f=0),h=j,b?(f=Math.max(g-e,0),k=f,i=d.substr(f,g-f)+i,j=h.previousSibling):(g=Math.min(e,d.length),k=f+g,i+=d.substr(f,g),j=h.nextSibling);return{node:h||j,offset:k,text:i}},k=function(a,c){var f,k,l,m=c||a.contentDocument||a.document,n=a,o=!!a.getSelection,p="sceditor-start-marker",q="sceditor-end-marker",r="character",s=this;s.insertHTML=function(a,b){var c,d,e=s.selectedRange();if(!e)return!1;if(o){for(b&&(a+=s.selectedHtml()+b),d=m.createElement("p"),c=m.createDocumentFragment(),d.innerHTML=a;d.firstChild;)c.appendChild(d.firstChild);s.insertNode(c)}else e.pasteHTML(l(a,b,!0)),s.restoreRange()},l=function(a,c,e){var h,i,j=m.createElement("div"),k=b(j);if("string"==typeof a?(c&&(a+=s.selectedHtml()+c),k.html(a)):(k.append(a),c&&k.append(s.selectedRange().extractContents()).append(c)),h=j.lastChild){for(;!d.isInline(h.lastChild,!0);)h=h.lastChild;return d.canHaveChildren(h)&&(i=b(h),h.lastChild||i.append("")),g&&g<9&&b(h).is("img")&&k.append(""),s.removeMarkers(),(i||k).append(f(p)).append(f(q)),e?k.html():b(m.createDocumentFragment()).append(k.contents())[0]}},s.insertNode=function(a,b){if(o){var c=l(a,b),e=s.selectedRange(),f=e.commonAncestorContainer;if(!c)return!1;e.deleteContents(),f&&3!==f.nodeType&&!d.canHaveChildren(f)?f.parentNode.insertBefore(c,f):e.insertNode(c),s.restoreRange()}else s.insertHTML(i(a),b?i(b):null)},s.cloneSelected=function(){var a=s.selectedRange();if(a)return o?a.cloneRange():a.duplicate()},s.selectedRange=function(){var a,b,c=o?n.getSelection():m.selection;if(c){if(c.getRangeAt&&c.rangeCount<=0){for(b=m.body;b.firstChild;)b=b.firstChild;a=m.createRange(),a.setStartBefore(b),c.addRange(a)}return o&&c.rangeCount>0&&(a=c.getRangeAt(0)),o||"Control"===c.type||(a=c.createRange()),k(a)?a:null}},k=function(a){var b;return a&&!o&&(b=a.parentElement()),!b||b.ownerDocument===m},s.hasSelection=function(){var a=o?n.getSelection():m.selection;return o||!a?a&&a.rangeCount>0:"None"!==a.type&&k(a.createRange())},s.selectedHtml=function(){var a,b=s.selectedRange();if(b){if(o)return a=m.createElement("p"),a.appendChild(b.cloneContents()),a.innerHTML;if(""!==b.text&&b.htmlText)return b.htmlText}return""},s.parentNode=function(){var a=s.selectedRange();if(a)return a.parentElement?a.parentElement():a.commonAncestorContainer},s.getFirstBlockParent=function(a){var b=function(a){return d.isInline(a,!0)?(a=a?a.parentNode:null,a?b(a):a):a};return b(a||s.parentNode())},s.insertNodeAt=function(a,b){var c=s.selectedRange(),d=s.cloneSelected();return!!d&&(d.collapse(a),o?d.insertNode(b):d.pasteHTML(i(b)),void s.selectRange(c))},f=function(a){s.removeMarker(a);var b=m.createElement("span");return b.id=a,b.style.lineHeight="0",b.style.display="none",b.className="sceditor-selection sceditor-ignore",b.innerHTML=" ",b},s.insertMarkers=function(){s.insertNodeAt(!0,f(p)),s.insertNodeAt(!1,f(q))},s.getMarker=function(a){return m.getElementById(a)},s.removeMarker=function(a){var b=s.getMarker(a);b&&b.parentNode.removeChild(b)},s.removeMarkers=function(){s.removeMarker(p),s.removeMarker(q)},s.saveRange=function(){s.insertMarkers()},s.selectRange=function(a){if(o){var c,e=n.getSelection(),f=a.endContainer;if(!h&&a.collapsed&&f&&!d.isInline(f,!0)){for(c=f.lastChild;c&&b(c).is(".sceditor-ignore");)c=c.previousSibling;if(b(c).is("br")){var g=m.createRange();g.setEndAfter(c),g.collapse(!1),s.compare(a,g)&&(a.setStartBefore(c),a.collapse(!0))}}e&&(s.clear(),e.addRange(a))}else a.select()},s.restoreRange=function(){var a,c,e,f=s.selectedRange(),g=s.getMarker(p),h=s.getMarker(q);return!!(g&&h&&f)&&(c=g.nextSibling===h,o?(f=m.createRange(),f.setStartBefore(g),f.setEndAfter(h)):(f=m.body.createTextRange(),a=m.body.createTextRange(),e=g.previousSibling,g.nextSibling!==h||e&&d.isInline(e,!0)&&!b(e).is("br")||b(g).before(""),a.moveToElementText(g),f.setEndPoint("StartToStart",a),f.moveStart(r,0),a.moveToElementText(h),f.setEndPoint("EndToStart",a),f.moveEnd(r,0)),c&&f.collapse(!0),s.selectRange(f),void s.removeMarkers())},s.selectOuterText=function(a,b){var c,d,e=s.cloneSelected();return!!e&&(e.collapse(!1),o?(c=j(e,!0,a),d=j(e,!1,b),e.setStart(c.node,c.offset),e.setEnd(d.node,d.offset)):(e.moveStart(r,0-a),e.moveEnd(r,b)),void s.selectRange(e))},s.getOuterText=function(a,b){var c=s.cloneSelected();return c?(c.collapse(!a),o?j(c,a,b).text:(a?c.moveStart(r,0-b):c.moveEnd(r,b),c.text)):""},s.replaceKeyword=function(a,b,c,d,f,g){c||a.sort(function(a,b){return a[0].length-b[0].length});var h,i,j,k,l,m,n,p="[\\s ]",q=a.length,r=f?1:0,t=d||a[q-1][0].length;if(f){if(!o)return!1;t++}for(g=g||"",h=s.getOuterText(!0,t),k=h.length,h+=g,b&&(h+=s.getOuterText(!1,t));q--;)if(m=a[q][0],n=m.length,j=Math.max(0,k-n-r),i=f?h.substr(j).search(new RegExp("(?:"+p+")"+e.regex(m)+"(?="+p+")")):h.indexOf(m,j),i>-1&&(f&&(i+=j+1),i<=k&&i+n+r>=k))return l=k-i,s.selectOuterText(l,n-l-(/^\S/.test(g)?1:0)),s.insertHTML(a[q][1]),!0;return!1},s.compare=function(a,b){var c=o?Range.END_TO_END:"EndToEnd",d=o?Range.START_TO_START:"StartToStart",e=o?"compareBoundaryPoints":"compareEndPoints";return b||(b=s.selectedRange()),a&&b?k(a)&&k(b)&&0===a[e](c,b)&&0===a[e](d,b):!a&&!b},s.clear=function(){var a=o?n.getSelection():m.selection;a&&(a.removeAllRanges?a.removeAllRanges():a.empty&&a.empty())}};return k}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6),e={},f={traverse:function(a,b,c,d,e){if(a)for(a=e?a.lastChild:a.firstChild;a;){var g=e?a.previousSibling:a.nextSibling;if(!c&&b(a)===!1||!d&&f.traverse(a,b,c,d,e)===!1||c&&b(a)===!1)return!1;a=g}},rTraverse:function(a,b,c,d){this.traverse(a,b,c,d,!0)},parseHTML:function(a,c){var d=[],e=(c||document).createElement("div");return e.innerHTML=a,b.merge(d,e.childNodes),d},hasStyling:function(a){var c=b(a);return a&&(!c.is("p,div")||a.className||c.attr("style")||!b.isEmptyObject(c.data()))},convertElement:function(a,b){for(var c,e,g=a.attributes,h=g.length,i=a.ownerDocument.createElement(b);h--;)if(e=g[h], | ||
!d.ie||e.specified)if(d.ie<8&&/style/i.test(e.name))f.copyCSS(a,i);else try{i.setAttribute(e.name,e.value)}catch(a){}for(;c=a.firstChild;)i.appendChild(c);return a.parentNode.replaceChild(i,a),i},blockLevelList:"|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|",canHaveChildren:function(a){return!!/11?|9/.test(a.nodeType)&&"|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr|isindex|link|meta|param|command|embed|keygen|source|track|object|".indexOf("|"+a.nodeName.toLowerCase()+"|")<0},isInline:function(a,b){var c,d=(a||{}).nodeType||3;return 1!==d?3===d:(c=a.tagName.toLowerCase(),"code"===c?!b:f.blockLevelList.indexOf("|"+c+"|")<0)},copyCSS:function(a,b){b.style.cssText=a.style.cssText+b.style.cssText},fixNesting:function(a){var b=function(a){for(;f.isInline(a.parentNode,!0);)a=a.parentNode;return a};f.traverse(a,function(a){if(1===a.nodeType&&!f.isInline(a,!0)&&f.isInline(a.parentNode,!0)){var c=b(a),d=c.parentNode,e=f.extractContents(c,a),g=a;f.copyCSS(c,g),d.insertBefore(e,c),d.insertBefore(g,c)}})},findCommonAncestor:function(a,c){return b(a).parents().has(b(c)).first()},getSibling:function(a,b){return a?(b?a.previousSibling:a.nextSibling)||f.getSibling(a.parentNode,b):null},removeWhiteSpace:function(a,c){for(var d,e,g,h,i,j,k,l,m=f.getSibling,n=f.isInline,o=a.firstChild;o;){if(k=o.nextSibling,d=o.nodeValue,e=o.nodeType,1===e&&o.firstChild&&(j=b(o).css("whiteSpace"),/pre(\-wrap)?$/i.test(j)||f.removeWhiteSpace(o,/line$/i.test(j))),3===e&&d){for(g=m(o),h=m(o,!0),l=!1;b(h).hasClass("sceditor-ignore");)h=m(h,!0);if(n(o)&&h){for(i=h;i.lastChild;)i=i.lastChild;l=3===i.nodeType?/[\t\n\r ]$/.test(i.nodeValue):!n(i)}d=d.replace(/\u200B/g,""),h&&n(h)&&!l||(d=d.replace(c?/^[\t ]+/:/^[\t\n\r ]+/,"")),g&&n(g)||(d=d.replace(c?/[\t ]+$/:/[\t\n\r ]+$/,"")),d.length?o.nodeValue=d.replace(c?/[\t ]+/g:/[\t\n\r ]+/g," "):a.removeChild(o)}o=k}},extractContents:function(a,c){var d,e=f.findCommonAncestor(a,c).get(0),g=!1,h=!1;return(d=function(e){var i,j=a.ownerDocument.createDocumentFragment();return f.traverse(e,function(e){return h||e===c?(h=!0,!1):(e===a&&(g=!0),void(b.contains(e,a)||g&&b.contains(e,c)?(i=e.cloneNode(!1),i.appendChild(d(e)),j.appendChild(i)):g&&!b.contains(j,e)&&j.appendChild(e)))},!1),j})(e)},getOffset:function(a){for(var b=0,c=0;a;)b+=a.offsetLeft,c+=a.offsetTop,a=a.offsetParent;return{left:b,top:c}},getStyle:function(a,c){var d,f,g,h=a.style;if(!h)return"";if(e[c]||(e[c]=b.camelCase(c)),c=e[c],g=h[c],"textAlign"===c){if(d=b(a),f=h.direction,g=g||d.css(c),d.parent().css(c)===g||"block"!==d.css("display")||d.is("hr")||d.is("th"))return"";if(/right/i.test(g)&&"rtl"===f||/left/i.test(g)&&"ltr"===f)return""}return g},hasStyle:function(a,c,d){var e=f.getStyle(a,c);return!!e&&(!d||e===d||b.isArray(d)&&b.inArray(e,d)>-1)}};return f}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var d=c(1),e=navigator.userAgent;b.ie=function(){var a,b=3,c=document,d=c.createElement("div"),e=d.getElementsByTagName("i");do d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->";while(e[0]);return c.documentMode&&c.all&&window.atob&&(b=10),4===b&&c.documentMode&&(b=11),b>4?b:a}(),b.ios=/iPhone|iPod|iPad| wosbrowser\//i.test(e),b.isWysiwygSupported=function(){var a,c,f,g=d('<p contenteditable="true">')[0].contentEditable;return g!==f&&"inherit"!==g&&(c=/Opera Mobi|Opera Mini/i.test(e),/Android/i.test(e)&&(c=!0,/Safari/.test(e)&&(a=/Safari\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534)),/ Silk\//i.test(e)&&(a=/AppleWebKit\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534),b.ios&&(c=/OS [0-4](_\d)+ like Mac/i.test(e)),/Firefox/i.test(e)&&(c=!1),/OneBrowser/i.test(e)&&(c=!1),"UCWEB"===navigator.vendor&&(c=!1),!c)}()}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var c=/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;b.regex=function(a){return a.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},b.entities=function(a,b){if(!a)return a;var c={"&":"&","<":"<",">":">"," ":" ","\r\n":"\n","\r":"\n","\n":"<br />"};return b!==!1&&(c['"']=""",c["'"]="'",c["`"]="`"),a=a.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(a){return c[a]||a})},b.uriScheme=function(a){var b,d=/^[^\/]*:/i,e=window.location;return a&&d.test(a)&&!c.test(a)?(b=e.pathname.split("/"),b.pop(),e.protocol+"//"+e.host+b.join("/")+"/"+a):a}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={html:'<!DOCTYPE html><html{attrs}><head><style>.ie * {min-height: auto !important} .ie table td {height:15px} @supports (-ms-ime-align:auto) { * { min-height: auto !important; } }</style><meta http-equiv="Content-Type" content="text/html;charset={charset}" /><link rel="stylesheet" type="text/css" href="{style}" /></head><body contenteditable="true" {spellcheck}><p></p></body></html>',toolbarButton:'<a class="sceditor-button sceditor-button-{name}" data-sceditor-command="{name}" unselectable="on"><div unselectable="on">{dispName}</div></a>',emoticon:'<img src="{url}" data-sceditor-emoticon="{key}" alt="{key}" title="{tooltip}" />',fontOpt:'<a class="sceditor-font-option" href="#" data-font="{font}"><font face="{font}">{font}</font></a>',sizeOpt:'<a class="sceditor-fontsize-option" data-size="{size}" href="#"><font size="{size}">{size}</font></a>',pastetext:'<div><label for="txt">{label}</label> <textarea cols="20" rows="7" id="txt"></textarea></div><div><input type="button" class="button" value="{insert}" /></div>',table:'<div><label for="rows">{rows}</label><input type="text" id="rows" value="2" /></div><div><label for="cols">{cols}</label><input type="text" id="cols" value="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',image:'<div><label for="link">{url}</label> <input type="text" id="image" placeholder="http://" /></div><div><label for="width">{width}</label> <input type="text" id="width" size="2" /></div><div><label for="height">{height}</label> <input type="text" id="height" size="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',email:'<div><label for="email">{label}</label> <input type="text" id="email" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{insert}" /></div>',link:'<div><label for="link">{url}</label> <input type="text" id="link" placeholder="http://" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{ins}" /></div>',youtubeMenu:'<div><label for="link">{label}</label> <input type="text" id="link" placeholder="https://" /></div><div><input type="button" class="button" value="{insert}" /></div>',youtube:'<iframe width="560" height="315" src="https://www.youtube.com/embed/{id}?wmode=opaque" data-youtube-id="{id}" frameborder="0" allowfullscreen></iframe>'};return function(b,c,d){var e=a[b];return $.each(c,function(a,b){e=e.replace(new RegExp("\\{"+a+"\\}","g"),b)}),d&&(e=$(e)),e}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6).ie,e=c(8),f=d&&d<11,g={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(a,c,d){for(var f=0,g=a.opts.fonts.split(","),h=b("<div />"),i=function(){return d(b(this).data("font")),a.closeDropDown(!0),!1};f<g.length;f++)h.append(e("fontOpt",{font:g[f]},!0).click(i));a.createDropDown(c,"font-picker",h)},exec:function(a){var b=this;g.font._dropDown(b,a,function(a){b.execCommand("fontname",a)})},tooltip:"Font Name"},size:{_dropDown:function(a,c,d){for(var f=b("<div />"),g=function(c){d(b(this).data("size")),a.closeDropDown(!0),c.preventDefault()},h=1;h<=7;h++)f.append(e("sizeOpt",{size:h},!0).click(g));a.createDropDown(c,"fontsize-picker",f)},exec:function(a){var b=this;g.size._dropDown(b,a,function(a){b.execCommand("fontsize",a)})},tooltip:"Font Size"},color:{_dropDown:function(a,c,d){var e,f,h,i,j={r:255,g:255,b:255},k=b("<div />"),l=a.opts.colors?a.opts.colors.split("|"):new Array(21),m=[],n=g.color;if(!n._htmlCache){for(e=0;e<l.length;++e){for(i=l[e]?l[e].split(","):new Array(21),m.push('<div class="sceditor-color-column">'),f=0;f<i.length;++f)h=i[f]||"#"+j.r.toString(16)+j.g.toString(16)+j.b.toString(16),m.push('<a href="#" class="sceditor-color-option" style="background-color: '+h+'" data-color="'+h+'"></a>'),f%5===0?(j.g-=51,j.b=255):j.b-=51;m.push("</div>"),e%5===0?(j.r-=51,j.g=255,j.b=255):(j.g=255,j.b=255)}n._htmlCache=m.join("")}k.append(n._htmlCache).find("a").click(function(c){d(b(this).attr("data-color")),a.closeDropDown(!0),c.preventDefault()}),a.createDropDown(c,"color-picker",k)},exec:function(a){var b=this;g.color._dropDown(b,a,function(a){b.execCommand("forecolor",a)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(a){var b,c,d=this;c=e("pastetext",{label:d._("Paste your text inside the following box:"),insert:d._("Insert")},!0),c.find(".button").click(function(a){b=c.find("#txt").val(),b&&d.wysiwygEditorInsertText(b),d.closeDropDown(!0),a.preventDefault()}),d.createDropDown(a,"pastetext",c)},tooltip:"Paste Text"},bulletlist:{exec:"insertunorderedlist",tooltip:"Bullet list"},orderedlist:{exec:"insertorderedlist",tooltip:"Numbered list"},indent:{state:function(a,c){var d,e,f,g=b(c),h=g.parents("ul,ol,menu"),i=h.first();if(h.length>1||i.children().length>1)return 0;if(g.is("ul,ol,menu")){if(d=this.getRangeHelper().selectedRange(),!(window.Range&&d instanceof Range))return g.is("li,ul,ol,menu")?0:-1;if(e=d.startContainer.parentNode,f=d.endContainer.parentNode,e!==e.parentNode.firstElementChild||b(f).is("li")&&f!==f.parentNode.lastElementChild)return 0}return-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());a.focus(),c.parents("ul,ol,menu")&&a.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(a,c){return b(c).is("ul,ol,menu")||b(c).parents("ul,ol,menu").length>0?0:-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());c.parents("ul,ol,menu")&&a.execCommand("outdent")},tooltip:"Remove one indent"},table:{forceNewLineAfter:["table"],exec:function(a){var b=this,c=e("table",{rows:b._("Rows:"),cols:b._("Cols:"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d,e,g=c.find("#rows").val()-0,h=c.find("#cols").val()-0,i="<table>";if(!(g<1||h<1)){for(d=0;d<g;d++){for(i+="<tr>",e=0;e<h;e++)i+="<td>"+(f?"":"<br />")+"</td>";i+="</tr>"}i+="</table>",b.wysiwygEditorInsertHtml(i),b.closeDropDown(!0),a.preventDefault()}}),b.createDropDown(a,"inserttable",c)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{forceNewLineAfter:["code"],exec:function(){this.wysiwygEditorInsertHtml("<code>",(f?"":"<br />")+"</code>")},tooltip:"Code"},image:{exec:function(a){var b=this,c=e("image",{url:b._("URL:"),width:b._("Width (optional):"),height:b._("Height (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#image").val(),e=c.find("#width").val(),f=c.find("#height").val(),g="";e&&(g+=' width="'+e+'"'),f&&(g+=' height="'+f+'"'),d&&b.wysiwygEditorInsertHtml("<img"+g+' src="'+d+'" />'),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertimage",c)},tooltip:"Insert an image"},email:{exec:function(a){var b=this,c=e("email",{label:b._("E-mail:"),desc:b._("Description (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#email").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml('<a href="mailto:'+d+'">'+e+"</a>")):b.execCommand("createlink","mailto:"+d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertemail",c)},tooltip:"Insert an email"},link:{exec:function(a){var b=this,c=e("link",{url:b._("URL:"),desc:b._("Description (optional):"),ins:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#link").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml('<a href="'+d+'">'+e+"</a>")):b.execCommand("createlink",d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertlink",c)},tooltip:"Insert a link"},unlink:{state:function(){var a=b(this.currentNode());return a.is("a")||a.parents("a").length>0?0:-1},exec:function(){var a=b(this.currentNode()),c=a.is("a")?a:a.parents("a").first();c.length&&c.replaceWith(c.contents())},tooltip:"Unlink"},quote:{forceNewLineAfter:["blockquote"],exec:function(a,b,c){var d="<blockquote>",e="</blockquote>";b?(c=c?"<cite>"+c+"</cite>":"",d=d+c+b+e,e=null):""===this.getRangeHelper().selectedHtml()&&(e=(f?"":"<br />")+e),this.wysiwygEditorInsertHtml(d,e)},tooltip:"Insert a Quote"},emoticon:{exec:function(a){var c=this,d=function(e){var f,g=c.opts.emoticonsCompat,h=c.getRangeHelper(),i=g&&" "!==h.getOuterText(!0,1)?" ":"",j=g&&" "!==h.getOuterText(!1,1)?" ":"",k=b("<div />"),l=b("<div />").appendTo(k),m=0,n=b.extend({},c.opts.emoticons.dropdown,e?c.opts.emoticons.more:{});return b.each(n,function(){m++}),m=Math.sqrt(m),b.each(n,function(a,d){l.append(b("<img />").attr({src:d.url||d,alt:a,title:d.tooltip||a}).click(function(){return c.insert(i+b(this).attr("alt")+j,null,!1).closeDropDown(!0),!1})),l.children().length>=m&&(l=b("<div />").appendTo(k))}),!e&&c.opts.emoticons.more&&(f=b('<a class="sceditor-more">'+c._("More")+"</a>").click(function(){return c.createDropDown(a,"more-emoticons",d(!0)),!1}),k.append(f)),k};c.createDropDown(a,"emoticons",d(!1))},txtExec:function(a){g.emoticon.exec.call(this,a)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(a,b,c){var d,f=e("youtubeMenu",{label:a._("Video URL:"),insert:a._("Insert")},!0);f.find(".button").click(function(b){var e=f.find("#link").val();e&&(d=e.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),d&&(e=d[1]),/^[a-zA-Z0-9_\-]{11}$/.test(e)?c(e):alert("Invalid YouTube video")),a.closeDropDown(!0),b.preventDefault()}),a.createDropDown(b,"insertlink",f)},exec:function(a){var b=this;g.youtube._dropDown(b,a,function(a){b.wysiwygEditorInsertHtml(e("youtube",{id:a}))})},tooltip:"Insert a YouTube video"},date:{_date:function(a){var b=new Date,c=b.getYear(),d=b.getMonth()+1,e=b.getDate();return c<2e3&&(c=1900+c),d<10&&(d="0"+d),e<10&&(e="0"+e),a.opts.dateFormat.replace(/year/i,c).replace(/month/i,d).replace(/day/i,e)},exec:function(){this.insertText(g.date._date(this))},txtExec:function(){this.insertText(g.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var a=new Date,b=a.getHours(),c=a.getMinutes(),d=a.getSeconds();return b<10&&(b="0"+b),c<10&&(c="0"+c),d<10&&(d="0"+d),b+":"+c+":"+d},exec:function(){this.insertText(g.time._time())},txtExec:function(){this.insertText(g.time._time())},tooltip:"Insert current time"},ltr:{state:function(a,b){return b&&"ltr"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("ltr"===d.css("direction")?d.css("direction",""):d.css("direction","ltr"))},tooltip:"Left-to-Right"},rtl:{state:function(a,b){return b&&"rtl"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("rtl"===d.css("direction")?d.css("direction",""):d.css("direction","rtl"))},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}};return g}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1);return{toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:null,locale:b("html").attr("lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}]); | ||
/* SCEditor v2.0.0-beta1 | (C) 2017, Sam Clarke | sceditor.com/license */ | ||
!function(e){"use strict";function t(e,t){return typeof t===e}function n(e){return!Object.keys(e).length}function o(e,t){for(var n=e===!!e,i=n?2:1,r=n?t:e,a=!!n&&e;i<arguments.length;i++){var c=arguments[i];for(var l in c){var s=c[l];if(!ce(s)){var u=null!==s&&"object"==typeof s,d=Array.isArray(s);r[l]=a&&(u||d)?o(!0,r[l]||(d?[]:{}),s):s}}}return r}function i(e,t){var n=e.indexOf(t);n>-1&&e.splice(n,1)}function r(e,t){if(Array.isArray(e)||"length"in e&&se(e.length))for(var n=0;n<e.length;n++)t(n,e[n]);else Object.keys(e).forEach(function(n){t(n,e[n])})}function a(e){return e=parseFloat(e),isFinite(e)?e:0}function c(e,t,n){var o=(n||document).createElement(e);return r(t||{},function(e,t){"style"===e?o.style.cssText=t:e in o?o[e]=t:o.setAttribute(e,t)}),o}function l(e,t){for(var n=[],o=e||{};(o=o.parentNode)&&!/(9|11)/.test(o.nodeType);)t&&!k(o,t)||n.push(o);return n}function s(e,t){for(var n=e||{};(n=n.parentNode)&&!/(9|11)/.test(n.nodeType);)if(!t||k(n,t))return n}function u(e,t){return k(e,t)?e:s(e,t)}function d(e){e.parentNode.removeChild(e)}function f(e,t){e.appendChild(t)}function p(e,t){return e.querySelectorAll(t)}function m(e,t,n,o,i){t.split(" ").forEach(function(t){var r;ae(n)?(r=o["_sce-event-"+t+n]||function(t){for(var i=t.target;i&&i!==e;){if(k(i,n))return void o.call(i,t);i=i.parentNode}},o["_sce-event-"+t+n]=r):(r=n,i=o),e.addEventListener(t,r,i||!1)})}function g(e,t,n,o,i){t.split(" ").forEach(function(t){var r;ae(n)?r=o["_sce-event-"+t+n]:(r=n,i=o),e.removeEventListener(t,r,i||!1)})}function h(e,t,n){if(arguments.length<3)return e.getAttribute(t);null==n?v(e,t):e.setAttribute(t,n)}function v(e,t){e.removeAttribute(t)}function y(e){w(e,"display","none")}function b(e){w(e,"display","")}function x(e){O(e)?y(e):b(e)}function w(e,t,n){if(arguments.length<3){if(ae(t))return getComputedStyle(e)[t];r(t,function(t,n){w(e,t,n)})}else{var o=(n||0===n)&&!isNaN(n);e.style[t]=o?n+"px":n}}function C(e,t,n){var o=arguments.length,i={};if(e.nodeType===de){if(1===o)return r(e.attributes,function(e,t){/^data\-/i.test(t.name)&&(i[t.name.substr(5)]=t.value)}),i;if(2===o)return h(e,"data-"+t);h(e,"data-"+t,String(n))}}function k(e,t){var n=!1;if(e&&e.nodeType===de){n=(e.matches||e.msMatchesSelector||e.webkitMatchesSelector).call(e,t)}return n}function E(e,t){return e!==t&&e.contains&&e.contains(t)}function S(e,t){var n=e.previousElementSibling;return t&&n?k(n,t)?n:null:n}function D(e,t){return t.parentNode.insertBefore(e,t)}function T(e){return e.className.trim().split(/\s+/)}function M(e,t){return k(e,"."+t)}function N(e,t){var n=T(e);n.indexOf(t)<0&&n.push(t),e.className=n.join(" ")}function R(e,t){var n=T(e);i(n,t),e.className=n.join(" ")}function F(e,t,n){(n=ce(n)?!M(e,t):n)?N(e,t):R(e,t)}function H(e,t){if(ce(t)){var n=getComputedStyle(e),o=a(n.paddingLeft)+a(n.paddingRight),i=a(n.borderLeftWidth)+a(n.borderRightWidth);return e.offsetWidth-o-i}w(e,"width",t)}function _(e,t){if(ce(t)){var n=getComputedStyle(e),o=a(n.paddingTop)+a(n.paddingBottom),i=a(n.borderTopWidth)+a(n.borderBottomWidth);return e.offsetHeight-o-i}w(e,"height",t)}function z(e,t,n){var o;le(window.CustomEvent)?o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n}):(o=e.ownerDocument.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,n),e.dispatchEvent(o)}function O(e){return!!e.getClientRects().length}function B(e){return e.replace(/^-ms-/,"ms-").replace(/-(\w)/g,function(e,t){return t.toUpperCase()})}function A(e,t,n,o,i){for(e=i?e.lastChild:e.firstChild;e;){var r=i?e.previousSibling:e.nextSibling;if(!n&&!1===t(e)||!o&&!1===A(e,t,n,o,i)||n&&!1===t(e))return!1;e=r}}function I(e,t,n,o){A(e,t,n,o,!0)}function L(e,t){var n=(t=t||document).createDocumentFragment(),o=c("div",{},t);for(o.innerHTML=e;o.firstChild;)f(n,o.firstChild);return n}function P(e){return e&&(!k(e,"p,div")||e.className||h(e,"style")||!n(C(e)))}function V(e,t){var n=c(t,{},e.ownerDocument);for(r(e.attributes,function(e,t){try{h(n,t.name,t.value)}catch(e){}});e.firstChild;)f(n,e.firstChild);return e.parentNode.replaceChild(n,e),n}function W(e){return!!/11?|9/.test(e.nodeType)&&"|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr|isindex|link|meta|param|command|embed|keygen|source|track|object|".indexOf("|"+e.nodeName.toLowerCase()+"|")<0}function j(e,t){var n,o=(e||{}).nodeType||fe;return o!==de?o===fe:"code"===(n=e.tagName.toLowerCase())?!t:me.indexOf("|"+n+"|")<0}function q(e,t){t.style.cssText=e.style.cssText+t.style.cssText}function U(e){var t=function(e){for(;j(e.parentNode,!0);)e=e.parentNode;return e};A(e,function(e){var n=!j(e,!0);if(n&&j(e.parentNode,!0)){var o=t(e),i=K(o,e),r=e;q(o,r),D(i,o),D(r,o)}if(n&&k(e,"ul,ol")&&k(e.parentNode,"ul,ol")){var a=S(e,"li");a||D(a=c("li"),e),f(a,e)}})}function $(e,t){return e?(t?e.previousSibling:e.nextSibling)||$(e.parentNode,t):null}function Y(e){var t,n,o,i,r,a,c,l=w(e,"whiteSpace"),s=/line$/i.test(l),u=e.firstChild;if(!/pre(\-wrap)?$/i.test(l))for(;u;){if(a=u.nextSibling,t=u.nodeValue,(n=u.nodeType)===de&&u.firstChild&&Y(u),n===fe){for(o=$(u),i=$(u,!0),c=!1;M(i,"sceditor-ignore");)i=$(i,!0);if(j(u)&&i){for(r=i;r.lastChild;)r=r.lastChild;c=r.nodeType===fe?/[\t\n\r ]$/.test(r.nodeValue):!j(r)}t=t.replace(/\u200B/g,""),i&&j(i)&&!c||(t=t.replace(s?/^[\t ]+/:/^[\t\n\r ]+/,"")),o&&j(o)||(t=t.replace(s?/[\t ]+$/:/[\t\n\r ]+$/,"")),t.length?u.nodeValue=t.replace(s?/[\t ]+/g:/[\t\n\r ]+/g," "):d(u)}u=a}}function K(e,t){var n=e.ownerDocument.createRange();return n.setStartBefore(e),n.setEndAfter(t),n.extractContents()}function X(e){for(var t=0,n=0;e;)t+=e.offsetLeft,n+=e.offsetTop,e=e.offsetParent;return{left:t,top:n}}function Q(e,t){var n,o,i=e.style;if(ue[t]||(ue[t]=B(t)),t=ue[t],o=i[t],"textAlign"===t){if(n=i.direction,o=o||w(e,t),w(e.parentNode,t)===o||"block"!==w(e,"display")||k(e,"hr,th"))return"";if(/right/i.test(o)&&"rtl"===n||/left/i.test(o)&&"ltr"===n)return""}return o}function G(e){return e.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")}function J(e,t){if(!e)return e;var n={"&":"&","<":"<",">":">"," ":" ","\r\n":"<br />","\r":"<br />","\n":"<br />"};return!1!==t&&(n['"']=""",n["'"]="'",n["`"]="`"),e=e.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(e){return n[e]||e})}function Z(e){if("mozHidden"in document)for(var t,n=e.getBody();n;){if((t=n).firstChild)t=t.firstChild;else{for(;t&&!t.nextSibling;)t=t.parentNode;t&&(t=t.nextSibling)}3===n.nodeType&&/[\n\r\t]+/.test(n.nodeValue)&&(/^pre/.test(w(n.parentNode,"whiteSpace"))||d(n)),n=t}}function ee(e){var t=this,n=[],o=function(e){return"signal"+e.charAt(0).toUpperCase()+e.slice(1)},i=function(t,i){t=[].slice.call(t);var r,a,c=o(t.shift());for(r=0;r<n.length;r++)if(c in n[r]&&(a=n[r][c].apply(e,t),i))return a};t.call=function(){i(arguments,!1)},t.callOnlyFirst=function(){return i(arguments,!0)},t.hasHandler=function(e){var t=n.length;for(e=o(e);t--;)if(e in n[t])return!0;return!1},t.exists=function(e){return e in De&&("function"==typeof(e=De[e])&&"object"==typeof e.prototype)},t.isRegistered=function(e){if(t.exists(e))for(var o=n.length;o--;)if(n[o]instanceof De[e])return!0;return!1},t.register=function(o){return!(!t.exists(o)||t.isRegistered(o))&&(o=new De[o],n.push(o),"init"in o&&o.init.call(e),!0)},t.deregister=function(o){var i,r=n.length,a=!1;if(!t.isRegistered(o))return a;for(;r--;)n[r]instanceof De[o]&&(a=!0,"destroy"in(i=n.splice(r,1)[0])&&i.destroy.call(e));return a},t.destroy=function(){for(var t=n.length;t--;)"destroy"in n[t]&&n[t].destroy.call(e);n=[],e=null}}function te(e,t){var n,o,i=t||e.contentDocument||e.document,r="sceditor-start-marker",a="sceditor-end-marker",l=this;l.insertHTML=function(e,t){var n,o;if(!l.selectedRange())return!1;for(t&&(e+=l.selectedHtml()+t),o=c("p",{},i),n=i.createDocumentFragment(),o.innerHTML=e;o.firstChild;)f(n,o.firstChild);l.insertNode(n)},o=function(e,t,o){var s,u=i.createDocumentFragment();if("string"==typeof e?(t&&(e+=l.selectedHtml()+t),u=L(e)):(f(u,e),t&&(f(u,l.selectedRange().extractContents()),f(u,t))),s=u.lastChild){for(;!j(s.lastChild,!0);)s=s.lastChild;if(W(s)?s.lastChild||f(s,document.createTextNode("")):s=u,l.removeMarkers(),f(s,n(r)),f(s,n(a)),o){var d=c("div");return f(d,u),d.innerHTML}return u}},l.insertNode=function(e,t){var n=o(e,t),i=l.selectedRange(),r=i.commonAncestorContainer;if(!n)return!1;i.deleteContents(),r&&3!==r.nodeType&&!W(r)?D(n,r):i.insertNode(n),l.restoreRange()},l.cloneSelected=function(){var e=l.selectedRange();if(e)return e.cloneRange()},l.selectedRange=function(){var t,n,o=e.getSelection();if(o){if(o.getRangeAt&&o.rangeCount<=0){for(n=i.body;n.firstChild;)n=n.firstChild;(t=i.createRange()).setStartBefore(n),o.addRange(t)}return o.rangeCount>0&&(t=o.getRangeAt(0)),t}},l.hasSelection=function(){var t=e.getSelection();return t&&t.rangeCount>0},l.selectedHtml=function(){var e,t=l.selectedRange();return t?(e=c("p",{},i),f(e,t.cloneContents()),e.innerHTML):""},l.parentNode=function(){var e=l.selectedRange();if(e)return e.commonAncestorContainer},l.getFirstBlockParent=function(e){var t=function(e){return j(e,!0)&&(e=e?e.parentNode:null)?t(e):e};return t(e||l.parentNode())},l.insertNodeAt=function(e,t){var n=l.selectedRange(),o=l.cloneSelected();if(!o)return!1;o.collapse(e),o.insertNode(t),l.selectRange(n)},n=function(e){l.removeMarker(e);var t=c("span",{id:e,className:"sceditor-selection sceditor-ignore",style:"display:none;line-height:0"},i);return t.innerHTML=" ",t},l.insertMarkers=function(){var e=l.selectedRange(),t=n(r);l.removeMarkers(),l.insertNodeAt(!0,t),e&&e.collapsed?t.parentNode.insertBefore(n(a),t.nextSibling):l.insertNodeAt(!1,n(a))},l.getMarker=function(e){return i.getElementById(e)},l.removeMarker=function(e){var t=l.getMarker(e);t&&d(t)},l.removeMarkers=function(){l.removeMarker(r),l.removeMarker(a)},l.saveRange=function(){l.insertMarkers()},l.selectRange=function(t){var n,o=e.getSelection(),r=t.endContainer;if(!Te&&t.collapsed&&r&&!j(r,!0)){for(n=r.lastChild;n&&k(n,".sceditor-ignore");)n=n.previousSibling;if(k(n,"br")){var a=i.createRange();a.setEndAfter(n),a.collapse(!1),l.compare(t,a)&&(t.setStartBefore(n),t.collapse(!0))}}o&&(l.clear(),o.addRange(t))},l.restoreRange=function(){var e,t=l.selectedRange(),n=l.getMarker(r),o=l.getMarker(a);if(!n||!o||!t)return!1;e=n.nextSibling===o,(t=i.createRange()).setStartBefore(n),t.setEndAfter(o),e&&t.collapse(!0),l.selectRange(t),l.removeMarkers()},l.selectOuterText=function(e,t){var n,o,i=l.cloneSelected();if(!i)return!1;i.collapse(!1),n=Me(i,!0,e),o=Me(i,!1,t),i.setStart(n.node,n.offset),i.setEnd(o.node,o.offset),l.selectRange(i)},l.getOuterText=function(e,t){var n=l.cloneSelected();return n?(n.collapse(!e),Me(n,e,t).text):""},l.replaceKeyword=function(e,t,n,o,i,r){n||e.sort(function(e,t){return e[0].length-t[0].length});var a,c,s,u,d,f,p,m,g=e.length,h=i?1:0,v=o||e[g-1][0].length;for(i&&v++,r=r||"",d=(a=l.getOuterText(!0,v)).length,a+=r,t&&(a+=l.getOuterText(!1,v));g--;)if(p=e[g][0],m=p.length,u=Math.max(0,d-m-h),s=-1,i?(c=a.substr(u).match(new RegExp("(^|[\\s ])"+G(p)+"(^|[\\s ])")))&&(s=c.index+u+c[1].length):s=a.indexOf(p,u),s>-1&&s<=d&&s+m+h>=d)return f=d-s,l.selectOuterText(f,m-f-(/^\S/.test(r)?1:0)),l.insertHTML(e[g][1]),!0;return!1},l.compare=function(e,t){return t||(t=l.selectedRange()),e&&t?0===e.compareBoundaryPoints(Range.END_TO_END,t)&&0===e.compareBoundaryPoints(Range.START_TO_START,t):!e&&!t},l.clear=function(){var t=e.getSelection();t&&(t.removeAllRanges?t.removeAllRanges():t.empty&&t.empty())}}function ne(e,t){var n=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/,o=e&&p(e,"img[data-sceditor-emoticon]");if(e&&o.length)for(var i=0;i<o.length;i++){var r=o[i],a=r.parentNode,c=r.previousSibling,l=r.nextSibling;if(c&&n.test(c.nodeValue.slice(-1))||l&&n.test((l.nodeValue||"")[0])){var s=t.cloneSelected(),u=-1,f=s.startContainer,m=c.nodeValue;null===m&&(m=c.innerText||""),m+=C(r,"sceditor-emoticon"),f===l&&(u=m.length+s.startOffset),f===e&&e.childNodes[s.startOffset]===l&&(u=m.length),f===c&&(u=s.startOffset),l&&l.nodeType===fe||(l=a.insertBefore(a.ownerDocument.createTextNode(""),l)),l.insertData(0,m),d(c),d(r),u>-1&&(s.setStart(l,u),s.collapse(!0),t.selectRange(s))}}}function oe(e,t,n){var o=e.ownerDocument,i="(^|\\s| | | | |$)",a=[],c={};s(e,"code")||(r(t,function(e){c[e]=new RegExp(i+G(e)+i),a.push(e)}),a.sort(function(e,t){return t.length-e.length}),function e(i){for(i=i.firstChild;i;){if(i.nodeType!==de||k(i,"code")||e(i),i.nodeType===fe)for(var r=0;r<a.length;r++){var l=i.nodeValue,s=a[r],u=n?l.search(c[s]):l.indexOf(s);if(u>-1){var d=l.indexOf(s,u),f=L(t[s],o),p=l.substr(d+s.length);f.appendChild(o.createTextNode(p)),i.nodeValue=l.substr(0,d),i.parentNode.insertBefore(f,i.nextSibling)}}i=i.nextSibling}}(e))}function ie(e,t){var n;A(e,function(e){j(e,!0)?(n||D(n=c("p",{},t),e),e.nodeType===fe&&""===e.nodeValue||f(n,e)):n=null},!1,!0)}function re(e,t){var n,a,l,s,v,E,S,T,B,A,L,q,$,K,Q,G,Z,se,ue,me,he,ve,we,Ce,Ee,De,Te,Me,ze,Oe,Be,Ae,Ie,Le,Pe,Ve,We,je,qe,Ue,$e,Ye,Ke,Xe,Qe,Ge,Je,Ze,et,tt,nt,ot,it,rt,at,ct,lt,st,ut,dt,ft,pt,mt=this,gt=e.get?e.get(0):e,ht={},vt=[],yt=[],bt={},xt={},wt={};mt.commands=o(!0,{},t.commands||Se);var Ct=mt.opts=o(!0,{},ge,t);mt.opts.emoticons=t.emoticons||ge.emoticons,De=function(){gt._sceditor=mt,Ct.locale&&"en"!==Ct.locale&&Ae(),D(a=c("div",{className:"sceditor-container"}),gt),w(a,"z-index",Ct.zIndex),Fe&&N(a,"ie ie"+Fe),ue=gt.required,gt.required=!1;var e=re.formats[Ct.format];"init"in(n=e?new e:{})&&n.init.call(mt),Be(),We(),Ie(),Oe(),Le(),Pe(),xe||mt.toggleSourceMode(),et();var t=function(){g(Ne,"load",t),Ct.autofocus&&rt(),pt(),nt(),K.call("ready"),"onReady"in n&&n.onReady.call(mt)};m(Ne,"load",t),"complete"===Re.readyState&&t()},Be=function(){var e=Ct.plugins;e=e?e.toString().split(","):[],K=new ee(mt),e.forEach(function(e){K.register(e.trim())})},Ae=function(){var e;(q=re.locale[Ct.locale])||(e=Ct.locale.split("-"),q=re.locale[e[0]]),q&&q.dateFormat&&(Ct.dateFormat=q.dateFormat)},Oe=function(){S=c("textarea"),s=c("iframe",{frameborder:0,allowfullscreen:!0}),Ct.startInSourceMode?(N(a,"sourceMode"),y(s)):(N(a,"wysiwygMode"),y(S)),Ct.spellcheck||h(a,"spellcheck","false"),"https:"===Ne.location.protocol&&h(s,"src","javascript:false"),f(a,s),f(a,S),mt.dimensions(Ct.width||H(gt),Ct.height||_(gt));var e=Fe?"ie ie"+Fe:"";e+=be?" ios":"",(E=s.contentDocument).open(),E.write(ke("html",{attrs:' class="'+e+'"',spellcheck:Ct.spellcheck?"":'spellcheck="false"',charset:Ct.charset,style:Ct.style})),E.close(),v=E.body,mt.readOnly(!!Ct.readOnly),(be||ye||Fe)&&(_(v,"100%"),Fe||m(v,"touchend",mt.focus));var t=h(gt,"tabindex");h(S,"tabindex",t),h(s,"tabindex",t),$=new te(s.contentWindow),y(gt),mt.val(gt.value);var n=Ct.placeholder||h(gt,"placeholder");n&&(S.placeholder=n,h(v,"placeholder",n))},Le=function(){Ct.autoUpdate&&(m(v,"blur",ft),m(S,"blur",ft)),null===Ct.rtl&&(Ct.rtl="rtl"===w(S,"direction")),mt.rtl(!!Ct.rtl),Ct.autoExpand&&(m(v,"load",pt,pe),m(E,"input keyup",pt)),Ct.resizeEnabled&&Ve(),h(a,"id",Ct.id),mt.emoticons(Ct.emoticonsEnabled)},Pe=function(){var e=gt.form,t="onselectionchange"in E?"selectionchange":"keyup focus blur contextmenu mouseup touchend click";m(Re,"click",Je),e&&(m(e,"reset",Ke),m(e,"submit",mt.updateOriginal,pe)),m(v,"keypress",Ye),m(v,"keydown",Ue),m(v,"keydown",$e),m(v,"keyup",nt),m(v,"blur",ut),m(v,"keyup",dt),m(v,"paste",je),m(v,"compositionstart compositionend",Qe),m(v,t,ot),m(v,"keydown keyup keypress focus blur contextmenu",Ge),Ct.emoticonsCompat&&Ne.getSelection&&m(v,"keyup",ct),m(v,"blur",function(){mt.val()||N(v,"placeholder")}),m(v,"focus",function(){R(v,"placeholder")}),m(S,"blur",ut),m(S,"keyup",dt),m(S,"keydown",Ue),m(S,"compositionstart compositionend",Qe),m(S,"keydown keyup keypress focus blur contextmenu",Ge),m(E,"mousedown",Xe),m(E,t,ot),m(E,"beforedeactivate keyup mouseup",ze),m(E,"keyup",nt),m(E,"focus",function(){B=null}),m(a,"selectionchanged",it),m(a,"selectionchanged",et),m(a,"selectionchanged valuechanged nodechanged",Ge)},Ie=function(){var e,t=mt.commands,n=(Ct.toolbarExclude||"").split(","),o=Ct.toolbar.split("|");l=c("div",{className:"sceditor-toolbar",unselectable:"on"}),Ct.icons in re.icons&&(Ee=new re.icons[Ct.icons]),r(o,function(o,i){e=c("div",{className:"sceditor-group"}),r(i.split(","),function(o,i){var r,a,c=t[i];!c||n.indexOf(i)>-1||(a=c.shortcut,r=ke("toolbarButton",{name:i,dispName:mt._(c.name||c.tooltip||i)},!0).firstChild,Ee&&Ee.create&&Ee.create(i)&&(D(Ee.create(i),r.firstChild),N(r,"has-icon")),r._sceTxtMode=!!c.txtExec,r._sceWysiwygMode=!!c.exec,F(r,"disabled",!c.exec),m(r,"click",function(e){M(r,"disabled")||Me(r,c),et(),e.preventDefault()}),m(r,"mousedown",function(e){mt.closeDropDown(),e.preventDefault()}),c.tooltip&&h(r,"title",mt._(c.tooltip)+(a?" ("+a+")":"")),a&&mt.addShortcut(a,i),c.state?yt.push({name:i,state:c.state}):ae(c.exec)&&yt.push({name:i,state:c.exec}),f(e,r),xt[i]=r)}),e.firstChild&&f(l,e)}),f(Ct.toolbarContainer||a,l)},Ve=function(){var e,t,n,o,i,r,l=c("div",{className:"sceditor-grip"}),s=c("div",{className:"sceditor-resize-cover"}),u="touchcancel touchend mouseup",d=0,p=0,h=0,v=0,x=0,w=0,C=H(a),k=_(a),E=!1,S=mt.rtl();if(e=Ct.resizeMinHeight||k/1.5,t=Ct.resizeMaxHeight||2.5*k,n=Ct.resizeMinWidth||C/1.25,o=Ct.resizeMaxWidth||1.25*C,i=function(i){"touchmove"===i.type?(i=Ne.event,h=i.changedTouches[0].pageX,v=i.changedTouches[0].pageY):(h=i.pageX,v=i.pageY);var r=w+(v-p),a=S?x-(h-d):x+(h-d);o>0&&a>o&&(a=o),n>0&&a<n&&(a=n),Ct.resizeWidth||(a=!1),t>0&&r>t&&(r=t),e>0&&r<e&&(r=e),Ct.resizeHeight||(r=!1),(a||r)&&mt.dimensions(a,r),i.preventDefault()},r=function(e){E&&(E=!1,y(s),R(a,"resizing"),g(Re,"touchmove mousemove",i),g(Re,u,r),e.preventDefault())},Ee&&Ee.create){var D=Ee.create("grip");D&&(f(l,D),N(l,"has-icon"))}f(a,l),f(a,s),y(s),m(l,"touchstart mousedown",function(e){"touchstart"===e.type?(e=Ne.event,d=e.touches[0].pageX,p=e.touches[0].pageY):(d=e.pageX,p=e.pageY),x=H(a),w=_(a),E=!0,N(a,"resizing"),b(s),m(Re,"touchmove mousemove",i),m(Re,u,r),e.preventDefault()})},We=function(){var e=Ct.emoticons,t=Ct.emoticonsRoot||"";e&&(wt=o({},e.more,e.dropdown,e.hidden)),r(wt,function(e,n){wt[e]=ke("emoticon",{key:e,url:t+(n.url||n),tooltip:n.tooltip||e}),Ct.emoticonsEnabled&&vt.push(c("img",{src:t+(n.url||n)}))})},rt=function(){var e,t,n=v.firstChild,o=!!Ct.autofocusEnd;if(O(a)){if(mt.sourceMode())return t=o?S.value.length:0,void S.setSelectionRange(t,t);if(Y(v),o)for((n=v.lastChild)||(n=c("p",{},E),f(v,n));n.lastChild;)n=n.lastChild,!He&&k(n,"br")&&n.previousSibling&&(n=n.previousSibling);e=E.createRange(),W(n)?e.selectNodeContents(n):(e.setStartBefore(n),o&&e.setStartAfter(n)),e.collapse(!o),$.selectRange(e),Z=e,o&&(v.scrollTop=v.scrollHeight),mt.focus()}},mt.readOnly=function(e){return"boolean"!=typeof e?!S.readonly:(v.contentEditable=!e,S.readonly=!e,Ze(e),mt)},mt.rtl=function(e){var t=e?"rtl":"ltr";return"boolean"!=typeof e?"rtl"===h(S,"dir"):(h(v,"dir",t),h(S,"dir",t),R(a,"rtl"),R(a,"ltr"),N(a,t),Ee&&Ee.rtl&&Ee.rtl(e),mt)},Ze=function(e){var t=mt.inSourceMode()?"_sceTxtMode":"_sceWysiwygMode";r(xt,function(n,o){F(o,"disabled",e||!o[t])})},mt.width=function(e,t){return e||0===e?(mt.dimensions(e,null,t),mt):H(a)},mt.dimensions=function(e,t,n){return e=!(!e&&0!==e)&&e,t=!(!t&&0!==t)&&t,!1===e&&!1===t?{width:mt.width(),height:mt.height()}:(!1!==e&&(!1!==n&&(Ct.width=e),H(a,e)),!1!==t&&(!1!==n&&(Ct.height=t),_(a,t)),mt)},mt.height=function(e,t){return e||0===e?(mt.dimensions(null,e,t),mt):_(a)},mt.maximize=function(e){return ce(e)?M(a,"sceditor-maximize"):((e=!!e)&&(we=Ne.pageYOffset),F(Re.documentElement,"sceditor-maximize",e),F(Re.body,"sceditor-maximize",e),F(a,"sceditor-maximize",e),mt.width(e?"100%":Ct.width,!1),mt.height(e?"100%":Ct.height,!1),e||Ne.scrollTo(0,we),pt(),mt)},pt=function(){Ct.autoExpand&&!ve&&setTimeout(mt.expandToContent,200)},mt.expandToContent=function(e){if(!mt.maximize()){if(ve=!1,!he){var t=Ct.resizeMinHeight||Ct.height||_(gt);he={min:t,max:Ct.resizeMaxHeight||2*t}}var n=Re.createRange();n.selectNodeContents(v);var o=n.getBoundingClientRect(),i=E.documentElement.clientHeight,r=o.bottom-o.top,a=mt.height()+(r-i);e||-1===he.max||(a=Math.min(a,he.max)),mt.height(Math.ceil(Math.max(a,he.min)))}},mt.destroy=function(){if(K){K.destroy(),$=null,B=null,K=null,T&&d(T),g(Re,"click",Je);var e=gt.form;e&&(g(e,"reset",Ke),g(e,"submit",mt.updateOriginal)),d(S),d(l),d(a),delete gt._sceditor,b(gt),gt.required=ue}},mt.createDropDown=function(e,t,n,i){var a,l="sceditor-"+t;mt.closeDropDown(!0),T&&M(T,l)||(!1!==i&&r(p(n,":not(input):not(textarea)"),function(e,t){t.nodeType===de&&h(t,"unselectable","on")}),a=o({top:X(e).top,left:X(e).left,marginTop:e.clientHeight},Ct.dropDownCss),w(T=c("div",{className:"sceditor-dropdown "+l}),a),f(T,n),f(Re.body,T),m(T,"click focusin",function(e){e.stopPropagation()}),setTimeout(function(){if(T){var e=p(T,"input,textarea")[0];e&&e.focus()}}))},Je=function(e){3!==e.which&&T&&!e.defaultPrevented&&(ft(),mt.closeDropDown())},je=function(e){var t=Fe||ye,n=v,o=e.clipboardData;if(o&&!t){var i={},r=o.types,a=o.items;e.preventDefault();for(var c=0;c<r.length;c++){if(Ne.FileReader&&a&&_e.test(a[c].type))return function(e){var t=new FileReader;t.onload=function(e){qe({html:'<img src="'+e.target.result+'" />'})},t.readAsDataURL(e)}(o.items[c].getAsFile());i[r[c]]=o.getData(r[c])}i.text=i["text/plain"],i.html=i["text/html"],qe(i)}else if(!Ce){var l=n.scrollTop;for($.saveRange(),Ce=Re.createDocumentFragment();n.firstChild;)f(Ce,n.firstChild);setTimeout(function(){var e=n.innerHTML;n.innerHTML="",f(n,Ce),n.scrollTop=l,Ce=!1,$.restoreRange(),qe({html:e})},0)}},qe=function(e){var t=c("div",{},E);K.call("pasteRaw",e),e.html?(t.innerHTML=e.html,U(t)):t.innerHTML=J(e.text||"");var o={val:t.innerHTML};"fragmentToSource"in n&&(o.val=n.fragmentToSource(o.val,E,Q)),K.call("paste",o),"fragmentToHtml"in n&&(o.val=n.fragmentToHtml(o.val,Q)),K.call("pasteHtml",o),mt.wysiwygEditorInsertHtml(o.val,null,!0)},mt.closeDropDown=function(e){T&&(d(T),T=null),!0===e&&mt.focus()},mt.wysiwygEditorInsertHtml=function(e,t,n){var o,i,r,a=_(s);mt.focus(),!n&&u(G,"code")||($.insertHTML(e,t),$.saveRange(),Te(),b(o=p(v,"#sceditor-end-marker")[0]),i=v.scrollTop,r=X(o).top+1.5*o.offsetHeight-a,y(o),(r>i||r+a<i)&&(v.scrollTop=r),st(!1),$.restoreRange(),nt())},mt.wysiwygEditorInsertText=function(e,t){mt.wysiwygEditorInsertHtml(J(e),J(t))},mt.insertText=function(e,t){return mt.inSourceMode()?mt.sourceEditorInsertText(e,t):mt.wysiwygEditorInsertText(e,t),mt},mt.sourceEditorInsertText=function(e,t){var n,o,i=S.selectionStart,r=S.selectionEnd;n=S.scrollTop,S.focus(),o=S.value,t&&(e+=o.substring(i,r)+t),S.value=o.substring(0,i)+e+o.substring(r,o.length),S.selectionStart=i+e.length-(t?t.length:0),S.selectionEnd=S.selectionStart,S.scrollTop=n,S.focus(),st()},mt.getRangeHelper=function(){return $},mt.sourceEditorCaret=function(e){return S.focus(),e?(S.selectionStart=e.start,S.selectionEnd=e.end,this):{start:S.selectionStart,end:S.selectionEnd}},mt.val=function(e,t){return ae(e)?(mt.inSourceMode()?mt.setSourceEditorValue(e):(!1!==t&&"toHtml"in n&&(e=n.toHtml(e)),mt.setWysiwygEditorValue(e)),mt):mt.inSourceMode()?mt.getSourceEditorValue(!1):mt.getWysiwygEditorValue(t)},mt.insert=function(e,t,o,i,r){if(mt.inSourceMode())return mt.sourceEditorInsertText(e,t),mt;if(t){var a=$.selectedHtml();!1!==o&&"fragmentToSource"in n&&(a=n.fragmentToSource(a,E,Q)),e+=a+t}return!1!==o&&"fragmentToHtml"in n&&(e=n.fragmentToHtml(e,Q)),!1!==o&&!0===r&&(e=e.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),mt.wysiwygEditorInsertHtml(e),mt},mt.getWysiwygEditorValue=function(e){for(var t,o=c("div",{},E),i=v.childNodes,r=0;r<i.length;r++)f(o,i[r].cloneNode(!0));return f(v,o),U(o),d(o),t=o.innerHTML,!1!==e&&n.hasOwnProperty("toSource")&&(t=n.toSource(t,E)),t},mt.getBody=function(){return v},mt.getContentAreaContainer=function(){return s},mt.getSourceEditorValue=function(e){var t=S.value;return!1!==e&&"toHtml"in n&&(t=n.toHtml(t)),t},mt.setWysiwygEditorValue=function(e){e||(e="<p>"+(Fe?"":"<br />")+"</p>"),v.innerHTML=e,Te(),nt(),st(),pt()},mt.setSourceEditorValue=function(e){S.value=e,st()},mt.updateOriginal=function(){gt.value=mt.val()},Te=function(){Ct.emoticonsEnabled&&oe(v,wt,Ct.emoticonsCompat)},mt.inSourceMode=function(){return M(a,"sourceMode")},mt.sourceMode=function(e){var t=mt.inSourceMode();return"boolean"!=typeof e?t:((t&&!e||!t&&e)&&mt.toggleSourceMode(),mt)},mt.toggleSourceMode=function(){var e=mt.inSourceMode();!xe&&e||(e||($.saveRange(),$.clear()),mt.blur(),e?mt.setWysiwygEditorValue(mt.getSourceEditorValue()):mt.setSourceEditorValue(mt.getWysiwygEditorValue()),B=null,x(S),x(s),F(a,"wysiwygMode",e),F(a,"sourceMode",!e),Ze(),et())},tt=function(){return S.focus(),S.value.substring(S.selectionStart,S.selectionEnd)},Me=function(e,t){mt.inSourceMode()?t.txtExec&&(Array.isArray(t.txtExec)?mt.sourceEditorInsertText.apply(mt,t.txtExec):t.txtExec.call(mt,e,tt())):t.exec&&(le(t.exec)?t.exec.call(mt,e):mt.execCommand(t.exec,t.hasOwnProperty("execParam")?t.execParam:null))},ze=function(){Fe&&(B=$.selectedRange())},mt.execCommand=function(e,t){var n=!1,o=mt.commands[e];if(mt.focus(),!u($.parentNode(),"code")){try{n=E.execCommand(e,!1,t)}catch(e){}!n&&o&&o.errorMessage&&alert(mt._(o.errorMessage)),et()}},ot=function(){function e(){if($&&!$.compare(Z)){if((Z=$.cloneSelected())&&Z.collapsed){var e=Z.startContainer,t=Z.startOffset;for(t&&e.nodeType!==fe&&(e=e.childNodes[t]);e&&e.parentNode!==v;)e=e.parentNode;e&&j(e,!0)&&($.saveRange(),ie(v,E),$.restoreRange())}z(a,"selectionchanged")}se=!1}se||(se=!0,"onselectionchange"in E?e():setTimeout(e,100))},it=function(){var e,t=$.parentNode();Q!==t&&(e=Q,Q=t,G=$.getFirstBlockParent(t),z(a,"nodechanged",{oldNode:e,newNode:Q}))},mt.currentNode=function(){return Q},mt.currentBlockNode=function(){return G},et=function(){var e,t,n=E,o=mt.sourceMode();if(mt.readOnly())r(p(l,"active"),function(e,t){R(t,"active")});else{o||(t=$.parentNode(),e=$.getFirstBlockParent(t));for(var i=0;i<yt.length;i++){var a=0,c=xt[yt[i].name],s=yt[i].state,u=o&&!c._sceTxtMode||!o&&!c._sceWysiwygMode;if(ae(s)){if(!o)try{(a=n.queryCommandEnabled(s)?0:-1)>-1&&(a=n.queryCommandState(s)?1:0)}catch(e){}}else u||(a=s.call(mt,t,e));F(c,"disabled",u||a<0),F(c,"active",a>0)}Ee&&Ee.update&&Ee.update(o,t,e)}},Ye=function(e){if(!e.defaultPrevented&&(mt.closeDropDown(),13===e.which)){if(!k(G,"li,ul,ol")&&P(G)){B=null;var t=c("br",{},E);if($.insertNode(t),!He){var n=t.parentNode,o=n.lastChild;o&&o.nodeType===fe&&""===o.nodeValue&&(d(o),o=n.lastChild),!j(n,!0)&&o===t&&j(t.previousSibling)&&$.insertHTML("<br>")}e.preventDefault()}}},nt=function(){I(v,function(e){if(e.nodeType===de&&!/inline/.test(w(e,"display"))&&!k(e,".sceditor-nlf")&&P(e)){var t=c("p",{},E);return t.className="sceditor-nlf",t.innerHTML=He?"":"<br />",f(v,t),!1}if(3===e.nodeType&&!/^\s*$/.test(e.nodeValue)||k(e,"br"))return!1})},Ke=function(){mt.val(gt.value)},Xe=function(){mt.closeDropDown(),B=null},mt._=function(){var e=arguments;return q&&q[e[0]]&&(e[0]=q[e[0]]),e[0].replace(/\{(\d+)\}/g,function(t,n){return void 0!==e[n-0+1]?e[n-0+1]:"{"+n+"}"})},Ge=function(e){K&&K.call(e.type+"Event",e,mt);var t=(e.target===S?"scesrc":"scewys")+e.type;ht[t]&&ht[t].forEach(function(t){t.call(mt,e)})},mt.bind=function(e,t,n,o){for(var i=(e=e.split(" ")).length;i--;)if(le(t)){var r="scewys"+e[i],a="scesrc"+e[i];n||(ht[r]=ht[r]||[],ht[r].push(t)),o||(ht[a]=ht[a]||[],ht[a].push(t)),"valuechanged"===e[i]&&(st.hasHandler=!0)}return mt},mt.unbind=function(e,t,n,o){for(var r=(e=e.split(" ")).length;r--;)le(t)&&(n||i(ht["scewys"+e[r]]||[],t),o||i(ht["scesrc"+e[r]]||[],t));return mt},mt.blur=function(e,t,n){return le(e)?mt.bind("blur",e,t,n):mt.sourceMode()?S.blur():v.blur(),mt},mt.focus=function(e,t,n){if(le(e))mt.bind("focus",e,t,n);else if(mt.inSourceMode())S.focus();else{if(p(E,":focus").length)return;var o,i=$.selectedRange();Z||rt(),!He&&i&&1===i.endOffset&&i.collapsed&&(o=i.endContainer)&&1===o.childNodes.length&&k(o.firstChild,"br")&&(i.setStartBefore(o.firstChild),i.collapse(!0),$.selectRange(i)),s.contentWindow.focus(),v.focus(),B&&($.selectRange(B),B=null)}return et(),mt},mt.keyDown=function(e,t,n){return mt.bind("keydown",e,t,n)},mt.keyPress=function(e,t,n){return mt.bind("keypress",e,t,n)},mt.keyUp=function(e,t,n){return mt.bind("keyup",e,t,n)},mt.nodeChanged=function(e){return mt.bind("nodechanged",e,!1,!0)},mt.selectionChanged=function(e){return mt.bind("selectionchanged",e,!1,!0)},mt.valueChanged=function(e,t,n){return mt.bind("valuechanged",e,t,n)},at=function(e){var t=0,n=mt.emoticonsCache,o=String.fromCharCode(e.which);u(G,"code")||(n||(n=[],r(wt,function(e,o){n[t++]=[e,o]}),n.sort(function(e,t){return e[0].length-t[0].length}),mt.emoticonsCache=n,mt.longestEmoticonCode=n[n.length-1][0].length),$.replaceKeyword(mt.emoticonsCache,!0,!0,mt.longestEmoticonCode,Ct.emoticonsCompat,o)&&(Ct.emoticonsCompat&&/^\s$/.test(o)||e.preventDefault()))},ct=function(){ne(G,$)},mt.emoticons=function(e){return e||!1===e?(Ct.emoticonsEnabled=e,e?(m(v,"keypress",at),mt.sourceMode()||($.saveRange(),Te(),st(!1),$.restoreRange())):(r(p(v,"img[data-sceditor-emoticon]"),function(e,t){var n=C(t,"sceditor-emoticon"),o=E.createTextNode(n);t.parentNode.replaceChild(o,t)}),g(v,"keypress",at),st()),mt):Ct.emoticonsEnabled},mt.css=function(e){return me||(me=c("style",{id:"inline"},E),f(E.head,me)),ae(e)?(me.styleSheet?me.styleSheet.cssText=e:me.innerHTML=e,mt):me.styleSheet?me.styleSheet.cssText:me.innerHTML},Ue=function(e){var t=[],n={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},o={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},i={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},r=e.which,a=o[r]||String.fromCharCode(r).toLowerCase();(e.ctrlKey||e.metaKey)&&t.push("ctrl"),e.altKey&&t.push("alt"),e.shiftKey&&(t.push("shift"),i[r]?a=i[r]:n[a]&&(a=n[a])),a&&(r<16||r>18)&&t.push(a),t=t.join("+"),bt[t]&&!1===bt[t].call(mt)&&(e.stopPropagation(),e.preventDefault())},mt.addShortcut=function(e,t){return e=e.toLowerCase(),ae(t)?bt[e]=function(){return Me(xt[t],mt.commands[t]),!1}:bt[e]=t,mt},mt.removeShortcut=function(e){return delete bt[e.toLowerCase()],mt},$e=function(e){var t,n,o;if(!Ct.disableBlockRemove&&8===e.which&&(n=$.selectedRange())&&(t=n.startContainer,0===n.startOffset&&(o=lt()))){for(;t!==o;){for(;t.previousSibling;)if((t=t.previousSibling).nodeType!==fe||t.nodeValue)return;if(!(t=t.parentNode))return}o&&!k(o,"body")&&(mt.clearBlockFormatting(o),e.preventDefault())}},lt=function(){for(var e=G;!P(e)||j(e,!0);)if(!(e=e.parentNode)||k(e,"body"))return;return e},mt.clearBlockFormatting=function(e){return!(e=e||lt())||k(e,"body")?mt:($.saveRange(),e.className="",B=null,h(e,"style",""),k(e,"p,div,td")||V(e,"p"),$.restoreRange(),mt)},st=function(e){if(K&&(K.hasHandler("valuechangedEvent")||st.hasHandler)){var t,n=mt.sourceMode(),o=!n&&$.hasSelection();A=!1,e=!1!==e&&!E.getElementById("sceditor-start-marker"),L&&(clearTimeout(L),L=!1),o&&e&&$.saveRange(),(t=n?S.value:v.innerHTML)!==st.lastVal&&(st.lastVal=t,z(a,"valuechanged",{rawValue:n?mt.val():t})),o&&e&&$.removeMarkers()}},ut=function(){L&&st()},dt=function(e){var t=e.which,n=dt.lastChar,o=13===n||32===n,i=8===n||46===n;dt.lastChar=t,A||(13===t||32===t?o?dt.triggerNext=!0:st():8===t||46===t?i?dt.triggerNext=!0:st():dt.triggerNext&&(st(),dt.triggerNext=!1),clearTimeout(L),L=setTimeout(function(){A||st()},1500))},Qe=function(e){(A=/start/i.test(e.type))||st()},ft=function(){mt.updateOriginal()},De()}e=e&&e.hasOwnProperty("default")?e.default:e;var ae=t.bind(null,"string"),ce=t.bind(null,"undefined"),le=t.bind(null,"function"),se=t.bind(null,"number"),ue={},de=1,fe=3,pe=!0,me="|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|",ge={toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:"#000000,#44B8FF,#1E92F7,#0074D9,#005DC2,#00369B,#b3d5f4|#444444,#C3FFFF,#9DF9FF,#7FDBFF,#68C4E8,#419DC1,#d9f4ff|#666666,#72FF84,#4CEA5E,#2ECC40,#17B529,#008E02,#c0f0c6|#888888,#FFFF44,#FFFA1E,#FFDC00,#E8C500,#C19E00,#fff5b3|#aaaaaa,#FFC95F,#FFA339,#FF851B,#E86E04,#C14700,#ffdbbb|#cccccc,#FF857A,#FF5F54,#FF4136,#E82A1F,#C10300,#ffc6c3|#eeeeee,#FF56FF,#FF30DC,#F012BE,#D900A7,#B20080,#fbb8ec|#ffffff,#F551FF,#CF2BE7,#B10DC9,#9A00B2,#9A00B2,#e8b6ef",locale:h(document.documentElement,"lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}},he=navigator.userAgent,ve=function(){var e=3,t=document,n=t.createElement("div"),o=n.getElementsByTagName("i");do{n.innerHTML="\x3c!--[if gt IE "+ ++e+"]><i></i><![endif]--\x3e"}while(o[0]);return t.documentMode&&t.all&&window.atob&&(e=10),4===e&&t.documentMode&&(e=11),e>4?e:void 0}(),ye="-ms-ime-align"in document.documentElement.style,be=/iPhone|iPod|iPad| wosbrowser\//i.test(he),xe=function(){var e,t,n=document.createElement("div");return n.contentEditable=!0,"contentEditable"in document.documentElement&&"true"===n.contentEditable&&(t=/Opera Mobi|Opera Mini/i.test(he),/Android/i.test(he)&&(t=!0,/Safari/.test(he)&&(t=!(e=/Safari\/(\d+)/.exec(he))||!e[1]||e[1]<534)),/ Silk\//i.test(he)&&(t=!(e=/AppleWebKit\/(\d+)/.exec(he))||!e[1]||e[1]<534),be&&(t=/OS [0-4](_\d)+ like Mac/i.test(he)),/Firefox/i.test(he)&&(t=!1),/OneBrowser/i.test(he)&&(t=!1),"UCWEB"===navigator.vendor&&(t=!1),ve<=9&&(t=!0),!t)}(),we=/^(https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(\/\/)|data:image\/(png|bmp|gif|p?jpe?g);/i,Ce={html:'<!DOCTYPE html><html{attrs}><head><style>.ie * {min-height: auto !important} .ie table td {height:15px} @supports (-ms-ime-align:auto) { * { min-height: auto !important; } }</style><meta http-equiv="Content-Type" content="text/html;charset={charset}" /><link rel="stylesheet" type="text/css" href="{style}" /></head><body contenteditable="true" {spellcheck}><p></p></body></html>',toolbarButton:'<a class="sceditor-button sceditor-button-{name}" data-sceditor-command="{name}" unselectable="on"><div unselectable="on">{dispName}</div></a>',emoticon:'<img src="{url}" data-sceditor-emoticon="{key}" alt="{key}" title="{tooltip}" />',fontOpt:'<a class="sceditor-font-option" href="#" data-font="{font}"><font face="{font}">{font}</font></a>',sizeOpt:'<a class="sceditor-fontsize-option" data-size="{size}" href="#"><font size="{size}">{size}</font></a>',pastetext:'<div><label for="txt">{label}</label> <textarea cols="20" rows="7" id="txt"></textarea></div><div><input type="button" class="button" value="{insert}" /></div>',table:'<div><label for="rows">{rows}</label><input type="text" id="rows" value="2" /></div><div><label for="cols">{cols}</label><input type="text" id="cols" value="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',image:'<div><label for="link">{url}</label> <input type="text" id="image" placeholder="https://" /></div><div><label for="width">{width}</label> <input type="text" id="width" size="2" /></div><div><label for="height">{height}</label> <input type="text" id="height" size="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',email:'<div><label for="email">{label}</label> <input type="text" id="email" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{insert}" /></div>',link:'<div><label for="link">{url}</label> <input type="text" id="link" placeholder="https://" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{ins}" /></div>',youtubeMenu:'<div><label for="link">{label}</label> <input type="text" id="link" placeholder="https://" /></div><div><input type="button" class="button" value="{insert}" /></div>',youtube:'<iframe width="560" height="315" frameborder="0" allowfullscreensrc="https://www.youtube.com/embed/{id}?wmode=opaque&start={time}" data-youtube-id="{id}"></iframe>'},ke=function(e,t,n){var o=Ce[e];return Object.keys(t).forEach(function(e){o=o.replace(new RegExp(G("{"+e+"}"),"g"),t[e])}),n&&(o=L(o)),o},Ee=ve&&ve<11,Se={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(e,t,n){var o=c("div");m(o,"click","a",function(t){n(C(this,"font")),e.closeDropDown(!0),t.preventDefault()}),e.opts.fonts.split(",").forEach(function(e){f(o,ke("fontOpt",{font:e},!0))}),e.createDropDown(t,"font-picker",o)},exec:function(e){var t=this;Se.font._dropDown(t,e,function(e){t.execCommand("fontname",e)})},tooltip:"Font Name"},size:{_dropDown:function(e,t,n){var o=c("div");m(o,"click","a",function(t){n(C(this,"size")),e.closeDropDown(!0),t.preventDefault()});for(var i=1;i<=7;i++)f(o,ke("sizeOpt",{size:i},!0));e.createDropDown(t,"fontsize-picker",o)},exec:function(e){var t=this;Se.size._dropDown(t,e,function(e){t.execCommand("fontsize",e)})},tooltip:"Font Size"},color:{_dropDown:function(e,t,n){var o=c("div"),i="",r=Se.color;r._htmlCache||(e.opts.colors.split("|").forEach(function(e){i+='<div class="sceditor-color-column">',e.split(",").forEach(function(e){i+='<a href="#" class="sceditor-color-option" style="background-color: '+e+'" data-color="'+e+'"></a>'}),i+="</div>"}),r._htmlCache=i),f(o,L(r._htmlCache)),m(o,"click","a",function(t){n(C(this,"color")),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"color-picker",o)},exec:function(e){var t=this;Se.color._dropDown(t,e,function(e){t.execCommand("forecolor",e)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(e){var t,n=c("div"),o=this;f(n,ke("pastetext",{label:o._("Paste your text inside the following box:"),insert:o._("Insert")},!0)),m(n,"click",".button",function(e){(t=p(n,"#txt")[0].value)&&o.wysiwygEditorInsertText(t),o.closeDropDown(!0),e.preventDefault()}),o.createDropDown(e,"pastetext",n)},tooltip:"Paste Text"},bulletlist:{exec:function(){Z(this),this.execCommand("insertunorderedlist")},tooltip:"Bullet list"},orderedlist:{exec:function(){Z(this),this.execCommand("insertorderedlist")},tooltip:"Numbered list"},indent:{state:function(e,t){var n,o,i,r=l(t,"ul,ol,menu");return r.length>1&&r[0].children.length>1?0:k(t,"ul,ol,menu")&&(n=this.getRangeHelper().selectedRange(),o=n.startContainer.parentNode,i=n.endContainer.parentNode,o!==o.parentNode.firstElementChild||k(i,"li")&&i!==i.parentNode.lastElementChild)?0:-1},exec:function(){var e=this,t=e.getRangeHelper().getFirstBlockParent();e.focus(),l(t,"ul,ol,menu")&&e.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(e,t){return u(t,"ul,ol,menu")>0?0:-1},exec:function(){l(this.getRangeHelper().getFirstBlockParent(),"ul,ol,menu")&&this.execCommand("outdent")},tooltip:"Remove one indent"},table:{exec:function(e){var t=this,n=c("div");f(n,ke("table",{rows:t._("Rows:"),cols:t._("Cols:"),insert:t._("Insert")},!0)),m(n,"click",".button",function(e){var o=Number(p(n,"#rows")[0].value),i=Number(p(n,"#cols")[0].value),r="<table>";o>0&&i>0&&(r+=Array(o+1).join("<tr>"+Array(i+1).join("<td>"+(Ee?"":"<br />")+"</td>")+"</tr>"),r+="</table>",t.wysiwygEditorInsertHtml(r),t.closeDropDown(!0),e.preventDefault())}),t.createDropDown(e,"inserttable",n)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{exec:function(){this.wysiwygEditorInsertHtml("<code>",(Ee?"":"<br />")+"</code>")},tooltip:"Code"},image:{_dropDown:function(e,t,n,o){var i=c("div");f(i,ke("image",{url:e._("URL:"),width:e._("Width (optional):"),height:e._("Height (optional):"),insert:e._("Insert")},!0));var r=p(i,"#image")[0];r.value=n,m(i,"click",".button",function(t){r.value&&o(r.value,p(i,"#width")[0].value,p(i,"#height")[0].value),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertimage",i)},exec:function(e){var t=this;Se.image._dropDown(t,e,"",function(e,n,o){var i="";n&&(i+=' width="'+n+'"'),o&&(i+=' height="'+o+'"'),t.wysiwygEditorInsertHtml("<img"+i+' src="'+e+'" />')})},tooltip:"Insert an image"},email:{_dropDown:function(e,t,n){var o=c("div");f(o,ke("email",{label:e._("E-mail:"),desc:e._("Description (optional):"),insert:e._("Insert")},!0)),m(o,"click",".button",function(t){var i=p(o,"#email")[0].value;i&&n(i,p(o,"#des")[0].value),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertemail",o)},exec:function(e){var t=this;Se.email._dropDown(t,e,function(e,n){t.focus(),!t.getRangeHelper().selectedHtml()||n?t.wysiwygEditorInsertHtml('<a href="mailto:'+e+'">'+(n||e)+"</a>"):t.execCommand("createlink","mailto:"+e)})},tooltip:"Insert an email"},link:{_dropDown:function(e,t,n){function o(t){r.value&&n(r.value,p(i,"#des")[0].value),e.closeDropDown(!0),t.preventDefault()}var i=c("div");f(i,ke("link",{url:e._("URL:"),desc:e._("Description (optional):"),ins:e._("Insert")},!0));var r=p(i,"#link")[0];m(i,"click",".button",o),m(i,"keypress",function(e){13===e.which&&r.value&&o(e)},pe),e.createDropDown(t,"insertlink",i)},exec:function(e){var t=this;Se.link._dropDown(t,e,function(e,n){t.focus(),!t.getRangeHelper().selectedHtml()||n?(n=n||e,t.wysiwygEditorInsertHtml('<a href="'+e+'">'+n+"</a>")):t.execCommand("createlink",e)})},tooltip:"Insert a link"},unlink:{state:function(){return u(this.currentNode(),"a")?0:-1},exec:function(){var e=u(this.currentNode(),"a");if(e){for(;e.firstChild;)D(e.firstChild,e);d(e)}},tooltip:"Unlink"},quote:{exec:function(e,t,n){var o="<blockquote>",i="</blockquote>";t?(o=o+(n=n?"<cite>"+n+"</cite>":"")+t+i,i=null):""===this.getRangeHelper().selectedHtml()&&(i=(Ee?"":"<br />")+i),this.wysiwygEditorInsertHtml(o,i)},tooltip:"Insert a Quote"},emoticon:{exec:function(e){var t=this,n=function(i){var a,l=t.opts.emoticonsCompat,s=t.getRangeHelper(),u=l&&" "!==s.getOuterText(!0,1)?" ":"",d=l&&" "!==s.getOuterText(!1,1)?" ":"",p=c("div"),g=c("div"),v=0,y=o({},t.opts.emoticons.dropdown,i?t.opts.emoticons.more:{});return f(p,g),v=Math.sqrt(Object.keys(y).length),m(p,"click","img",function(e){t.insert(u+h(this,"alt")+d,null,!1).closeDropDown(!0),e.preventDefault()}),r(y,function(e,t){f(g,c("img",{src:t.url||t,alt:e,title:t.tooltip||e})),g.children.length>=v&&(g=c("div"),f(p,g))}),!i&&t.opts.emoticons.more&&(f(a=c("a",{className:"sceditor-more"}),document.createTextNode(t._("More"))),m(a,"click",function(o){t.createDropDown(e,"more-emoticons",n(!0)),o.preventDefault()}),f(p,a)),p};t.createDropDown(e,"emoticons",n(!1))},txtExec:function(e){Se.emoticon.exec.call(this,e)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(e,t,n){var o=c("div");f(o,ke("youtubeMenu",{label:e._("Video URL:"),insert:e._("Insert")},!0)),m(o,"click",".button",function(t){var i=p(o,"#link")[0].value,a=i.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),c=i.match(/[&|?](?:star)?t=((\d+[hms]?){1,3})/),l=0;c&&r(c[1].split(/[hms]/),function(e,t){""!==t&&(l=60*l+Number(t))}),a&&/^[a-zA-Z0-9_\-]{11}$/.test(a[1])&&n(a[1],l),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertlink",o)},exec:function(e){var t=this;Se.youtube._dropDown(t,e,function(e,n){t.wysiwygEditorInsertHtml(ke("youtube",{id:e,time:n}))})},tooltip:"Insert a YouTube video"},date:{_date:function(e){var t=new Date,n=t.getYear(),o=t.getMonth()+1,i=t.getDate();return n<2e3&&(n=1900+n),o<10&&(o="0"+o),i<10&&(i="0"+i),e.opts.dateFormat.replace(/year/i,n).replace(/month/i,o).replace(/day/i,i)},exec:function(){this.insertText(Se.date._date(this))},txtExec:function(){this.insertText(Se.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var e=new Date,t=e.getHours(),n=e.getMinutes(),o=e.getSeconds();return t<10&&(t="0"+t),n<10&&(n="0"+n),o<10&&(o="0"+o),t+":"+n+":"+o},exec:function(){this.insertText(Se.time._time())},txtExec:function(){this.insertText(Se.time._time())},tooltip:"Insert current time"},ltr:{state:function(e,t){return t&&"ltr"===t.style.direction},exec:function(){var e=this,t=e.getRangeHelper(),n=t.getFirstBlockParent();e.focus(),(n&&!k(n,"body")||(e.execCommand("formatBlock","p"),(n=t.getFirstBlockParent())&&!k(n,"body")))&&w(n,"direction","ltr"===w(n,"direction")?"":"ltr")},tooltip:"Left-to-Right"},rtl:{state:function(e,t){return t&&"rtl"===t.style.direction},exec:function(){var e=this,t=e.getRangeHelper(),n=t.getFirstBlockParent();e.focus(),(n&&!k(n,"body")||(e.execCommand("formatBlock","p"),(n=t.getFirstBlockParent())&&!k(n,"body")))&&w(n,"direction","rtl"===w(n,"direction")?"":"rtl")},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}},De={};ee.plugins=De;var Te=ve&&ve<11,Me=function(e,t,n){var o,i,r,a,c,l="",s=e.startContainer,u=e.startOffset;for(s&&3!==s.nodeType&&(s=s.childNodes[u],u=0),r=a=u;n>l.length&&s&&3===s.nodeType;)o=s.nodeValue,i=n-l.length,c&&(a=o.length,r=0),c=s,t?(u=r=Math.max(a-i,0),l=o.substr(r,a-r)+l,s=c.previousSibling):(u=r+(a=Math.min(i,o.length)),l+=o.substr(r,a),s=c.nextSibling);return{node:c||s,offset:u,text:l}},Ne=window,Re=document,Fe=ve,He=Fe&&Fe<11,_e=/^image\/(p?jpe?g|gif|png|bmp)$/i;re.locale={},re.formats={},re.icons={},re.command={get:function(e){return Se[e]||null},set:function(e,t){return!(!e||!t)&&(t=o(Se[e]||{},t),t.remove=function(){re.command.remove(e)},Se[e]=t,this)},remove:function(e){return Se[e]&&delete Se[e],this}},window.sceditor={command:re.command,commands:Se,defaultOptions:ge,ie:ve,ios:be,isWysiwygSupported:xe,regexEscape:G,escapeEntities:J,escapeUriScheme:function(e){var t,n=/^[^\/]*:/i,o=window.location;return e&&n.test(e)&&!we.test(e)?((t=o.pathname.split("/")).pop(),o.protocol+"//"+o.host+t.join("/")+"/"+e):e},dom:{css:w,attr:h,removeAttr:v,is:k,closest:u,width:H,height:_,traverse:A,rTraverse:I,parseHTML:L,hasStyling:P,convertElement:V,blockLevelList:me,canHaveChildren:W,isInline:j,copyCSS:q,fixNesting:U,findCommonAncestor:function(e,t){for(;e=e.parentNode;)if(E(e,t))return e},getSibling:$,removeWhiteSpace:Y,extractContents:K,getOffset:X,getStyle:Q,hasStyle:function(e,t,n){var o=Q(e,t);return!!o&&(!n||o===n||Array.isArray(n)&&n.indexOf(o)>-1)}},locale:re.locale,icons:re.icons,utils:{each:r,isEmptyObject:n,extend:o},plugins:ee.plugins,formats:re.formats,create:function(e,t){t=t||{},s(e,".sceditor-container")||(t.runWithoutWysiwygSupport||xe)&&new re(e,t)},instance:function(e){return e._sceditor}},e.sceditor=window.sceditor,e.fn.sceditor=function(t){var n,o=[];return this.each(function(){n=this._sceditor,"state"===t?o.push(!!n):"instance"===t?o.push(n):n||e.sceditor.create(this,t)}),o.length?1===o.length?o[0]:o:this}}(jQuery); |
@@ -1,3 +0,3 @@ | ||
/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ | ||
!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(2),e=c(3),f=c(6),g=c(7);b.sceditor=d,d.commands=c(9),d.defaultOptions=c(10),d.RangeHelper=c(4),d.dom=c(5),d.ie=f.ie,d.ios=f.ios,d.isWysiwygSupported=f.isWysiwygSupported,d.regexEscape=g.regex,d.escapeEntities=g.entities,d.escapeUriScheme=g.uriScheme,d.PluginManager=e,d.plugins=e.plugins,b.fn.sceditor=function(a){var c,e,g=[];if(a=a||{},a.runWithoutWysiwygSupport||f.isWysiwygSupported)return this.each(function(){c=this.jquery?this:b(this),e=c.data("sceditor"),c.parents(".sceditor-container").length>0||("state"===a?g.push(!!e):"instance"===a?g.push(e):e||new d(this,a))}),g.length?1===g.length?g[0]:b(g):this}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports=jQuery},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(3),e=c(4),f=c(5),g=c(7),h=c(6),i=c(8),j=window,k=document,l=b(j),m=b(k),n=h.ie,o=n&&n<11,p=function(a,c){var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua=this,va=a.get?a.get(0):a,wa=b(va),xa=[],ya=[],za=[],Aa={},Ba=[],Ca={};ua.commands=b.extend(!0,{},c.commands||p.commands),ua.opts=c=b.extend({},p.defaultOptions,c),K=function(){wa.data("sceditor",ua),b.each(c,function(a,d){b.isPlainObject(d)&&(c[a]=b.extend(!0,{},d))}),c.locale&&"en"!==c.locale&&Q(),q=b('<div class="sceditor-container" />').insertAfter(wa).css("z-index",c.zIndex),n&&q.addClass("ie ie"+n),H=!!wa.attr("required"),wa.removeAttr("required"),P(),W(),R(),O(!!c.startInSourceMode),U(),S(),T(),h.isWysiwygSupported||ua.toggleSourceMode(),ha();var a=function(){l.off("load",a),c.autofocus&&ma(),c.autoExpand&&ua.expandToContent(),fa(),C.call("ready")};l.on("load",a),k.readyState&&"complete"===k.readyState&&a()},P=function(){var a=c.plugins;a=a?a.toString().split(","):[],C=new d(ua),b.each(a,function(a,c){C.register(b.trim(c))})},Q=function(){var a;A=p.locale[c.locale],A||(a=c.locale.split("-"),A=p.locale[a[0]]),A&&A.dateFormat&&(c.dateFormat=A.dateFormat)},O=function(a){var d,f;w=b("<textarea></textarea>"),s=b('<iframe frameborder="0" allowfullscreen="true"></iframe>'),a?(q.addClass("sourceMode"),s.hide()):(q.addClass("wysiwygMode"),w.hide()),c.spellcheck||w.attr("spellcheck","false"),"https:"===j.location.protocol&&s.attr("src","javascript:false"),q.append(s).append(w),t=s[0],x=w[0],ua.dimensions(c.width||wa.width(),c.height||wa.height()),d=X(),d.open(),d.write(i("html",{attrs:n?' class="ie ie'+n+'"':"",spellcheck:c.spellcheck?"":'spellcheck="false"',charset:c.charset,style:c.style})),d.close(),v=b(d),u=b(d.body),ua.readOnly(!!c.readOnly),(h.ios||n)&&(u.height("100%"),n||u.on("touchend",ua.focus)),f=wa.attr("tabindex"),w.attr("tabindex",f),s.attr("tabindex",f),B=new e(t.contentWindow),ua.val(wa.hide().val())},S=function(){c.autoUpdate&&(u.on("blur",ta),w.on("blur",ta)),null===c.rtl&&(c.rtl="rtl"===w.css("direction")),ua.rtl(!!c.rtl),c.autoExpand&&v.on("keyup",ua.expandToContent),c.resizeEnabled&&V(),q.attr("id",c.id),ua.emoticons(c.emoticonsEnabled)},T=function(){var a=n?"selectionchange":"keyup focus blur contextmenu mouseup touchend click",d="keydown keyup keypress focus blur contextmenu";m.click(ea),b(va.form).on("reset",ba).submit(ua.updateOriginal),l.on("resize orientationChanged",fa),u.keypress(aa).keydown($).keydown(_).keyup(ja).blur(ra).keyup(sa).on("paste",Y).on(a,ka).on(d,da),c.emoticonsCompat&&j.getSelection&&u.keyup(oa),w.blur(ra).keyup(sa).keydown($).on(d,da),v.mousedown(ca).blur(ra).on(a,ka).on("beforedeactivate keyup mouseup",N).keyup(ja).focus(function(){z=null}),q.on("selectionchanged",la).on("selectionchanged",ha).on("selectionchanged valuechanged nodechanged",da)},R=function(){var a,d=ua.commands,e=(c.toolbarExclude||"").split(","),f=c.toolbar.split("|");r=b('<div class="sceditor-toolbar" unselectable="on" />'),b.each(f,function(c,f){a=b('<div class="sceditor-group" />'),b.each(f.split(","),function(c,f){var g,h,j=d[f];!j||b.inArray(f,e)>-1||(h=j.shortcut,g=i("toolbarButton",{name:f,dispName:ua._(j.name||j.tooltip||f)},!0),g.data("sceditor-txtmode",!!j.txtExec).data("sceditor-wysiwygmode",!!j.exec).toggleClass("disabled",!j.exec).mousedown(function(){(!n||n<9)&&(J=!0)}).click(function(){var a=b(this);return a.hasClass("disabled")||M(a,j),ha(),!1}),j.tooltip&&g.attr("title",ua._(j.tooltip)+(h?" ("+h+")":"")),h&&ua.addShortcut(h,f),j.state?za.push({name:f,state:j.state}):"string"==typeof j.exec&&za.push({name:f,state:j.exec}),a.append(g),Ca[f]=g)}),a[0].firstChild&&r.append(a)}),b(c.toolbarContainer||q).append(r)},U=function(){b.each(ua.commands,function(a,c){c.forceNewLineAfter&&b.isArray(c.forceNewLineAfter)&&(ya=b.merge(ya,c.forceNewLineAfter))}),ja()},V=function(){var a,d,e,f,g,h,i=b('<div class="sceditor-grip" />'),k=b('<div class="sceditor-resize-cover" />'),l="touchmove mousemove",o="touchcancel touchend mouseup",p=0,r=0,s=0,t=0,u=0,v=0,w=q.width(),x=q.height(),y=!1,z=ua.rtl();a=c.resizeMinHeight||x/1.5,d=c.resizeMaxHeight||2.5*x,e=c.resizeMinWidth||w/1.25,f=c.resizeMaxWidth||1.25*w,g=function(b){"touchmove"===b.type?(b=j.event,s=b.changedTouches[0].pageX,t=b.changedTouches[0].pageY):(s=b.pageX,t=b.pageY);var g=v+(t-r),h=z?u-(s-p):u+(s-p);f>0&&h>f&&(h=f),e>0&&h<e&&(h=e),c.resizeWidth||(h=!1),d>0&&g>d&&(g=d),a>0&&g<a&&(g=a),c.resizeHeight||(g=!1),(h||g)&&(ua.dimensions(h,g),n<7&&q.height(g)),b.preventDefault()},h=function(a){y&&(y=!1,k.hide(),q.removeClass("resizing").height("auto"),m.off(l,g),m.off(o,h),a.preventDefault())},q.append(i),q.append(k.hide()),i.on("touchstart mousedown",function(a){"touchstart"===a.type?(a=j.event,p=a.touches[0].pageX,r=a.touches[0].pageY):(p=a.pageX,r=a.pageY),u=q.width(),v=q.height(),y=!0,q.addClass("resizing"),k.show(),m.on(l,g),m.on(o,h),n<7&&q.height(v),a.preventDefault()})},W=function(){var a,d=c.emoticons,e=c.emoticonsRoot;b.isPlainObject(d)&&c.emoticonsEnabled&&b.each(d,function(c,f){b.each(f,function(b,f){e&&(f={url:e+(f.url||f),tooltip:f.tooltip||b},d[c][b]=f),a=k.createElement("img"),a.src=f.url||f,xa.push(a)})})},ma=function(){var a,d,e=v[0],g=u[0],h=g.firstChild,i=!!c.autofocusEnd;if(q.is(":visible")){if(ua.sourceMode())return d=i?x.value.length:0,void(x.setSelectionRange?x.setSelectionRange(d,d):(a=x.createTextRange(),a.moveEnd("character",d),a.collapse(!1),a.select()));if(f.removeWhiteSpace(g),i)for((h=g.lastChild)||(h=e.createElement("p"),u.append(h));h.lastChild;)h=h.lastChild,!o&&b(h).is("br")&&h.previousSibling&&(h=h.previousSibling);e.createRange?(a=e.createRange(),f.canHaveChildren(h)?a.selectNodeContents(h):(a.setStartBefore(h),i&&a.setStartAfter(h))):(a=g.createTextRange(),a.moveToElementText(3!==h.nodeType?h:h.parentNode)),a.collapse(!i),B.selectRange(a),F=a,i&&(v.scrollTop(g.scrollHeight),u.scrollTop(g.scrollHeight)),ua.focus()}},ua.readOnly=function(a){return"boolean"!=typeof a?"readonly"===w.attr("readonly"):(u[0].contentEditable=!a,a?w.attr("readonly","readonly"):w.removeAttr("readonly"),ga(a),ua)},ua.rtl=function(a){var b=a?"rtl":"ltr";return"boolean"!=typeof a?"rtl"===w.attr("dir"):(u.attr("dir",b),w.attr("dir",b),q.removeClass("rtl").removeClass("ltr").addClass(b),ua)},ga=function(a){var c=ua.inSourceMode()?"txtmode":"wysiwygmode";b.each(Ca,function(b,d){a!==!0&&d.data("sceditor-"+c)?d.removeClass("disabled"):d.addClass("disabled")})},ua.width=function(a,b){return a||0===a?(ua.dimensions(a,null,b),ua):q.width()},ua.dimensions=function(a,b,d){var e,f=n<8||k.documentMode<8?2:0;return a=!(!a&&0!==a)&&a,b=!(!b&&0!==b)&&b,a===!1&&b===!1?{width:ua.width(),height:ua.height()}:(s.data("outerWidthOffset")===e&&ua.updateStyleCache(),a!==!1&&(d!==!1&&(c.width=a),b===!1&&(b=q.height(),d=!1),q.width(a),a&&a.toString().indexOf("%")>-1&&(a=q.width()),s.width(a-s.data("outerWidthOffset")),w.width(a-w.data("outerWidthOffset")),h.ios&&u&&u.width(a-s.data("outerWidthOffset")-(u.outerWidth(!0)-u.width()))),b!==!1&&(d!==!1&&(c.height=b),b&&b.toString().indexOf("%")>-1&&(b=q.height(b).height(),q.height("auto")),b-=c.toolbarContainer?0:r.outerHeight(!0),s.height(b-s.data("outerHeightOffset")),w.height(b-f-w.data("outerHeightOffset"))),ua)},ua.updateStyleCache=function(){s.data("outerWidthOffset",s.outerWidth(!0)-s.width()),w.data("outerWidthOffset",w.outerWidth(!0)-w.width()),s.data("outerHeightOffset",s.outerHeight(!0)-s.height()),w.data("outerHeightOffset",w.outerHeight(!0)-w.height())},ua.height=function(a,b){return a||0===a?(ua.dimensions(null,a,b),ua):q.height()},ua.maximize=function(a){return"undefined"==typeof a?q.is(".sceditor-maximize"):(a=!!a,n<7&&b("html, body").toggleClass("sceditor-maximize",a),q.toggleClass("sceditor-maximize",a),ua.width(a?"100%":c.width,!1),ua.height(a?"100%":c.height,!1),ua)},ua.expandToContent=function(a){var b=q.height(),d=b-s.height(),e=u[0].scrollHeight||v[0].documentElement.scrollHeight,f=c.resizeMaxHeight||2*(c.height||wa.height());e+=d,(a===!0||e<=f)&&e>b&&ua.height(e)},ua.destroy=function(){C&&(C.destroy(),B=null,z=null,C=null,y&&y.off().remove(),m.off("click",ea),l.off("resize orientationChanged",fa),b(va.form).off("reset",ba).off("submit",ua.updateOriginal),u.off(),v.off().find("*").remove(),w.off().remove(),r.remove(),q.off().find("*").off().remove(),q.remove(),wa.removeData("sceditor").removeData("sceditorbbcode").show(),H&&wa.attr("required","required"))},ua.createDropDown=function(a,d,e,f){var g,h="sceditor-"+d,i=y&&y.is("."+h);ua.closeDropDown(!0),i||(f!==!1&&b(e).find(":not(input,textarea)").filter(function(){return 1===this.nodeType}).attr("unselectable","on"),g={top:a.offset().top,left:a.offset().left,marginTop:a.outerHeight()},b.extend(g,c.dropDownCss),y=b('<div class="sceditor-dropdown '+h+'" />').css(g).append(e).appendTo(b("body")).on("click focusin",function(a){a.stopPropagation()}),setTimeout(function(){y&&y.find("input,textarea").first().focus()}))},ea=function(a){3!==a.which&&y&&(ta(),ua.closeDropDown())},Y=function(a){var b,d,e,f=u[0],g=v[0],h=0,i=k.createElement("div"),j=g.createDocumentFragment(),l=!!a&&a.clipboardData;if(c.disablePasting)return!1;if(c.enablePasteFiltering){if(B.saveRange(),k.body.appendChild(i),l&&l.getData&&((b=l.getData("text/html"))||(b=l.getData("text/plain"))))return i.innerHTML=b,Z(f,i),!1;for(e=u.scrollTop()||v.scrollTop();f.firstChild;)j.appendChild(f.firstChild);return d=function(a,b){if(a.childNodes.length>0||h>25){for(;a.firstChild;)b.appendChild(a.firstChild);for(;j.firstChild;)a.appendChild(j.firstChild);u.scrollTop(e),v.scrollTop(e),b.childNodes.length>0?Z(a,b):B.restoreRange()}else h++,setTimeout(function(){d(a,b)},20)},d(f,i),ua.focus(),!0}},Z=function(a,c){f.fixNesting(c);var d=c.innerHTML;C.hasHandler("toSource")&&(d=C.callOnlyFirst("toSource",d,b(c))),c.parentNode.removeChild(c),C.hasHandler("toWysiwyg")&&(d=C.callOnlyFirst("toWysiwyg",d,!0)),B.restoreRange(),ua.wysiwygEditorInsertHtml(d,null,!0)},ua.closeDropDown=function(a){y&&(y.off().remove(),y=null),a===!0&&ua.focus()},X=function(){return t.contentDocument?t.contentDocument:t.contentWindow&&t.contentWindow.document?t.contentWindow.document:t.document},ua.wysiwygEditorInsertHtml=function(a,c,d){var e,g,h,i=s.height();ua.focus(),(d||!b(E).is("code")&&0===b(E).parents("code").length)&&(B.insertHTML(a,c),B.saveRange(),L(u[0]),e=u.find("#sceditor-end-marker").show(),g=u.scrollTop()||v.scrollTop(),h=f.getOffset(e[0]).top+1.5*e.outerHeight(!0)-i,e.hide(),(h>g||h+i<g)&&(u.scrollTop(h),v.scrollTop(h)),qa(!1),B.restoreRange(),ja())},ua.wysiwygEditorInsertText=function(a,b){ua.wysiwygEditorInsertHtml(g.entities(a),g.entities(b))},ua.insertText=function(a,b){return ua.inSourceMode()?ua.sourceEditorInsertText(a,b):ua.wysiwygEditorInsertText(a,b),ua},ua.sourceEditorInsertText=function(a,b){var c,d,e,f=x.selectionStart,g=x.selectionEnd;d=x.scrollTop,x.focus(),"undefined"!=typeof f?(e=x.value,b&&(a+=e.substring(f,g)+b),x.value=e.substring(0,f)+a+e.substring(g,e.length),x.selectionStart=f+a.length-(b?b.length:0),x.selectionEnd=x.selectionStart):(c=k.selection.createRange(),b&&(a+=c.text+b),c.text=a,b&&c.moveEnd("character",0-b.length),c.moveStart("character",c.End-c.Start),c.select()),x.scrollTop=d,x.focus(),qa()},ua.getRangeHelper=function(){return B},ua.sourceEditorCaret=function(a){var b,c={};return x.focus(),"undefined"!=typeof x.selectionStart?a?(x.selectionStart=a.start,x.selectionEnd=a.end):(c.start=x.selectionStart,c.end=x.selectionEnd):(b=k.selection.createRange(),a?(b.moveEnd("character",a.end),b.moveStart("character",a.start),b.select()):(c.start=b.Start,c.end=b.End)),a?this:c},ua.val=function(a,b){return"string"!=typeof a?ua.inSourceMode()?ua.getSourceEditorValue(!1):ua.getWysiwygEditorValue(b):(ua.inSourceMode()?ua.setSourceEditorValue(a):(b!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a)),ua.setWysiwygEditorValue(a)),ua)},ua.insert=function(a,c,d,e,f){if(ua.inSourceMode())return ua.sourceEditorInsertText(a,c),ua;if(c){var g=B.selectedHtml(),h=b("<div>").appendTo(b("body")).hide().html(g);d!==!1&&C.hasHandler("toSource")&&(g=C.callOnlyFirst("toSource",g,h)),h.remove(),a+=g+c}return d!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a,!0)),d!==!1&&f===!0&&(a=a.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),ua.wysiwygEditorInsertHtml(a),ua},ua.getWysiwygEditorValue=function(a){var c,d=b("<div>").appendTo(document.body).append(b(u[0].childNodes).clone());return f.fixNesting(d[0]),c=d.html(),a!==!1&&C.hasHandler("toSource")&&(c=C.callOnlyFirst("toSource",c,d)),d.remove(),c},ua.getBody=function(){return u},ua.getContentAreaContainer=function(){return s},ua.getSourceEditorValue=function(a){var b=w.val();return a!==!1&&C.hasHandler("toWysiwyg")&&(b=C.callOnlyFirst("toWysiwyg",b)),b},ua.setWysiwygEditorValue=function(a){a||(a="<p>"+(n?"":"<br />")+"</p>"),u[0].innerHTML=a,L(u[0]),ja(),qa()},ua.setSourceEditorValue=function(a){w.val(a),qa()},ua.updateOriginal=function(){wa.val(ua.val())},L=function(a){if(c.emoticonsEnabled&&!b(a).parents("code").length){var d=a.ownerDocument,e="\\s| | | | | ",h=[],j=[],k=b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden);b.each(k,function(a){c.emoticonsCompat&&(j[a]=new RegExp("(>|^|"+e+")"+g.regex(a)+"($|<|"+e+")")),h.push(a)});var l=function(a){for(a=a.firstChild;a;){var e,g,m,n,o,p,q,r=a.parentNode,s=a.nodeValue;if(3!==a.nodeType)b(a).is("code")||l(a);else if(s)for(o=h.length;o--;)g=h[o],q=c.emoticonsCompat?s.search(j[g]):s.indexOf(g),q>-1&&(p=a.nextSibling,m=k[g],e=s.substr(q).split(g),s=s.substr(0,q)+e.shift(),a.nodeValue=s,n=f.parseHTML(i("emoticon",{key:g,url:m.url||m,tooltip:m.tooltip||g}),d),r.insertBefore(n[0],p),r.insertBefore(d.createTextNode(e.join(g)),p));a=a.nextSibling}};l(a),c.emoticonsCompat&&(Ba=u.find("img[data-sceditor-emoticon]"))}},ua.inSourceMode=function(){return q.hasClass("sourceMode")},ua.sourceMode=function(a){var b=ua.inSourceMode();return"boolean"!=typeof a?b:((b&&!a||!b&&a)&&ua.toggleSourceMode(),ua)},ua.toggleSourceMode=function(){var a=ua.inSourceMode();!h.isWysiwygSupported&&a||(a||(B.saveRange(),B.clear()),ua.blur(),a?ua.setWysiwygEditorValue(ua.getSourceEditorValue()):ua.setSourceEditorValue(ua.getWysiwygEditorValue()),z=null,w.toggle(),s.toggle(),q.toggleClass("wysiwygMode",a).toggleClass("sourceMode",!a),ga(),ha())},ia=function(){return x.focus(),"undefined"!=typeof x.selectionStart?x.value.substring(x.selectionStart,x.selectionEnd):k.selection.createRange().text},M=function(a,c){ua.inSourceMode()?c.txtExec&&(b.isArray(c.txtExec)?ua.sourceEditorInsertText.apply(ua,c.txtExec):c.txtExec.call(ua,a,ia())):c.exec&&(b.isFunction(c.exec)?c.exec.call(ua,a):ua.execCommand(c.exec,c.hasOwnProperty("execParam")?c.execParam:null))},N=function(){n&&(z=B.selectedRange())},ua.execCommand=function(a,c){var d=!1,e=ua.commands[a],f=b(B.parentNode());if(ua.focus(),!f.is("code")&&0===f.parents("code").length){try{d=v[0].execCommand(a,!1,c)}catch(a){}!d&&e&&e.errorMessage&&alert(ua._(e.errorMessage)),ha()}},ka=function(){function a(){B&&!B.compare(F)&&(F=B.cloneSelected(),q.trigger(b.Event("selectionchanged"))),G=!1}G||(G=!0,n?a():setTimeout(a,100))},la=function(){var a,c=B.parentNode();D!==c&&(a=D,D=c,E=B.getFirstBlockParent(c),q.trigger(b.Event("nodechanged",{oldNode:a,newNode:D})))},ua.currentNode=function(){return D},ua.currentBlockNode=function(){return E},ha=function(a){var b,c,d="active",e=v[0],f=ua.sourceMode();if(ua.readOnly())return void r.find(d).removeClass(d);f||(c=a?a.newNode:B.parentNode(),b=B.getFirstBlockParent(c));for(var g=0;g<za.length;g++){var h=0,i=Ca[za[g].name],j=za[g].state,k=f&&!i.data("sceditor-txtmode")||!f&&!i.data("sceditor-wysiwygmode");if("string"==typeof j){if(!f)try{h=e.queryCommandEnabled(j)?0:-1,h>-1&&(h=e.queryCommandState(j)?1:0)}catch(a){}}else k||(h=j.call(ua,c,b));i.toggleClass("disabled",k||h<0).toggleClass(d,h>0)}},aa=function(a){var c,d,e,g,h="code,blockquote,pre",i="li,ul,ol";if(!a.originalEvent.defaultPrevented)return ua.closeDropDown(),c=b(E).closest(h+","+i).first(),13===a.which&&c.length&&!c.is(i)?(z=null,d=v[0].createElement("br"),B.insertNode(d),o||(e=d.parentNode,g=e.lastChild,g&&3===g.nodeType&&""===g.nodeValue&&(e.removeChild(g),g=e.lastChild),!f.isInline(e,!0)&&g===d&&f.isInline(d.previousSibling)&&B.insertHTML("<br>")),!1):void 0},ja=function(){var a,c,d,e=u[0];f.rTraverse(e,function(g){if(a=g.nodeName.toLowerCase(),b.inArray(a,ya)>-1&&(c=!0),3===g.nodeType&&!/^\s*$/.test(g.nodeValue)||"br"===a||o&&!g.firstChild&&!f.isInline(g,!1))return c&&(d=v[0].createElement("p"),d.className="sceditor-nlf",d.innerHTML=o?"":"<br />",e.appendChild(d)),!1})},ba=function(){ua.val(wa.val())},ca=function(){ua.closeDropDown(),z=null},fa=function(){var a=c.height,b=c.width;ua.maximize()?ua.dimensions("100%","100%",!1):(a&&a.toString().indexOf("%")>-1||b&&b.toString().indexOf("%")>-1)&&ua.dimensions(b,a)},ua._=function(){var a,b=arguments;return A&&A[b[0]]&&(b[0]=A[b[0]]),b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},da=function(a){C.call(a.type+"Event",a,ua);var c=a.target===x?"scesrc":"scewys",d=b.Event(a);d.type=c+a.type,q.trigger(d,ua)},ua.bind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.on("scewys"+a[f],c),e||q.on("scesrc"+a[f],c),"valuechanged"===a[f]&&(qa.hasHandler=!0));return ua},ua.unbind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.off("scewys"+a[f],c),e||q.off("scesrc"+a[f],c));return ua},ua.blur=function(a,c,d){return b.isFunction(a)?ua.bind("blur",a,c,d):ua.sourceMode()?w.blur():u.blur(),ua},ua.focus=function(a,c,d){if(b.isFunction(a))ua.bind("focus",a,c,d);else if(ua.inSourceMode())x.focus();else{var e,f=B.selectedRange();F||B.hasSelection()||ma(),!o&&f&&1===f.endOffset&&f.collapsed&&(e=f.endContainer,e&&1===e.childNodes.length&&b(e.firstChild).is("br")&&(f.setStartBefore(e.firstChild),f.collapse(!0),B.selectRange(f))),t.contentWindow.focus(),u[0].focus(),z&&(B.selectRange(z),z=null)}return ha(),ua},ua.keyDown=function(a,b,c){return ua.bind("keydown",a,b,c)},ua.keyPress=function(a,b,c){return ua.bind("keypress",a,b,c)},ua.keyUp=function(a,b,c){return ua.bind("keyup",a,b,c)},ua.nodeChanged=function(a){return ua.bind("nodechanged",a,!1,!0)},ua.selectionChanged=function(a){return ua.bind("selectionchanged",a,!1,!0)},ua.valueChanged=function(a,b,c){return ua.bind("valuechanged",a,b,c)},na=function(a){var d,e=0,f=ua.emoticonsCache,g=String.fromCharCode(a.which);if(!b(E).is("code")&&!b(E).parents("code").length)return f||(f=[],b.each(b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden),function(a,b){f[e++]=[a,i("emoticon",{key:a,url:b.url||b,tooltip:b.tooltip||a})]}),f.sort(function(a,b){return a[0].length-b[0].length}),ua.emoticonsCache=f,ua.longestEmoticonCode=f[f.length-1][0].length),d=B.replaceKeyword(ua.emoticonsCache,!0,!0,ua.longestEmoticonCode,c.emoticonsCompat,g),d&&c.emoticonsCompat?(Ba=u.find("img[data-sceditor-emoticon]"),/^\s$/.test(g)):!d},oa=function(){if(Ba.length){var a,c,d,e,f,g,h=ua.currentBlockNode(),i=!1,j=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/;Ba=b.map(Ba,function(k){return k&&k.parentNode?b.contains(h,k)?(a=k.previousSibling,c=k.nextSibling,f=a.nodeValue,null===f&&(f=a.innerText||""),a&&j.test(a.nodeValue.slice(-1))||c&&j.test((c.nodeValue||"")[0])?(d=k.parentNode,e=B.cloneSelected(),g=e.startContainer,f+=b(k).data("sceditor-emoticon"),g===c?i=f.length+e.startOffset:g===h&&h.childNodes[e.startOffset]===c?i=f.length:g===a&&(i=e.startOffset),c&&3===c.nodeType||(c=d.insertBefore(d.ownerDocument.createTextNode(""),c)),c.insertData(0,f),d.removeChild(a),d.removeChild(k),i!==!1&&(e.setStart(c,i),e.collapse(!0),B.selectRange(e)),null):k):k:null})}},ua.emoticons=function(a){return a||a===!1?(c.emoticonsEnabled=a,a?(u.keypress(na),ua.sourceMode()||(B.saveRange(),L(u[0]),Ba=u.find("img[data-sceditor-emoticon]"),qa(!1),B.restoreRange())):(u.find("img[data-sceditor-emoticon]").replaceWith(function(){return b(this).data("sceditor-emoticon")}),Ba=[],u.off("keypress",na),qa()),ua):c.emoticonsEnabled},ua.css=function(a){return I||(I=b('<style id="#inline" />',v[0]).appendTo(v.find("head"))[0]),"string"!=typeof a?I.styleSheet?I.styleSheet.cssText:I.innerHTML:(I.styleSheet?I.styleSheet.cssText=a:I.innerHTML=a,ua)},$=function(a){var b=[],c={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},d={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},e={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},f=a.which,g=d[f]||String.fromCharCode(f).toLowerCase();if((a.ctrlKey||a.metaKey)&&b.push("ctrl"),a.altKey&&b.push("alt"),a.shiftKey&&(b.push("shift"),e[f]?g=e[f]:c[g]&&(g=c[g])),g&&(f<16||f>18)&&b.push(g),b=b.join("+"),Aa[b])return Aa[b].call(ua)},ua.addShortcut=function(a,b){return a=a.toLowerCase(),"string"==typeof b?Aa[a]=function(){return M(Ca[b],ua.commands[b]),!1}:Aa[a]=b,ua},ua.removeShortcut=function(a){return delete Aa[a.toLowerCase()],ua},_=function(a){var d,e,f,g,h;if(!c.disableBlockRemove&&8===a.which&&(g=B.selectedRange())&&(j.getSelection?(d=g.startContainer,e=g.startOffset):(d=g.parentElement(),f=v[0].selection.createRange(),f.moveToElementText(d),f.setEndPoint("EndToStart",g),e=f.text.length),0===e&&(h=pa()))){for(;d!==h;){for(;d.previousSibling;)if(d=d.previousSibling,3!==d.nodeType||d.nodeValue)return;if(!(d=d.parentNode))return}if(h&&!b(h).is("body"))return ua.clearBlockFormatting(h),!1}},pa=function(){for(var a=E;!f.hasStyling(a)||f.isInline(a,!0);)if(!(a=a.parentNode)||b(a).is("body"))return;return a},ua.clearBlockFormatting=function(a){return a=a||pa(),!a||b(a).is("body")?ua:(B.saveRange(),a.className="",z=null,b(a).attr("style",""),b(a).is("p,div,td")||f.convertElement(a,"p"),B.restoreRange(),ua)},qa=function(a){if(C&&(C.hasHandler("valuechangedEvent")||qa.hasHandler)){var c,d=ua.sourceMode(),e=!d&&B.hasSelection();a=a!==!1&&!v[0].getElementById("sceditor-start-marker"),sa.timer&&(clearTimeout(sa.timer),sa.timer=!1),e&&a&&B.saveRange(),c=d?w.val():u.html(),c!==qa.lastHtmlValue&&(qa.lastHtmlValue=c,q.trigger(b.Event("valuechanged",{rawValue:d?ua.val():c}))),e&&a&&B.removeMarkers()}},ra=function(){sa.timer&&qa()},sa=function(a){var b=a.which,c=sa.lastChar,d=13===c||32===c,e=8===c||46===c;sa.lastChar=b,13===b||32===b?d?sa.triggerNextChar=!0:qa():8===b||46===b?e?sa.triggerNextChar=!0:qa():sa.triggerNextChar&&(qa(),sa.triggerNextChar=!1),sa.timer&&clearTimeout(sa.timer),sa.timer=setTimeout(function(){qa()},1500)},ta=function(){J||ua.updateOriginal(),J=!1},K()};return p.locale={},p.command={get:function(a){return p.commands[a]||null},set:function(a,c){return!(!a||!c)&&(c=b.extend(p.commands[a]||{},c),c.remove=function(){p.command.remove(a)},p.commands[a]=c,this)},remove:function(a){return p.commands[a]&&delete p.commands[a],this}},p}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={},b=function(b){var c=this,d=[],e=function(a){return"signal"+a.charAt(0).toUpperCase()+a.slice(1)},f=function(a,c){a=[].slice.call(a);var f,g,h=e(a.shift());for(f=0;f<d.length;f++)if(h in d[f]&&(g=d[f][h].apply(b,a),c))return g};c.call=function(){f(arguments,!1)},c.callOnlyFirst=function(){return f(arguments,!0)},c.hasHandler=function(a){var b=d.length;for(a=e(a);b--;)if(a in d[b])return!0;return!1},c.exists=function(b){return b in a&&(b=a[b],"function"==typeof b&&"object"==typeof b.prototype)},c.isRegistered=function(b){if(c.exists(b))for(var e=d.length;e--;)if(d[e]instanceof a[b])return!0;return!1},c.register=function(e){return!(!c.exists(e)||c.isRegistered(e)||(e=new a[e],d.push(e),"init"in e&&e.init.call(b),0))},c.deregister=function(e){var f,g=d.length,h=!1;if(!c.isRegistered(e))return h;for(;g--;)d[g]instanceof a[e]&&(f=d.splice(g,1)[0],h=!0,"destroy"in f&&f.destroy.call(b));return h},c.destroy=function(){for(var a=d.length;a--;)"destroy"in d[a]&&d[a].destroy.call(b);d=[],b=null}};return b.plugins=a,b}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(5),e=c(7),f=c(6),g=f.ie,h=g&&g<11,i=function(a){return b("<p>",a.ownerDocument).append(a).html()},j=function(a,b,c){var d,e,f,g,h,i="",j=a.startContainer,k=a.startOffset;for(j&&3!==j.nodeType&&(j=j.childNodes[k],k=0),f=g=k;c>i.length&&j&&3===j.nodeType;)d=j.nodeValue,e=c-i.length,h&&(g=d.length,f=0),h=j,b?(f=Math.max(g-e,0),k=f,i=d.substr(f,g-f)+i,j=h.previousSibling):(g=Math.min(e,d.length),k=f+g,i+=d.substr(f,g),j=h.nextSibling);return{node:h||j,offset:k,text:i}},k=function(a,c){var f,k,l,m=c||a.contentDocument||a.document,n=a,o=!!a.getSelection,p="sceditor-start-marker",q="sceditor-end-marker",r="character",s=this;s.insertHTML=function(a,b){var c,d,e=s.selectedRange();if(!e)return!1;if(o){for(b&&(a+=s.selectedHtml()+b),d=m.createElement("p"),c=m.createDocumentFragment(),d.innerHTML=a;d.firstChild;)c.appendChild(d.firstChild);s.insertNode(c)}else e.pasteHTML(l(a,b,!0)),s.restoreRange()},l=function(a,c,e){var h,i,j=m.createElement("div"),k=b(j);if("string"==typeof a?(c&&(a+=s.selectedHtml()+c),k.html(a)):(k.append(a),c&&k.append(s.selectedRange().extractContents()).append(c)),h=j.lastChild){for(;!d.isInline(h.lastChild,!0);)h=h.lastChild;return d.canHaveChildren(h)&&(i=b(h),h.lastChild||i.append("")),g&&g<9&&b(h).is("img")&&k.append(""),s.removeMarkers(),(i||k).append(f(p)).append(f(q)),e?k.html():b(m.createDocumentFragment()).append(k.contents())[0]}},s.insertNode=function(a,b){if(o){var c=l(a,b),e=s.selectedRange(),f=e.commonAncestorContainer;if(!c)return!1;e.deleteContents(),f&&3!==f.nodeType&&!d.canHaveChildren(f)?f.parentNode.insertBefore(c,f):e.insertNode(c),s.restoreRange()}else s.insertHTML(i(a),b?i(b):null)},s.cloneSelected=function(){var a=s.selectedRange();if(a)return o?a.cloneRange():a.duplicate()},s.selectedRange=function(){var a,b,c=o?n.getSelection():m.selection;if(c){if(c.getRangeAt&&c.rangeCount<=0){for(b=m.body;b.firstChild;)b=b.firstChild;a=m.createRange(),a.setStartBefore(b),c.addRange(a)}return o&&c.rangeCount>0&&(a=c.getRangeAt(0)),o||"Control"===c.type||(a=c.createRange()),k(a)?a:null}},k=function(a){var b;return a&&!o&&(b=a.parentElement()),!b||b.ownerDocument===m},s.hasSelection=function(){var a=o?n.getSelection():m.selection;return o||!a?a&&a.rangeCount>0:"None"!==a.type&&k(a.createRange())},s.selectedHtml=function(){var a,b=s.selectedRange();if(b){if(o)return a=m.createElement("p"),a.appendChild(b.cloneContents()),a.innerHTML;if(""!==b.text&&b.htmlText)return b.htmlText}return""},s.parentNode=function(){var a=s.selectedRange();if(a)return a.parentElement?a.parentElement():a.commonAncestorContainer},s.getFirstBlockParent=function(a){var b=function(a){return d.isInline(a,!0)?(a=a?a.parentNode:null,a?b(a):a):a};return b(a||s.parentNode())},s.insertNodeAt=function(a,b){var c=s.selectedRange(),d=s.cloneSelected();return!!d&&(d.collapse(a),o?d.insertNode(b):d.pasteHTML(i(b)),void s.selectRange(c))},f=function(a){s.removeMarker(a);var b=m.createElement("span");return b.id=a,b.style.lineHeight="0",b.style.display="none",b.className="sceditor-selection sceditor-ignore",b.innerHTML=" ",b},s.insertMarkers=function(){s.insertNodeAt(!0,f(p)),s.insertNodeAt(!1,f(q))},s.getMarker=function(a){return m.getElementById(a)},s.removeMarker=function(a){var b=s.getMarker(a);b&&b.parentNode.removeChild(b)},s.removeMarkers=function(){s.removeMarker(p),s.removeMarker(q)},s.saveRange=function(){s.insertMarkers()},s.selectRange=function(a){if(o){var c,e=n.getSelection(),f=a.endContainer;if(!h&&a.collapsed&&f&&!d.isInline(f,!0)){for(c=f.lastChild;c&&b(c).is(".sceditor-ignore");)c=c.previousSibling;if(b(c).is("br")){var g=m.createRange();g.setEndAfter(c),g.collapse(!1),s.compare(a,g)&&(a.setStartBefore(c),a.collapse(!0))}}e&&(s.clear(),e.addRange(a))}else a.select()},s.restoreRange=function(){var a,c,e,f=s.selectedRange(),g=s.getMarker(p),h=s.getMarker(q);return!!(g&&h&&f)&&(c=g.nextSibling===h,o?(f=m.createRange(),f.setStartBefore(g),f.setEndAfter(h)):(f=m.body.createTextRange(),a=m.body.createTextRange(),e=g.previousSibling,g.nextSibling!==h||e&&d.isInline(e,!0)&&!b(e).is("br")||b(g).before(""),a.moveToElementText(g),f.setEndPoint("StartToStart",a),f.moveStart(r,0),a.moveToElementText(h),f.setEndPoint("EndToStart",a),f.moveEnd(r,0)),c&&f.collapse(!0),s.selectRange(f),void s.removeMarkers())},s.selectOuterText=function(a,b){var c,d,e=s.cloneSelected();return!!e&&(e.collapse(!1),o?(c=j(e,!0,a),d=j(e,!1,b),e.setStart(c.node,c.offset),e.setEnd(d.node,d.offset)):(e.moveStart(r,0-a),e.moveEnd(r,b)),void s.selectRange(e))},s.getOuterText=function(a,b){var c=s.cloneSelected();return c?(c.collapse(!a),o?j(c,a,b).text:(a?c.moveStart(r,0-b):c.moveEnd(r,b),c.text)):""},s.replaceKeyword=function(a,b,c,d,f,g){c||a.sort(function(a,b){return a[0].length-b[0].length});var h,i,j,k,l,m,n,p="[\\s ]",q=a.length,r=f?1:0,t=d||a[q-1][0].length;if(f){if(!o)return!1;t++}for(g=g||"",h=s.getOuterText(!0,t),k=h.length,h+=g,b&&(h+=s.getOuterText(!1,t));q--;)if(m=a[q][0],n=m.length,j=Math.max(0,k-n-r),i=f?h.substr(j).search(new RegExp("(?:"+p+")"+e.regex(m)+"(?="+p+")")):h.indexOf(m,j),i>-1&&(f&&(i+=j+1),i<=k&&i+n+r>=k))return l=k-i,s.selectOuterText(l,n-l-(/^\S/.test(g)?1:0)),s.insertHTML(a[q][1]),!0;return!1},s.compare=function(a,b){var c=o?Range.END_TO_END:"EndToEnd",d=o?Range.START_TO_START:"StartToStart",e=o?"compareBoundaryPoints":"compareEndPoints";return b||(b=s.selectedRange()),a&&b?k(a)&&k(b)&&0===a[e](c,b)&&0===a[e](d,b):!a&&!b},s.clear=function(){var a=o?n.getSelection():m.selection;a&&(a.removeAllRanges?a.removeAllRanges():a.empty&&a.empty())}};return k}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6),e={},f={traverse:function(a,b,c,d,e){if(a)for(a=e?a.lastChild:a.firstChild;a;){var g=e?a.previousSibling:a.nextSibling;if(!c&&b(a)===!1||!d&&f.traverse(a,b,c,d,e)===!1||c&&b(a)===!1)return!1;a=g}},rTraverse:function(a,b,c,d){this.traverse(a,b,c,d,!0)},parseHTML:function(a,c){var d=[],e=(c||document).createElement("div");return e.innerHTML=a,b.merge(d,e.childNodes),d},hasStyling:function(a){var c=b(a);return a&&(!c.is("p,div")||a.className||c.attr("style")||!b.isEmptyObject(c.data()))},convertElement:function(a,b){for(var c,e,g=a.attributes,h=g.length,i=a.ownerDocument.createElement(b);h--;)if(e=g[h],!d.ie||e.specified)if(d.ie<8&&/style/i.test(e.name))f.copyCSS(a,i);else try{ | ||
i.setAttribute(e.name,e.value)}catch(a){}for(;c=a.firstChild;)i.appendChild(c);return a.parentNode.replaceChild(i,a),i},blockLevelList:"|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|",canHaveChildren:function(a){return!!/11?|9/.test(a.nodeType)&&"|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr|isindex|link|meta|param|command|embed|keygen|source|track|object|".indexOf("|"+a.nodeName.toLowerCase()+"|")<0},isInline:function(a,b){var c,d=(a||{}).nodeType||3;return 1!==d?3===d:(c=a.tagName.toLowerCase(),"code"===c?!b:f.blockLevelList.indexOf("|"+c+"|")<0)},copyCSS:function(a,b){b.style.cssText=a.style.cssText+b.style.cssText},fixNesting:function(a){var b=function(a){for(;f.isInline(a.parentNode,!0);)a=a.parentNode;return a};f.traverse(a,function(a){if(1===a.nodeType&&!f.isInline(a,!0)&&f.isInline(a.parentNode,!0)){var c=b(a),d=c.parentNode,e=f.extractContents(c,a),g=a;f.copyCSS(c,g),d.insertBefore(e,c),d.insertBefore(g,c)}})},findCommonAncestor:function(a,c){return b(a).parents().has(b(c)).first()},getSibling:function(a,b){return a?(b?a.previousSibling:a.nextSibling)||f.getSibling(a.parentNode,b):null},removeWhiteSpace:function(a,c){for(var d,e,g,h,i,j,k,l,m=f.getSibling,n=f.isInline,o=a.firstChild;o;){if(k=o.nextSibling,d=o.nodeValue,e=o.nodeType,1===e&&o.firstChild&&(j=b(o).css("whiteSpace"),/pre(\-wrap)?$/i.test(j)||f.removeWhiteSpace(o,/line$/i.test(j))),3===e&&d){for(g=m(o),h=m(o,!0),l=!1;b(h).hasClass("sceditor-ignore");)h=m(h,!0);if(n(o)&&h){for(i=h;i.lastChild;)i=i.lastChild;l=3===i.nodeType?/[\t\n\r ]$/.test(i.nodeValue):!n(i)}d=d.replace(/\u200B/g,""),h&&n(h)&&!l||(d=d.replace(c?/^[\t ]+/:/^[\t\n\r ]+/,"")),g&&n(g)||(d=d.replace(c?/[\t ]+$/:/[\t\n\r ]+$/,"")),d.length?o.nodeValue=d.replace(c?/[\t ]+/g:/[\t\n\r ]+/g," "):a.removeChild(o)}o=k}},extractContents:function(a,c){var d,e=f.findCommonAncestor(a,c).get(0),g=!1,h=!1;return(d=function(e){var i,j=a.ownerDocument.createDocumentFragment();return f.traverse(e,function(e){return h||e===c?(h=!0,!1):(e===a&&(g=!0),void(b.contains(e,a)||g&&b.contains(e,c)?(i=e.cloneNode(!1),i.appendChild(d(e)),j.appendChild(i)):g&&!b.contains(j,e)&&j.appendChild(e)))},!1),j})(e)},getOffset:function(a){for(var b=0,c=0;a;)b+=a.offsetLeft,c+=a.offsetTop,a=a.offsetParent;return{left:b,top:c}},getStyle:function(a,c){var d,f,g,h=a.style;if(!h)return"";if(e[c]||(e[c]=b.camelCase(c)),c=e[c],g=h[c],"textAlign"===c){if(d=b(a),f=h.direction,g=g||d.css(c),d.parent().css(c)===g||"block"!==d.css("display")||d.is("hr")||d.is("th"))return"";if(/right/i.test(g)&&"rtl"===f||/left/i.test(g)&&"ltr"===f)return""}return g},hasStyle:function(a,c,d){var e=f.getStyle(a,c);return!!e&&(!d||e===d||b.isArray(d)&&b.inArray(e,d)>-1)}};return f}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var d=c(1),e=navigator.userAgent;b.ie=function(){var a,b=3,c=document,d=c.createElement("div"),e=d.getElementsByTagName("i");do d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->";while(e[0]);return c.documentMode&&c.all&&window.atob&&(b=10),4===b&&c.documentMode&&(b=11),b>4?b:a}(),b.ios=/iPhone|iPod|iPad| wosbrowser\//i.test(e),b.isWysiwygSupported=function(){var a,c,f,g=d('<p contenteditable="true">')[0].contentEditable;return g!==f&&"inherit"!==g&&(c=/Opera Mobi|Opera Mini/i.test(e),/Android/i.test(e)&&(c=!0,/Safari/.test(e)&&(a=/Safari\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534)),/ Silk\//i.test(e)&&(a=/AppleWebKit\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534),b.ios&&(c=/OS [0-4](_\d)+ like Mac/i.test(e)),/Firefox/i.test(e)&&(c=!1),/OneBrowser/i.test(e)&&(c=!1),"UCWEB"===navigator.vendor&&(c=!1),!c)}()}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var c=/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;b.regex=function(a){return a.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},b.entities=function(a,b){if(!a)return a;var c={"&":"&","<":"<",">":">"," ":" ","\r\n":"\n","\r":"\n","\n":"<br />"};return b!==!1&&(c['"']=""",c["'"]="'",c["`"]="`"),a=a.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(a){return c[a]||a})},b.uriScheme=function(a){var b,d=/^[^\/]*:/i,e=window.location;return a&&d.test(a)&&!c.test(a)?(b=e.pathname.split("/"),b.pop(),e.protocol+"//"+e.host+b.join("/")+"/"+a):a}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={html:'<!DOCTYPE html><html{attrs}><head><style>.ie * {min-height: auto !important} .ie table td {height:15px} @supports (-ms-ime-align:auto) { * { min-height: auto !important; } }</style><meta http-equiv="Content-Type" content="text/html;charset={charset}" /><link rel="stylesheet" type="text/css" href="{style}" /></head><body contenteditable="true" {spellcheck}><p></p></body></html>',toolbarButton:'<a class="sceditor-button sceditor-button-{name}" data-sceditor-command="{name}" unselectable="on"><div unselectable="on">{dispName}</div></a>',emoticon:'<img src="{url}" data-sceditor-emoticon="{key}" alt="{key}" title="{tooltip}" />',fontOpt:'<a class="sceditor-font-option" href="#" data-font="{font}"><font face="{font}">{font}</font></a>',sizeOpt:'<a class="sceditor-fontsize-option" data-size="{size}" href="#"><font size="{size}">{size}</font></a>',pastetext:'<div><label for="txt">{label}</label> <textarea cols="20" rows="7" id="txt"></textarea></div><div><input type="button" class="button" value="{insert}" /></div>',table:'<div><label for="rows">{rows}</label><input type="text" id="rows" value="2" /></div><div><label for="cols">{cols}</label><input type="text" id="cols" value="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',image:'<div><label for="link">{url}</label> <input type="text" id="image" placeholder="http://" /></div><div><label for="width">{width}</label> <input type="text" id="width" size="2" /></div><div><label for="height">{height}</label> <input type="text" id="height" size="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',email:'<div><label for="email">{label}</label> <input type="text" id="email" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{insert}" /></div>',link:'<div><label for="link">{url}</label> <input type="text" id="link" placeholder="http://" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{ins}" /></div>',youtubeMenu:'<div><label for="link">{label}</label> <input type="text" id="link" placeholder="https://" /></div><div><input type="button" class="button" value="{insert}" /></div>',youtube:'<iframe width="560" height="315" src="https://www.youtube.com/embed/{id}?wmode=opaque" data-youtube-id="{id}" frameborder="0" allowfullscreen></iframe>'};return function(b,c,d){var e=a[b];return $.each(c,function(a,b){e=e.replace(new RegExp("\\{"+a+"\\}","g"),b)}),d&&(e=$(e)),e}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6).ie,e=c(8),f=d&&d<11,g={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(a,c,d){for(var f=0,g=a.opts.fonts.split(","),h=b("<div />"),i=function(){return d(b(this).data("font")),a.closeDropDown(!0),!1};f<g.length;f++)h.append(e("fontOpt",{font:g[f]},!0).click(i));a.createDropDown(c,"font-picker",h)},exec:function(a){var b=this;g.font._dropDown(b,a,function(a){b.execCommand("fontname",a)})},tooltip:"Font Name"},size:{_dropDown:function(a,c,d){for(var f=b("<div />"),g=function(c){d(b(this).data("size")),a.closeDropDown(!0),c.preventDefault()},h=1;h<=7;h++)f.append(e("sizeOpt",{size:h},!0).click(g));a.createDropDown(c,"fontsize-picker",f)},exec:function(a){var b=this;g.size._dropDown(b,a,function(a){b.execCommand("fontsize",a)})},tooltip:"Font Size"},color:{_dropDown:function(a,c,d){var e,f,h,i,j={r:255,g:255,b:255},k=b("<div />"),l=a.opts.colors?a.opts.colors.split("|"):new Array(21),m=[],n=g.color;if(!n._htmlCache){for(e=0;e<l.length;++e){for(i=l[e]?l[e].split(","):new Array(21),m.push('<div class="sceditor-color-column">'),f=0;f<i.length;++f)h=i[f]||"#"+j.r.toString(16)+j.g.toString(16)+j.b.toString(16),m.push('<a href="#" class="sceditor-color-option" style="background-color: '+h+'" data-color="'+h+'"></a>'),f%5===0?(j.g-=51,j.b=255):j.b-=51;m.push("</div>"),e%5===0?(j.r-=51,j.g=255,j.b=255):(j.g=255,j.b=255)}n._htmlCache=m.join("")}k.append(n._htmlCache).find("a").click(function(c){d(b(this).attr("data-color")),a.closeDropDown(!0),c.preventDefault()}),a.createDropDown(c,"color-picker",k)},exec:function(a){var b=this;g.color._dropDown(b,a,function(a){b.execCommand("forecolor",a)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(a){var b,c,d=this;c=e("pastetext",{label:d._("Paste your text inside the following box:"),insert:d._("Insert")},!0),c.find(".button").click(function(a){b=c.find("#txt").val(),b&&d.wysiwygEditorInsertText(b),d.closeDropDown(!0),a.preventDefault()}),d.createDropDown(a,"pastetext",c)},tooltip:"Paste Text"},bulletlist:{exec:"insertunorderedlist",tooltip:"Bullet list"},orderedlist:{exec:"insertorderedlist",tooltip:"Numbered list"},indent:{state:function(a,c){var d,e,f,g=b(c),h=g.parents("ul,ol,menu"),i=h.first();if(h.length>1||i.children().length>1)return 0;if(g.is("ul,ol,menu")){if(d=this.getRangeHelper().selectedRange(),!(window.Range&&d instanceof Range))return g.is("li,ul,ol,menu")?0:-1;if(e=d.startContainer.parentNode,f=d.endContainer.parentNode,e!==e.parentNode.firstElementChild||b(f).is("li")&&f!==f.parentNode.lastElementChild)return 0}return-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());a.focus(),c.parents("ul,ol,menu")&&a.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(a,c){return b(c).is("ul,ol,menu")||b(c).parents("ul,ol,menu").length>0?0:-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());c.parents("ul,ol,menu")&&a.execCommand("outdent")},tooltip:"Remove one indent"},table:{forceNewLineAfter:["table"],exec:function(a){var b=this,c=e("table",{rows:b._("Rows:"),cols:b._("Cols:"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d,e,g=c.find("#rows").val()-0,h=c.find("#cols").val()-0,i="<table>";if(!(g<1||h<1)){for(d=0;d<g;d++){for(i+="<tr>",e=0;e<h;e++)i+="<td>"+(f?"":"<br />")+"</td>";i+="</tr>"}i+="</table>",b.wysiwygEditorInsertHtml(i),b.closeDropDown(!0),a.preventDefault()}}),b.createDropDown(a,"inserttable",c)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{forceNewLineAfter:["code"],exec:function(){this.wysiwygEditorInsertHtml("<code>",(f?"":"<br />")+"</code>")},tooltip:"Code"},image:{exec:function(a){var b=this,c=e("image",{url:b._("URL:"),width:b._("Width (optional):"),height:b._("Height (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#image").val(),e=c.find("#width").val(),f=c.find("#height").val(),g="";e&&(g+=' width="'+e+'"'),f&&(g+=' height="'+f+'"'),d&&b.wysiwygEditorInsertHtml("<img"+g+' src="'+d+'" />'),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertimage",c)},tooltip:"Insert an image"},email:{exec:function(a){var b=this,c=e("email",{label:b._("E-mail:"),desc:b._("Description (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#email").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml('<a href="mailto:'+d+'">'+e+"</a>")):b.execCommand("createlink","mailto:"+d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertemail",c)},tooltip:"Insert an email"},link:{exec:function(a){var b=this,c=e("link",{url:b._("URL:"),desc:b._("Description (optional):"),ins:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#link").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml('<a href="'+d+'">'+e+"</a>")):b.execCommand("createlink",d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertlink",c)},tooltip:"Insert a link"},unlink:{state:function(){var a=b(this.currentNode());return a.is("a")||a.parents("a").length>0?0:-1},exec:function(){var a=b(this.currentNode()),c=a.is("a")?a:a.parents("a").first();c.length&&c.replaceWith(c.contents())},tooltip:"Unlink"},quote:{forceNewLineAfter:["blockquote"],exec:function(a,b,c){var d="<blockquote>",e="</blockquote>";b?(c=c?"<cite>"+c+"</cite>":"",d=d+c+b+e,e=null):""===this.getRangeHelper().selectedHtml()&&(e=(f?"":"<br />")+e),this.wysiwygEditorInsertHtml(d,e)},tooltip:"Insert a Quote"},emoticon:{exec:function(a){var c=this,d=function(e){var f,g=c.opts.emoticonsCompat,h=c.getRangeHelper(),i=g&&" "!==h.getOuterText(!0,1)?" ":"",j=g&&" "!==h.getOuterText(!1,1)?" ":"",k=b("<div />"),l=b("<div />").appendTo(k),m=0,n=b.extend({},c.opts.emoticons.dropdown,e?c.opts.emoticons.more:{});return b.each(n,function(){m++}),m=Math.sqrt(m),b.each(n,function(a,d){l.append(b("<img />").attr({src:d.url||d,alt:a,title:d.tooltip||a}).click(function(){return c.insert(i+b(this).attr("alt")+j,null,!1).closeDropDown(!0),!1})),l.children().length>=m&&(l=b("<div />").appendTo(k))}),!e&&c.opts.emoticons.more&&(f=b('<a class="sceditor-more">'+c._("More")+"</a>").click(function(){return c.createDropDown(a,"more-emoticons",d(!0)),!1}),k.append(f)),k};c.createDropDown(a,"emoticons",d(!1))},txtExec:function(a){g.emoticon.exec.call(this,a)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(a,b,c){var d,f=e("youtubeMenu",{label:a._("Video URL:"),insert:a._("Insert")},!0);f.find(".button").click(function(b){var e=f.find("#link").val();e&&(d=e.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),d&&(e=d[1]),/^[a-zA-Z0-9_\-]{11}$/.test(e)?c(e):alert("Invalid YouTube video")),a.closeDropDown(!0),b.preventDefault()}),a.createDropDown(b,"insertlink",f)},exec:function(a){var b=this;g.youtube._dropDown(b,a,function(a){b.wysiwygEditorInsertHtml(e("youtube",{id:a}))})},tooltip:"Insert a YouTube video"},date:{_date:function(a){var b=new Date,c=b.getYear(),d=b.getMonth()+1,e=b.getDate();return c<2e3&&(c=1900+c),d<10&&(d="0"+d),e<10&&(e="0"+e),a.opts.dateFormat.replace(/year/i,c).replace(/month/i,d).replace(/day/i,e)},exec:function(){this.insertText(g.date._date(this))},txtExec:function(){this.insertText(g.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var a=new Date,b=a.getHours(),c=a.getMinutes(),d=a.getSeconds();return b<10&&(b="0"+b),c<10&&(c="0"+c),d<10&&(d="0"+d),b+":"+c+":"+d},exec:function(){this.insertText(g.time._time())},txtExec:function(){this.insertText(g.time._time())},tooltip:"Insert current time"},ltr:{state:function(a,b){return b&&"ltr"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("ltr"===d.css("direction")?d.css("direction",""):d.css("direction","ltr"))},tooltip:"Left-to-Right"},rtl:{state:function(a,b){return b&&"rtl"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("rtl"===d.css("direction")?d.css("direction",""):d.css("direction","rtl"))},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}};return g}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1);return{toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:null,locale:b("html").attr("lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}]),function(a){"use strict";var b=a.sceditor,c=b.plugins,d=b.dom,e={bold:{txtExec:["<strong>","</strong>"]},italic:{txtExec:["<em>","</em>"]},underline:{txtExec:['<span style="text-decoration: underline;">',"</span>"]},strike:{txtExec:['<span style="text-decoration: line-through;">',"</span>"]},subscript:{txtExec:["<sub>","</sub>"]},superscript:{txtExec:["<sup>","</sup>"]},left:{txtExec:['<div style="text-align: left;">',"</div>"]},center:{txtExec:['<div style="text-align: center;">',"</div>"]},right:{txtExec:['<div style="text-align: right;">',"</div>"]},justify:{txtExec:['<div style="text-align: justify;">',"</div>"]},font:{txtExec:function(a){var c=this;b.command.get("font")._dropDown(c,a,function(a){c.insertText('<span style="font-family: '+a+';">',"</span>")})}},size:{txtExec:function(a){var c=this;b.command.get("size")._dropDown(c,a,function(a){c.insertText('<span style="font-size: '+a+';">',"</span>")})}},color:{txtExec:function(a){var c=this;b.command.get("color")._dropDown(c,a,function(a){c.insertText('<span style="color: '+a+';">',"</span>")})}},bulletlist:{txtExec:["<ul><li>","</li></ul>"]},orderedlist:{txtExec:["<ol><li>","</li></ol>"]},table:{txtExec:["<table><tr><td>","</td></tr></table>"]},horizontalrule:{txtExec:["<hr />"]},code:{txtExec:["<code>","</code>"]},image:{txtExec:function(a,b){var c=prompt(this._("Enter the image URL:"),b);c&&this.insertText('<img src="'+c+'" />')}},email:{txtExec:function(a,b){var c,d,e=b&&b.indexOf("@")>-1?null:b;c=prompt(this._("Enter the e-mail address:"),e?"":b),d=prompt(this._("Enter the displayed text:"),e||c)||c,c&&this.insertText('<a href="mailto:'+c+'">'+d+"</a>")}},link:{txtExec:function(a,b){var c=b&&b.indexOf("http://")>-1?null:b,d=prompt(this._("Enter URL:"),c?"http://":b),e=prompt(this._("Enter the displayed text:"),c||d)||d;d&&this.insertText('<a href="'+d+'">'+e+"</a>")}},quote:{txtExec:["<blockquote>","</blockquote>"]},youtube:{txtExec:function(a){var c=this;b.command.get("youtube")._dropDown(c,a,function(a){c.insertText('<iframe width="560" height="315" src="https://www.youtube.com/embed/{id}?wmode=opaque" data-youtube-id="'+a+'" frameborder="0" allowfullscreen></iframe>')})}},rtl:{txtExec:['<div stlye="direction: rtl;">',"</div>"]},ltr:{txtExec:['<div stlye="direction: ltr;">',"</div>"]}};b.XHTMLSerializer=function(){var c,e,f,g,h,i,j,k,l,m,n=this,o={indentStr:"\t"},p=[],q=0;c=function(a){var b={"&":"&","<":"<",">":">",'"':"""};return a?a.replace(/[&<>"]/g,function(a){return b[a]||a}):""},e=function(a){return a.replace(/[\r\n]/," ").replace(/[^\S|\u00A0]+/g," ")},n.serialize=function(a,b){if(p=[],b)for(a=a.firstChild;a;)f(a),a=a.nextSibling;else f(a);return p.join("")},f=function(a,b){switch(a.nodeType){case 1:var c=a.nodeName.toLowerCase();"!"===c?j(a):h(a,b);break;case 3:k(a,b);break;case 4:i(a);break;case 8:j(a);break;case 9:case 11:g(a);break;case 2:case 5:case 6:case 7:case 10:case 12:}},g=function(a){for(var b=a.firstChild;b;)f(b),b=b.nextSibling},h=function(e,g){var h,i,j,k=e.nodeName.toLowerCase(),n="iframe"===k,o=e.attributes.length,p=e.firstChild,r=g||/pre(?:\-wrap)?$/i.test(a(e).css("whiteSpace")),s=!e.firstChild&&!d.canHaveChildren(e)&&!n;if(!a(e).hasClass("sceditor-ignore")){for(l("<"+k,!g&&m(e));o--;)i=e.attributes[o],(!b.ie||i.specified||"input"===k&&"value"===i.name)&&(j=b.ie<8&&/style/i.test(i.name)?e.style.cssText:i.value,l(" "+i.name.toLowerCase()+'="'+c(j)+'"',!1));for(l(s?" />":">",!1),n||(h=p);h;)q++,f(h,r),h=h.nextSibling,q--;s||l("</"+k+">",!r&&!n&&m(e)&&p&&m(p))}},i=function(a){l("<![CDATA["+c(a.nodeValue)+"]]>")},j=function(a){l("<!-- "+c(a.nodeValue)+" -->")},k=function(a,b){var d=a.nodeValue;b||(d=e(d)),d&&l(c(d),!b&&m(a))},l=function(a,b){var c=q;if(b!==!1)for(p.length&&p.push("\n");c--;)p.push(o.indentStr);p.push(a)},m=function(a){var b=a.previousSibling;return 1!==a.nodeType&&b?!d.isInline(b):!b&&!d.isInline(a.parentNode)||!d.isInline(a)}},c.xhtml=function(){var f,g,h,i,j,k,l,m=this,n={},o={};m.init=function(){a.isEmptyObject(c.xhtml.converters||{})||a.each(c.xhtml.converters,function(b,c){a.each(c.tags,function(a){n[a]||(n[a]=[]),n[a].push(c)})}),this.commands=a.extend(!0,{},e,this.commands)},m.signalToSource=function(a,c){return c=c.jquery?c[0]:c,f(c),i(c),k(c),l(c),(new b.XHTMLSerializer).serialize(c,!0)},m.signalToWysiwyg=function(a){return a},m.convertTagTo=d.convertElement,g=function(c,d,e){n[c]&&a.each(n[c],function(f,g){g.tags[c]?a.each(g.tags[c],function(c,f){e.getAttributeNode&&(c=e.getAttributeNode(c),!c||b.ie<8&&!c.specified||f&&a.inArray(c.value,f)<0||g.conv.call(m,e,d))}):g.conv&&g.conv.call(m,e,d)})},f=function(b){d.traverse(b,function(b){var c=a(b),d=b.nodeName.toLowerCase();g("*",c,b),g(d,c,b)},!0)},h=function(b,c){var e=b.childNodes,f=b.nodeName.toLowerCase(),g=b.nodeValue,i=e.length;if(c&&"br"===f)return!0;if(a(b).hasClass("sceditor-ignore"))return!0;if(!d.canHaveChildren(b))return!1;if(g&&/\S|\u00A0/.test(g))return!1;for(;i--;)if(!h(e[i],c&&!b.previousSibling&&!b.nextSibling))return!1;return!0},i=function(b){d.traverse(b,function(e){var f,g=e.nodeName.toLowerCase(),i=e.parentNode,j=e.nodeType,k=!d.isInline(e),l=e.previousSibling,m=e.nextSibling,n=i===b,o=!l&&!m,p="iframe"!==g&&h(e,n&&o&&"br"!==g),q=e.ownerDocument,r=c.xhtml.allowedTags,s=c.xhtml.disallowedTags;if(3!==j&&(4===j?g="!cdata":"!"!==g&&8!==j||(g="!comment"),p?f=!0:r&&r.length?f=a.inArray(g,r)<0:s&&s.length&&(f=a.inArray(g,s)>-1),f)){if(!p){for(k&&l&&d.isInline(l)&&i.insertBefore(q.createTextNode(" "),e);e.firstChild;)i.insertBefore(e.firstChild,m);k&&m&&d.isInline(m)&&i.insertBefore(q.createTextNode(" "),m)}i.removeChild(e)}},!0)},j=function(b,c){var d={};return b&&a.extend(d,b),c?(a.each(c,function(b,c){a.isArray(c)?d[b]=a.merge(d[b]||[],c):d[b]||(d[b]=null)}),d):d},l=function(b){var c=[],e=function(){c.length&&(a("<p>",b.ownerDocument).insertBefore(c[0]).append(c),c=[])};d.removeWhiteSpace(b);for(var f=b.firstChild;f;)d.isInline(f)&&!a(f).is(".sceditor-ignore")?c.push(f):e(),f=f.nextSibling;e()},k=function(b){var e,f,g,h,i,k,l=c.xhtml.allowedAttribs,m=l&&!a.isEmptyObject(l),n=c.xhtml.disallowedAttribs,p=n&&!a.isEmptyObject(n);o={},d.traverse(b,function(b){if(b.attributes&&(e=b.nodeName.toLowerCase(),h=b.attributes.length))for(o[e]||(m?o[e]=j(l["*"],l[e]):o[e]=j(n["*"],n[e]));h--;)f=b.attributes[h],g=f.name,i=o[e][g],k=!1,m?k=null!==i&&(!a.isArray(i)||a.inArray(f.value,i)<0):p&&(k=null===i||a.isArray(i)&&a.inArray(f.value,i)>-1),k&&b.removeAttribute(g)})}},c.xhtml.converters=[{tags:{"*":{width:null}},conv:function(a,b){b.css("width",b.attr("width")).removeAttr("width")}},{tags:{"*":{height:null}},conv:function(a,b){b.css("height",b.attr("height")).removeAttr("height")}},{tags:{li:{value:null}},conv:function(a,c){b.ie<8?a.removeAttribute("value"):c.removeAttr("value")}},{tags:{"*":{text:null}},conv:function(a,b){b.css("color",b.attr("text")).removeAttr("text")}},{tags:{"*":{color:null}},conv:function(a,b){b.css("color",b.attr("color")).removeAttr("color")}},{tags:{"*":{face:null}},conv:function(a,b){b.css("fontFamily",b.attr("face")).removeAttr("face")}},{tags:{"*":{align:null}},conv:function(a,b){b.css("textAlign",b.attr("align")).removeAttr("align")}},{tags:{"*":{border:null}},conv:function(a,b){b.css("borderWidth",b.attr("border")).removeAttr("border")}},{tags:{applet:{name:null},img:{name:null},layer:{name:null},map:{name:null},object:{name:null},param:{name:null}},conv:function(a,b){b.attr("id")||b.attr("id",b.attr("name")),b.removeAttr("name")}},{tags:{"*":{vspace:null}},conv:function(a,b){b.css("marginTop",b.attr("vspace")-0).css("marginBottom",b.attr("vspace")-0).removeAttr("vspace")}},{tags:{"*":{hspace:null}},conv:function(a,b){b.css("marginLeft",b.attr("hspace")-0).css("marginRight",b.attr("hspace")-0).removeAttr("hspace")}},{tags:{hr:{noshade:null}},conv:function(a,b){b.css("borderStyle","solid").removeAttr("noshade")}},{tags:{"*":{nowrap:null}},conv:function(a,b){b.css("white-space","nowrap").removeAttr("nowrap")}},{tags:{big:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","larger")}},{tags:{small:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","smaller")}},{tags:{b:null},conv:function(b){a(this.convertTagTo(b,"strong"))}},{tags:{u:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","underline")}},{tags:{i:null},conv:function(b){a(this.convertTagTo(b,"em"))}},{tags:{s:null,strike:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","line-through")}},{tags:{dir:null},conv:function(a){this.convertTagTo(a,"ul")}},{tags:{center:null},conv:function(b){a(this.convertTagTo(b,"div")).css("textAlign","center")}},{tags:{font:{size:null}},conv:function(a,c){var d=c.css("fontSize"),e=d;"+0"!==e&&(b.ie<9&&(e=10,d>1&&(e=13),d>2&&(e=16),d>3&&(e=18),d>4&&(e=24),d>5&&(e=32),d>6&&(e=48)),c.css("fontSize",e)),c.removeAttr("size")}},{tags:{font:null},conv:function(a){this.convertTagTo(a,"span")}},{tags:{"*":{type:["_moz"]}},conv:function(a,b){b.removeAttr("type")}},{tags:{"*":{_moz_dirty:null}},conv:function(a,b){b.removeAttr("_moz_dirty")}},{tags:{"*":{_moz_editor_bogus_node:null}},conv:function(a,b){b.remove()}}],c.xhtml.allowedAttribs={},c.xhtml.disallowedAttribs={},c.xhtml.allowedTags=[],c.xhtml.disallowedTags=[]}(jQuery); | ||
/* SCEditor v2.0.0-beta1 | (C) 2017, Sam Clarke | sceditor.com/license */ | ||
!function(e){"use strict";function t(e,t){return typeof t===e}function n(e){return!Object.keys(e).length}function o(e,t){for(var n=e===!!e,i=n?2:1,r=n?t:e,a=!!n&&e;i<arguments.length;i++){var l=arguments[i];for(var c in l){var s=l[c];if(!le(s)){var u=null!==s&&"object"==typeof s,d=Array.isArray(s);r[c]=a&&(u||d)?o(!0,r[c]||(d?[]:{}),s):s}}}return r}function i(e,t){var n=e.indexOf(t);n>-1&&e.splice(n,1)}function r(e,t){if(Array.isArray(e)||"length"in e&&se(e.length))for(var n=0;n<e.length;n++)t(n,e[n]);else Object.keys(e).forEach(function(n){t(n,e[n])})}function a(e){return e=parseFloat(e),isFinite(e)?e:0}function l(e,t,n){var o=(n||document).createElement(e);return r(t||{},function(e,t){"style"===e?o.style.cssText=t:e in o?o[e]=t:o.setAttribute(e,t)}),o}function c(e,t){for(var n=[],o=e||{};(o=o.parentNode)&&!/(9|11)/.test(o.nodeType);)t&&!E(o,t)||n.push(o);return n}function s(e,t){for(var n=e||{};(n=n.parentNode)&&!/(9|11)/.test(n.nodeType);)if(!t||E(n,t))return n}function u(e,t){return E(e,t)?e:s(e,t)}function d(e){e.parentNode.removeChild(e)}function f(e,t){e.appendChild(t)}function p(e,t){return e.querySelectorAll(t)}function m(e,t,n,o,i){t.split(" ").forEach(function(t){var r;ae(n)?(r=o["_sce-event-"+t+n]||function(t){for(var i=t.target;i&&i!==e;){if(E(i,n))return void o.call(i,t);i=i.parentNode}},o["_sce-event-"+t+n]=r):(r=n,i=o),e.addEventListener(t,r,i||!1)})}function g(e,t,n,o,i){t.split(" ").forEach(function(t){var r;ae(n)?r=o["_sce-event-"+t+n]:(r=n,i=o),e.removeEventListener(t,r,i||!1)})}function h(e,t,n){if(arguments.length<3)return e.getAttribute(t);null==n?v(e,t):e.setAttribute(t,n)}function v(e,t){e.removeAttribute(t)}function y(e){w(e,"display","none")}function b(e){w(e,"display","")}function x(e){A(e)?y(e):b(e)}function w(e,t,n){if(arguments.length<3){if(ae(t))return getComputedStyle(e)[t];r(t,function(t,n){w(e,t,n)})}else{var o=(n||0===n)&&!isNaN(n);e.style[t]=o?n+"px":n}}function C(e,t,n){var o=arguments.length,i={};if(e.nodeType===de){if(1===o)return r(e.attributes,function(e,t){/^data\-/i.test(t.name)&&(i[t.name.substr(5)]=t.value)}),i;if(2===o)return h(e,"data-"+t);h(e,"data-"+t,String(n))}}function E(e,t){var n=!1;return e&&e.nodeType===de&&(n=(e.matches||e.msMatchesSelector||e.webkitMatchesSelector).call(e,t)),n}function k(e,t){return e!==t&&e.contains&&e.contains(t)}function S(e,t){var n=e.previousElementSibling;return t&&n?E(n,t)?n:null:n}function T(e,t){return t.parentNode.insertBefore(e,t)}function D(e){return e.className.trim().split(/\s+/)}function M(e,t){return E(e,"."+t)}function N(e,t){var n=D(e);n.indexOf(t)<0&&n.push(t),e.className=n.join(" ")}function R(e,t){var n=D(e);i(n,t),e.className=n.join(" ")}function H(e,t,n){(n=le(n)?!M(e,t):n)?N(e,t):R(e,t)}function F(e,t){if(le(t)){var n=getComputedStyle(e),o=a(n.paddingLeft)+a(n.paddingRight),i=a(n.borderLeftWidth)+a(n.borderRightWidth);return e.offsetWidth-o-i}w(e,"width",t)}function z(e,t){if(le(t)){var n=getComputedStyle(e),o=a(n.paddingTop)+a(n.paddingBottom),i=a(n.borderTopWidth)+a(n.borderBottomWidth);return e.offsetHeight-o-i}w(e,"height",t)}function _(e,t,n){var o;ce(window.CustomEvent)?o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n}):(o=e.ownerDocument.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,n),e.dispatchEvent(o)}function A(e){return!!e.getClientRects().length}function O(e){return e.replace(/^-ms-/,"ms-").replace(/-(\w)/g,function(e,t){return t.toUpperCase()})}function B(e,t,n,o,i){for(e=i?e.lastChild:e.firstChild;e;){var r=i?e.previousSibling:e.nextSibling;if(!n&&!1===t(e)||!o&&!1===B(e,t,n,o,i)||n&&!1===t(e))return!1;e=r}}function I(e,t,n,o){B(e,t,n,o,!0)}function L(e,t){var n=(t=t||document).createDocumentFragment(),o=l("div",{},t);for(o.innerHTML=e;o.firstChild;)f(n,o.firstChild);return n}function V(e){return e&&(!E(e,"p,div")||e.className||h(e,"style")||!n(C(e)))}function P(e,t){var n=l(t,{},e.ownerDocument);for(r(e.attributes,function(e,t){try{h(n,t.name,t.value)}catch(e){}});e.firstChild;)f(n,e.firstChild);return e.parentNode.replaceChild(n,e),n}function W(e){return!!/11?|9/.test(e.nodeType)&&"|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr|isindex|link|meta|param|command|embed|keygen|source|track|object|".indexOf("|"+e.nodeName.toLowerCase()+"|")<0}function j(e,t){var n,o=(e||{}).nodeType||fe;return o!==de?o===fe:"code"===(n=e.tagName.toLowerCase())?!t:me.indexOf("|"+n+"|")<0}function q(e,t){t.style.cssText=e.style.cssText+t.style.cssText}function U(e){var t=function(e){for(;j(e.parentNode,!0);)e=e.parentNode;return e};B(e,function(e){var n=!j(e,!0);if(n&&j(e.parentNode,!0)){var o=t(e),i=K(o,e),r=e;q(o,r),T(i,o),T(r,o)}if(n&&E(e,"ul,ol")&&E(e.parentNode,"ul,ol")){var a=S(e,"li");a||T(a=l("li"),e),f(a,e)}})}function $(e,t){return e?(t?e.previousSibling:e.nextSibling)||$(e.parentNode,t):null}function Y(e){var t,n,o,i,r,a,l,c=w(e,"whiteSpace"),s=/line$/i.test(c),u=e.firstChild;if(!/pre(\-wrap)?$/i.test(c))for(;u;){if(a=u.nextSibling,t=u.nodeValue,(n=u.nodeType)===de&&u.firstChild&&Y(u),n===fe){for(o=$(u),i=$(u,!0),l=!1;M(i,"sceditor-ignore");)i=$(i,!0);if(j(u)&&i){for(r=i;r.lastChild;)r=r.lastChild;l=r.nodeType===fe?/[\t\n\r ]$/.test(r.nodeValue):!j(r)}t=t.replace(/\u200B/g,""),i&&j(i)&&!l||(t=t.replace(s?/^[\t ]+/:/^[\t\n\r ]+/,"")),o&&j(o)||(t=t.replace(s?/[\t ]+$/:/[\t\n\r ]+$/,"")),t.length?u.nodeValue=t.replace(s?/[\t ]+/g:/[\t\n\r ]+/g," "):d(u)}u=a}}function K(e,t){var n=e.ownerDocument.createRange();return n.setStartBefore(e),n.setEndAfter(t),n.extractContents()}function X(e){for(var t=0,n=0;e;)t+=e.offsetLeft,n+=e.offsetTop,e=e.offsetParent;return{left:t,top:n}}function Q(e,t){var n,o,i=e.style;if(ue[t]||(ue[t]=O(t)),t=ue[t],o=i[t],"textAlign"===t){if(n=i.direction,o=o||w(e,t),w(e.parentNode,t)===o||"block"!==w(e,"display")||E(e,"hr,th"))return"";if(/right/i.test(o)&&"rtl"===n||/left/i.test(o)&&"ltr"===n)return""}return o}function G(e){return e.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")}function J(e,t){if(!e)return e;var n={"&":"&","<":"<",">":">"," ":" ","\r\n":"<br />","\r":"<br />","\n":"<br />"};return!1!==t&&(n['"']=""",n["'"]="'",n["`"]="`"),e=e.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(e){return n[e]||e})}function Z(e){if("mozHidden"in document)for(var t,n=e.getBody();n;){if((t=n).firstChild)t=t.firstChild;else{for(;t&&!t.nextSibling;)t=t.parentNode;t&&(t=t.nextSibling)}3===n.nodeType&&/[\n\r\t]+/.test(n.nodeValue)&&(/^pre/.test(w(n.parentNode,"whiteSpace"))||d(n)),n=t}}function ee(e){var t=this,n=[],o=function(e){return"signal"+e.charAt(0).toUpperCase()+e.slice(1)},i=function(t,i){t=[].slice.call(t);var r,a,l=o(t.shift());for(r=0;r<n.length;r++)if(l in n[r]&&(a=n[r][l].apply(e,t),i))return a};t.call=function(){i(arguments,!1)},t.callOnlyFirst=function(){return i(arguments,!0)},t.hasHandler=function(e){var t=n.length;for(e=o(e);t--;)if(e in n[t])return!0;return!1},t.exists=function(e){return e in Te&&"function"==typeof(e=Te[e])&&"object"==typeof e.prototype},t.isRegistered=function(e){if(t.exists(e))for(var o=n.length;o--;)if(n[o]instanceof Te[e])return!0;return!1},t.register=function(o){return!(!t.exists(o)||t.isRegistered(o)||(o=new Te[o],n.push(o),"init"in o&&o.init.call(e),0))},t.deregister=function(o){var i,r=n.length,a=!1;if(!t.isRegistered(o))return a;for(;r--;)n[r]instanceof Te[o]&&(a=!0,"destroy"in(i=n.splice(r,1)[0])&&i.destroy.call(e));return a},t.destroy=function(){for(var t=n.length;t--;)"destroy"in n[t]&&n[t].destroy.call(e);n=[],e=null}}function te(e,t){var n,o,i=t||e.contentDocument||e.document,r="sceditor-start-marker",a="sceditor-end-marker",c=this;c.insertHTML=function(e,t){var n,o;if(!c.selectedRange())return!1;for(t&&(e+=c.selectedHtml()+t),o=l("p",{},i),n=i.createDocumentFragment(),o.innerHTML=e;o.firstChild;)f(n,o.firstChild);c.insertNode(n)},o=function(e,t,o){var s,u=i.createDocumentFragment();if("string"==typeof e?(t&&(e+=c.selectedHtml()+t),u=L(e)):(f(u,e),t&&(f(u,c.selectedRange().extractContents()),f(u,t))),s=u.lastChild){for(;!j(s.lastChild,!0);)s=s.lastChild;if(W(s)?s.lastChild||f(s,document.createTextNode("")):s=u,c.removeMarkers(),f(s,n(r)),f(s,n(a)),o){var d=l("div");return f(d,u),d.innerHTML}return u}},c.insertNode=function(e,t){var n=o(e,t),i=c.selectedRange(),r=i.commonAncestorContainer;if(!n)return!1;i.deleteContents(),r&&3!==r.nodeType&&!W(r)?T(n,r):i.insertNode(n),c.restoreRange()},c.cloneSelected=function(){var e=c.selectedRange();if(e)return e.cloneRange()},c.selectedRange=function(){var t,n,o=e.getSelection();if(o){if(o.getRangeAt&&o.rangeCount<=0){for(n=i.body;n.firstChild;)n=n.firstChild;(t=i.createRange()).setStartBefore(n),o.addRange(t)}return o.rangeCount>0&&(t=o.getRangeAt(0)),t}},c.hasSelection=function(){var t=e.getSelection();return t&&t.rangeCount>0},c.selectedHtml=function(){var e,t=c.selectedRange();return t?(e=l("p",{},i),f(e,t.cloneContents()),e.innerHTML):""},c.parentNode=function(){var e=c.selectedRange();if(e)return e.commonAncestorContainer},c.getFirstBlockParent=function(e){var t=function(e){return j(e,!0)&&(e=e?e.parentNode:null)?t(e):e};return t(e||c.parentNode())},c.insertNodeAt=function(e,t){var n=c.selectedRange(),o=c.cloneSelected();if(!o)return!1;o.collapse(e),o.insertNode(t),c.selectRange(n)},n=function(e){c.removeMarker(e);var t=l("span",{id:e,className:"sceditor-selection sceditor-ignore",style:"display:none;line-height:0"},i);return t.innerHTML=" ",t},c.insertMarkers=function(){var e=c.selectedRange(),t=n(r);c.removeMarkers(),c.insertNodeAt(!0,t),e&&e.collapsed?t.parentNode.insertBefore(n(a),t.nextSibling):c.insertNodeAt(!1,n(a))},c.getMarker=function(e){return i.getElementById(e)},c.removeMarker=function(e){var t=c.getMarker(e);t&&d(t)},c.removeMarkers=function(){c.removeMarker(r),c.removeMarker(a)},c.saveRange=function(){c.insertMarkers()},c.selectRange=function(t){var n,o=e.getSelection(),r=t.endContainer;if(!De&&t.collapsed&&r&&!j(r,!0)){for(n=r.lastChild;n&&E(n,".sceditor-ignore");)n=n.previousSibling;if(E(n,"br")){var a=i.createRange();a.setEndAfter(n),a.collapse(!1),c.compare(t,a)&&(t.setStartBefore(n),t.collapse(!0))}}o&&(c.clear(),o.addRange(t))},c.restoreRange=function(){var e,t=c.selectedRange(),n=c.getMarker(r),o=c.getMarker(a);if(!n||!o||!t)return!1;e=n.nextSibling===o,(t=i.createRange()).setStartBefore(n),t.setEndAfter(o),e&&t.collapse(!0),c.selectRange(t),c.removeMarkers()},c.selectOuterText=function(e,t){var n,o,i=c.cloneSelected();if(!i)return!1;i.collapse(!1),n=Me(i,!0,e),o=Me(i,!1,t),i.setStart(n.node,n.offset),i.setEnd(o.node,o.offset),c.selectRange(i)},c.getOuterText=function(e,t){var n=c.cloneSelected();return n?(n.collapse(!e),Me(n,e,t).text):""},c.replaceKeyword=function(e,t,n,o,i,r){n||e.sort(function(e,t){return e[0].length-t[0].length});var a,l,s,u,d,f,p,m,g=e.length,h=i?1:0,v=o||e[g-1][0].length;for(i&&v++,r=r||"",d=(a=c.getOuterText(!0,v)).length,a+=r,t&&(a+=c.getOuterText(!1,v));g--;)if(p=e[g][0],m=p.length,u=Math.max(0,d-m-h),s=-1,i?(l=a.substr(u).match(new RegExp("(^|[\\s ])"+G(p)+"(^|[\\s ])")))&&(s=l.index+u+l[1].length):s=a.indexOf(p,u),s>-1&&s<=d&&s+m+h>=d)return f=d-s,c.selectOuterText(f,m-f-(/^\S/.test(r)?1:0)),c.insertHTML(e[g][1]),!0;return!1},c.compare=function(e,t){return t||(t=c.selectedRange()),e&&t?0===e.compareBoundaryPoints(Range.END_TO_END,t)&&0===e.compareBoundaryPoints(Range.START_TO_START,t):!e&&!t},c.clear=function(){var t=e.getSelection();t&&(t.removeAllRanges?t.removeAllRanges():t.empty&&t.empty())}}function ne(e,t){var n=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/,o=e&&p(e,"img[data-sceditor-emoticon]");if(e&&o.length)for(var i=0;i<o.length;i++){var r=o[i],a=r.parentNode,l=r.previousSibling,c=r.nextSibling;if(l&&n.test(l.nodeValue.slice(-1))||c&&n.test((c.nodeValue||"")[0])){var s=t.cloneSelected(),u=-1,f=s.startContainer,m=l.nodeValue;null===m&&(m=l.innerText||""),m+=C(r,"sceditor-emoticon"),f===c&&(u=m.length+s.startOffset),f===e&&e.childNodes[s.startOffset]===c&&(u=m.length),f===l&&(u=s.startOffset),c&&c.nodeType===fe||(c=a.insertBefore(a.ownerDocument.createTextNode(""),c)),c.insertData(0,m),d(l),d(r),u>-1&&(s.setStart(c,u),s.collapse(!0),t.selectRange(s))}}}function oe(e,t,n){var o=e.ownerDocument,i="(^|\\s| | | | |$)",a=[],l={};s(e,"code")||(r(t,function(e){l[e]=new RegExp(i+G(e)+i),a.push(e)}),a.sort(function(e,t){return t.length-e.length}),function e(i){for(i=i.firstChild;i;){if(i.nodeType!==de||E(i,"code")||e(i),i.nodeType===fe)for(var r=0;r<a.length;r++){var c=i.nodeValue,s=a[r],u=n?c.search(l[s]):c.indexOf(s);if(u>-1){var d=c.indexOf(s,u),f=L(t[s],o),p=c.substr(d+s.length);f.appendChild(o.createTextNode(p)),i.nodeValue=c.substr(0,d),i.parentNode.insertBefore(f,i.nextSibling)}}i=i.nextSibling}}(e))}function ie(e,t){var n;B(e,function(e){j(e,!0)?(n||T(n=l("p",{},t),e),e.nodeType===fe&&""===e.nodeValue||f(n,e)):n=null},!1,!0)}function re(e,t){var n,a,c,s,v,k,S,D,O,B,L,q,$,K,Q,G,Z,se,ue,me,he,ve,we,Ce,ke,Te,De,Me,_e,Ae,Oe,Be,Ie,Le,Ve,Pe,We,je,qe,Ue,$e,Ye,Ke,Xe,Qe,Ge,Je,Ze,et,tt,nt,ot,it,rt,at,lt,ct,st,ut,dt,ft,pt,mt=this,gt=e.get?e.get(0):e,ht={},vt=[],yt=[],bt={},xt={},wt={};mt.commands=o(!0,{},t.commands||Se);var Ct=mt.opts=o(!0,{},ge,t);mt.opts.emoticons=t.emoticons||ge.emoticons,Te=function(){gt._sceditor=mt,Ct.locale&&"en"!==Ct.locale&&Be(),T(a=l("div",{className:"sceditor-container"}),gt),w(a,"z-index",Ct.zIndex),He&&N(a,"ie ie"+He),ue=gt.required,gt.required=!1;var e=re.formats[Ct.format];"init"in(n=e?new e:{})&&n.init.call(mt),Oe(),We(),Ie(),Ae(),Le(),Ve(),xe||mt.toggleSourceMode(),et();var t=function(){g(Ne,"load",t),Ct.autofocus&&rt(),pt(),nt(),K.call("ready"),"onReady"in n&&n.onReady.call(mt)};m(Ne,"load",t),"complete"===Re.readyState&&t()},Oe=function(){var e=Ct.plugins;e=e?e.toString().split(","):[],K=new ee(mt),e.forEach(function(e){K.register(e.trim())})},Be=function(){var e;(q=re.locale[Ct.locale])||(e=Ct.locale.split("-"),q=re.locale[e[0]]),q&&q.dateFormat&&(Ct.dateFormat=q.dateFormat)},Ae=function(){S=l("textarea"),s=l("iframe",{frameborder:0,allowfullscreen:!0}),Ct.startInSourceMode?(N(a,"sourceMode"),y(s)):(N(a,"wysiwygMode"),y(S)),Ct.spellcheck||h(a,"spellcheck","false"),"https:"===Ne.location.protocol&&h(s,"src","javascript:false"),f(a,s),f(a,S),mt.dimensions(Ct.width||F(gt),Ct.height||z(gt));var e=He?"ie ie"+He:"";e+=be?" ios":"",(k=s.contentDocument).open(),k.write(Ee("html",{attrs:' class="'+e+'"',spellcheck:Ct.spellcheck?"":'spellcheck="false"',charset:Ct.charset,style:Ct.style})),k.close(),v=k.body,mt.readOnly(!!Ct.readOnly),(be||ye||He)&&(z(v,"100%"),He||m(v,"touchend",mt.focus));var t=h(gt,"tabindex");h(S,"tabindex",t),h(s,"tabindex",t),$=new te(s.contentWindow),y(gt),mt.val(gt.value);var n=Ct.placeholder||h(gt,"placeholder");n&&(S.placeholder=n,h(v,"placeholder",n))},Le=function(){Ct.autoUpdate&&(m(v,"blur",ft),m(S,"blur",ft)),null===Ct.rtl&&(Ct.rtl="rtl"===w(S,"direction")),mt.rtl(!!Ct.rtl),Ct.autoExpand&&(m(v,"load",pt,pe),m(k,"input keyup",pt)),Ct.resizeEnabled&&Pe(),h(a,"id",Ct.id),mt.emoticons(Ct.emoticonsEnabled)},Ve=function(){var e=gt.form,t="onselectionchange"in k?"selectionchange":"keyup focus blur contextmenu mouseup touchend click";m(Re,"click",Je),e&&(m(e,"reset",Ke),m(e,"submit",mt.updateOriginal,pe)),m(v,"keypress",Ye),m(v,"keydown",Ue),m(v,"keydown",$e),m(v,"keyup",nt),m(v,"blur",ut),m(v,"keyup",dt),m(v,"paste",je),m(v,"compositionstart compositionend",Qe),m(v,t,ot),m(v,"keydown keyup keypress focus blur contextmenu",Ge),Ct.emoticonsCompat&&Ne.getSelection&&m(v,"keyup",lt),m(v,"blur",function(){mt.val()||N(v,"placeholder")}),m(v,"focus",function(){R(v,"placeholder")}),m(S,"blur",ut),m(S,"keyup",dt),m(S,"keydown",Ue),m(S,"compositionstart compositionend",Qe),m(S,"keydown keyup keypress focus blur contextmenu",Ge),m(k,"mousedown",Xe),m(k,t,ot),m(k,"beforedeactivate keyup mouseup",_e),m(k,"keyup",nt),m(k,"focus",function(){O=null}),m(a,"selectionchanged",it),m(a,"selectionchanged",et),m(a,"selectionchanged valuechanged nodechanged",Ge)},Ie=function(){var e,t=mt.commands,n=(Ct.toolbarExclude||"").split(","),o=Ct.toolbar.split("|");c=l("div",{className:"sceditor-toolbar",unselectable:"on"}),Ct.icons in re.icons&&(ke=new re.icons[Ct.icons]),r(o,function(o,i){e=l("div",{className:"sceditor-group"}),r(i.split(","),function(o,i){var r,a,l=t[i];!l||n.indexOf(i)>-1||(a=l.shortcut,r=Ee("toolbarButton",{name:i,dispName:mt._(l.name||l.tooltip||i)},!0).firstChild,ke&&ke.create&&ke.create(i)&&(T(ke.create(i),r.firstChild),N(r,"has-icon")),r._sceTxtMode=!!l.txtExec,r._sceWysiwygMode=!!l.exec,H(r,"disabled",!l.exec),m(r,"click",function(e){M(r,"disabled")||Me(r,l),et(),e.preventDefault()}),m(r,"mousedown",function(e){mt.closeDropDown(),e.preventDefault()}),l.tooltip&&h(r,"title",mt._(l.tooltip)+(a?" ("+a+")":"")),a&&mt.addShortcut(a,i),l.state?yt.push({name:i,state:l.state}):ae(l.exec)&&yt.push({name:i,state:l.exec}),f(e,r),xt[i]=r)}),e.firstChild&&f(c,e)}),f(Ct.toolbarContainer||a,c)},Pe=function(){var e,t,n,o,i,r,c=l("div",{className:"sceditor-grip"}),s=l("div",{className:"sceditor-resize-cover"}),u="touchcancel touchend mouseup",d=0,p=0,h=0,v=0,x=0,w=0,C=F(a),E=z(a),k=!1,S=mt.rtl();if(e=Ct.resizeMinHeight||E/1.5,t=Ct.resizeMaxHeight||2.5*E,n=Ct.resizeMinWidth||C/1.25,o=Ct.resizeMaxWidth||1.25*C,i=function(i){"touchmove"===i.type?(i=Ne.event,h=i.changedTouches[0].pageX,v=i.changedTouches[0].pageY):(h=i.pageX,v=i.pageY);var r=w+(v-p),a=S?x-(h-d):x+(h-d);o>0&&a>o&&(a=o),n>0&&a<n&&(a=n),Ct.resizeWidth||(a=!1),t>0&&r>t&&(r=t),e>0&&r<e&&(r=e),Ct.resizeHeight||(r=!1),(a||r)&&mt.dimensions(a,r),i.preventDefault()},r=function(e){k&&(k=!1,y(s),R(a,"resizing"),g(Re,"touchmove mousemove",i),g(Re,u,r),e.preventDefault())},ke&&ke.create){var T=ke.create("grip");T&&(f(c,T),N(c,"has-icon"))}f(a,c),f(a,s),y(s),m(c,"touchstart mousedown",function(e){"touchstart"===e.type?(e=Ne.event,d=e.touches[0].pageX,p=e.touches[0].pageY):(d=e.pageX,p=e.pageY),x=F(a),w=z(a),k=!0,N(a,"resizing"),b(s),m(Re,"touchmove mousemove",i),m(Re,u,r),e.preventDefault()})},We=function(){var e=Ct.emoticons,t=Ct.emoticonsRoot||"";e&&(wt=o({},e.more,e.dropdown,e.hidden)),r(wt,function(e,n){wt[e]=Ee("emoticon",{key:e,url:t+(n.url||n),tooltip:n.tooltip||e}),Ct.emoticonsEnabled&&vt.push(l("img",{src:t+(n.url||n)}))})},rt=function(){var e,t,n=v.firstChild,o=!!Ct.autofocusEnd;if(A(a)){if(mt.sourceMode())return t=o?S.value.length:0,void S.setSelectionRange(t,t);if(Y(v),o)for((n=v.lastChild)||(n=l("p",{},k),f(v,n));n.lastChild;)n=n.lastChild,!Fe&&E(n,"br")&&n.previousSibling&&(n=n.previousSibling);e=k.createRange(),W(n)?e.selectNodeContents(n):(e.setStartBefore(n),o&&e.setStartAfter(n)),e.collapse(!o),$.selectRange(e),Z=e,o&&(v.scrollTop=v.scrollHeight),mt.focus()}},mt.readOnly=function(e){return"boolean"!=typeof e?!S.readonly:(v.contentEditable=!e,S.readonly=!e,Ze(e),mt)},mt.rtl=function(e){var t=e?"rtl":"ltr";return"boolean"!=typeof e?"rtl"===h(S,"dir"):(h(v,"dir",t),h(S,"dir",t),R(a,"rtl"),R(a,"ltr"),N(a,t),ke&&ke.rtl&&ke.rtl(e),mt)},Ze=function(e){var t=mt.inSourceMode()?"_sceTxtMode":"_sceWysiwygMode";r(xt,function(n,o){H(o,"disabled",e||!o[t])})},mt.width=function(e,t){return e||0===e?(mt.dimensions(e,null,t),mt):F(a)},mt.dimensions=function(e,t,n){return e=!(!e&&0!==e)&&e,t=!(!t&&0!==t)&&t,!1===e&&!1===t?{width:mt.width(),height:mt.height()}:(!1!==e&&(!1!==n&&(Ct.width=e),F(a,e)),!1!==t&&(!1!==n&&(Ct.height=t),z(a,t)),mt)},mt.height=function(e,t){return e||0===e?(mt.dimensions(null,e,t),mt):z(a)},mt.maximize=function(e){return le(e)?M(a,"sceditor-maximize"):((e=!!e)&&(we=Ne.pageYOffset),H(Re.documentElement,"sceditor-maximize",e),H(Re.body,"sceditor-maximize",e),H(a,"sceditor-maximize",e),mt.width(e?"100%":Ct.width,!1),mt.height(e?"100%":Ct.height,!1),e||Ne.scrollTo(0,we),pt(),mt)},pt=function(){Ct.autoExpand&&!ve&&setTimeout(mt.expandToContent,200)},mt.expandToContent=function(e){if(!mt.maximize()){if(ve=!1,!he){var t=Ct.resizeMinHeight||Ct.height||z(gt);he={min:t,max:Ct.resizeMaxHeight||2*t}}var n=Re.createRange();n.selectNodeContents(v);var o=n.getBoundingClientRect(),i=k.documentElement.clientHeight,r=o.bottom-o.top,a=mt.height()+(r-i);e||-1===he.max||(a=Math.min(a,he.max)),mt.height(Math.ceil(Math.max(a,he.min)))}},mt.destroy=function(){if(K){K.destroy(),$=null,O=null,K=null,D&&d(D),g(Re,"click",Je);var e=gt.form;e&&(g(e,"reset",Ke),g(e,"submit",mt.updateOriginal)),d(S),d(c),d(a),delete gt._sceditor,b(gt),gt.required=ue}},mt.createDropDown=function(e,t,n,i){var a,c="sceditor-"+t;mt.closeDropDown(!0),D&&M(D,c)||(!1!==i&&r(p(n,":not(input):not(textarea)"),function(e,t){t.nodeType===de&&h(t,"unselectable","on")}),a=o({top:X(e).top,left:X(e).left,marginTop:e.clientHeight},Ct.dropDownCss),w(D=l("div",{className:"sceditor-dropdown "+c}),a),f(D,n),f(Re.body,D),m(D,"click focusin",function(e){e.stopPropagation()}),setTimeout(function(){if(D){var e=p(D,"input,textarea")[0];e&&e.focus()}}))},Je=function(e){3!==e.which&&D&&!e.defaultPrevented&&(ft(),mt.closeDropDown())},je=function(e){var t=He||ye,n=v,o=e.clipboardData;if(o&&!t){var i={},r=o.types,a=o.items;e.preventDefault();for(var l=0;l<r.length;l++){if(Ne.FileReader&&a&&ze.test(a[l].type))return function(e){var t=new FileReader;t.onload=function(e){qe({html:'<img src="'+e.target.result+'" />'})},t.readAsDataURL(e)}(o.items[l].getAsFile());i[r[l]]=o.getData(r[l])}i.text=i["text/plain"],i.html=i["text/html"],qe(i)}else if(!Ce){var c=n.scrollTop;for($.saveRange(),Ce=Re.createDocumentFragment();n.firstChild;)f(Ce,n.firstChild);setTimeout(function(){var e=n.innerHTML;n.innerHTML="",f(n,Ce),n.scrollTop=c,Ce=!1,$.restoreRange(),qe({html:e})},0)}},qe=function(e){var t=l("div",{},k);K.call("pasteRaw",e),e.html?(t.innerHTML=e.html,U(t)):t.innerHTML=J(e.text||"");var o={val:t.innerHTML};"fragmentToSource"in n&&(o.val=n.fragmentToSource(o.val,k,Q)),K.call("paste",o),"fragmentToHtml"in n&&(o.val=n.fragmentToHtml(o.val,Q)),K.call("pasteHtml",o),mt.wysiwygEditorInsertHtml(o.val,null,!0)},mt.closeDropDown=function(e){D&&(d(D),D=null),!0===e&&mt.focus()},mt.wysiwygEditorInsertHtml=function(e,t,n){var o,i,r,a=z(s);mt.focus(),!n&&u(G,"code")||($.insertHTML(e,t),$.saveRange(),De(),b(o=p(v,"#sceditor-end-marker")[0]),i=v.scrollTop,r=X(o).top+1.5*o.offsetHeight-a,y(o),(r>i||r+a<i)&&(v.scrollTop=r),st(!1),$.restoreRange(),nt())},mt.wysiwygEditorInsertText=function(e,t){mt.wysiwygEditorInsertHtml(J(e),J(t))},mt.insertText=function(e,t){return mt.inSourceMode()?mt.sourceEditorInsertText(e,t):mt.wysiwygEditorInsertText(e,t),mt},mt.sourceEditorInsertText=function(e,t){var n,o,i=S.selectionStart,r=S.selectionEnd;n=S.scrollTop,S.focus(),o=S.value,t&&(e+=o.substring(i,r)+t),S.value=o.substring(0,i)+e+o.substring(r,o.length),S.selectionStart=i+e.length-(t?t.length:0),S.selectionEnd=S.selectionStart,S.scrollTop=n,S.focus(),st()},mt.getRangeHelper=function(){return $},mt.sourceEditorCaret=function(e){return S.focus(),e?(S.selectionStart=e.start,S.selectionEnd=e.end,this):{start:S.selectionStart,end:S.selectionEnd}},mt.val=function(e,t){return ae(e)?(mt.inSourceMode()?mt.setSourceEditorValue(e):(!1!==t&&"toHtml"in n&&(e=n.toHtml(e)),mt.setWysiwygEditorValue(e)),mt):mt.inSourceMode()?mt.getSourceEditorValue(!1):mt.getWysiwygEditorValue(t)},mt.insert=function(e,t,o,i,r){if(mt.inSourceMode())return mt.sourceEditorInsertText(e,t),mt;if(t){var a=$.selectedHtml();!1!==o&&"fragmentToSource"in n&&(a=n.fragmentToSource(a,k,Q)),e+=a+t}return!1!==o&&"fragmentToHtml"in n&&(e=n.fragmentToHtml(e,Q)),!1!==o&&!0===r&&(e=e.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),mt.wysiwygEditorInsertHtml(e),mt},mt.getWysiwygEditorValue=function(e){for(var t,o=l("div",{},k),i=v.childNodes,r=0;r<i.length;r++)f(o,i[r].cloneNode(!0));return f(v,o),U(o),d(o),t=o.innerHTML,!1!==e&&n.hasOwnProperty("toSource")&&(t=n.toSource(t,k)),t},mt.getBody=function(){return v},mt.getContentAreaContainer=function(){return s},mt.getSourceEditorValue=function(e){var t=S.value;return!1!==e&&"toHtml"in n&&(t=n.toHtml(t)),t},mt.setWysiwygEditorValue=function(e){e||(e="<p>"+(He?"":"<br />")+"</p>"),v.innerHTML=e,De(),nt(),st(),pt()},mt.setSourceEditorValue=function(e){S.value=e,st()},mt.updateOriginal=function(){gt.value=mt.val()},De=function(){Ct.emoticonsEnabled&&oe(v,wt,Ct.emoticonsCompat)},mt.inSourceMode=function(){return M(a,"sourceMode")},mt.sourceMode=function(e){var t=mt.inSourceMode();return"boolean"!=typeof e?t:((t&&!e||!t&&e)&&mt.toggleSourceMode(),mt)},mt.toggleSourceMode=function(){var e=mt.inSourceMode();!xe&&e||(e||($.saveRange(),$.clear()),mt.blur(),e?mt.setWysiwygEditorValue(mt.getSourceEditorValue()):mt.setSourceEditorValue(mt.getWysiwygEditorValue()),O=null,x(S),x(s),H(a,"wysiwygMode",e),H(a,"sourceMode",!e),Ze(),et())},tt=function(){return S.focus(),S.value.substring(S.selectionStart,S.selectionEnd)},Me=function(e,t){mt.inSourceMode()?t.txtExec&&(Array.isArray(t.txtExec)?mt.sourceEditorInsertText.apply(mt,t.txtExec):t.txtExec.call(mt,e,tt())):t.exec&&(ce(t.exec)?t.exec.call(mt,e):mt.execCommand(t.exec,t.hasOwnProperty("execParam")?t.execParam:null))},_e=function(){He&&(O=$.selectedRange())},mt.execCommand=function(e,t){var n=!1,o=mt.commands[e];if(mt.focus(),!u($.parentNode(),"code")){try{n=k.execCommand(e,!1,t)}catch(e){}!n&&o&&o.errorMessage&&alert(mt._(o.errorMessage)),et()}},ot=function(){function e(){if($&&!$.compare(Z)){if((Z=$.cloneSelected())&&Z.collapsed){var e=Z.startContainer,t=Z.startOffset;for(t&&e.nodeType!==fe&&(e=e.childNodes[t]);e&&e.parentNode!==v;)e=e.parentNode;e&&j(e,!0)&&($.saveRange(),ie(v,k),$.restoreRange())}_(a,"selectionchanged")}se=!1}se||(se=!0,"onselectionchange"in k?e():setTimeout(e,100))},it=function(){var e,t=$.parentNode();Q!==t&&(e=Q,Q=t,G=$.getFirstBlockParent(t),_(a,"nodechanged",{oldNode:e,newNode:Q}))},mt.currentNode=function(){return Q},mt.currentBlockNode=function(){return G},et=function(){var e,t,n=k,o=mt.sourceMode();if(mt.readOnly())r(p(c,"active"),function(e,t){R(t,"active")});else{o||(t=$.parentNode(),e=$.getFirstBlockParent(t));for(var i=0;i<yt.length;i++){var a=0,l=xt[yt[i].name],s=yt[i].state,u=o&&!l._sceTxtMode||!o&&!l._sceWysiwygMode;if(ae(s)){if(!o)try{(a=n.queryCommandEnabled(s)?0:-1)>-1&&(a=n.queryCommandState(s)?1:0)}catch(e){}}else u||(a=s.call(mt,t,e));H(l,"disabled",u||a<0),H(l,"active",a>0)}ke&&ke.update&&ke.update(o,t,e)}},Ye=function(e){if(!e.defaultPrevented&&(mt.closeDropDown(),13===e.which)&&!E(G,"li,ul,ol")&&V(G)){O=null;var t=l("br",{},k);if($.insertNode(t),!Fe){var n=t.parentNode,o=n.lastChild;o&&o.nodeType===fe&&""===o.nodeValue&&(d(o),o=n.lastChild),!j(n,!0)&&o===t&&j(t.previousSibling)&&$.insertHTML("<br>")}e.preventDefault()}},nt=function(){I(v,function(e){if(e.nodeType===de&&!/inline/.test(w(e,"display"))&&!E(e,".sceditor-nlf")&&V(e)){var t=l("p",{},k);return t.className="sceditor-nlf",t.innerHTML=Fe?"":"<br />",f(v,t),!1}if(3===e.nodeType&&!/^\s*$/.test(e.nodeValue)||E(e,"br"))return!1})},Ke=function(){mt.val(gt.value)},Xe=function(){mt.closeDropDown(),O=null},mt._=function(){var e=arguments;return q&&q[e[0]]&&(e[0]=q[e[0]]),e[0].replace(/\{(\d+)\}/g,function(t,n){return void 0!==e[n-0+1]?e[n-0+1]:"{"+n+"}"})},Ge=function(e){K&&K.call(e.type+"Event",e,mt);var t=(e.target===S?"scesrc":"scewys")+e.type;ht[t]&&ht[t].forEach(function(t){t.call(mt,e)})},mt.bind=function(e,t,n,o){for(var i=(e=e.split(" ")).length;i--;)if(ce(t)){var r="scewys"+e[i],a="scesrc"+e[i];n||(ht[r]=ht[r]||[],ht[r].push(t)),o||(ht[a]=ht[a]||[],ht[a].push(t)),"valuechanged"===e[i]&&(st.hasHandler=!0)}return mt},mt.unbind=function(e,t,n,o){for(var r=(e=e.split(" ")).length;r--;)ce(t)&&(n||i(ht["scewys"+e[r]]||[],t),o||i(ht["scesrc"+e[r]]||[],t));return mt},mt.blur=function(e,t,n){return ce(e)?mt.bind("blur",e,t,n):mt.sourceMode()?S.blur():v.blur(),mt},mt.focus=function(e,t,n){if(ce(e))mt.bind("focus",e,t,n);else if(mt.inSourceMode())S.focus();else{if(p(k,":focus").length)return;var o,i=$.selectedRange();Z||rt(),!Fe&&i&&1===i.endOffset&&i.collapsed&&(o=i.endContainer)&&1===o.childNodes.length&&E(o.firstChild,"br")&&(i.setStartBefore(o.firstChild),i.collapse(!0),$.selectRange(i)),s.contentWindow.focus(),v.focus(),O&&($.selectRange(O),O=null)}return et(),mt},mt.keyDown=function(e,t,n){return mt.bind("keydown",e,t,n)},mt.keyPress=function(e,t,n){return mt.bind("keypress",e,t,n)},mt.keyUp=function(e,t,n){return mt.bind("keyup",e,t,n)},mt.nodeChanged=function(e){return mt.bind("nodechanged",e,!1,!0)},mt.selectionChanged=function(e){return mt.bind("selectionchanged",e,!1,!0)},mt.valueChanged=function(e,t,n){return mt.bind("valuechanged",e,t,n)},at=function(e){var t=0,n=mt.emoticonsCache,o=String.fromCharCode(e.which);u(G,"code")||(n||(n=[],r(wt,function(e,o){n[t++]=[e,o]}),n.sort(function(e,t){return e[0].length-t[0].length}),mt.emoticonsCache=n,mt.longestEmoticonCode=n[n.length-1][0].length),$.replaceKeyword(mt.emoticonsCache,!0,!0,mt.longestEmoticonCode,Ct.emoticonsCompat,o)&&(Ct.emoticonsCompat&&/^\s$/.test(o)||e.preventDefault()))},lt=function(){ne(G,$)},mt.emoticons=function(e){return e||!1===e?(Ct.emoticonsEnabled=e,e?(m(v,"keypress",at),mt.sourceMode()||($.saveRange(),De(),st(!1),$.restoreRange())):(r(p(v,"img[data-sceditor-emoticon]"),function(e,t){var n=C(t,"sceditor-emoticon"),o=k.createTextNode(n);t.parentNode.replaceChild(o,t)}),g(v,"keypress",at),st()),mt):Ct.emoticonsEnabled},mt.css=function(e){return me||(me=l("style",{id:"inline"},k),f(k.head,me)),ae(e)?(me.styleSheet?me.styleSheet.cssText=e:me.innerHTML=e,mt):me.styleSheet?me.styleSheet.cssText:me.innerHTML},Ue=function(e){var t=[],n={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},o={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},i={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},r=e.which,a=o[r]||String.fromCharCode(r).toLowerCase();(e.ctrlKey||e.metaKey)&&t.push("ctrl"),e.altKey&&t.push("alt"),e.shiftKey&&(t.push("shift"),i[r]?a=i[r]:n[a]&&(a=n[a])),a&&(r<16||r>18)&&t.push(a),t=t.join("+"),bt[t]&&!1===bt[t].call(mt)&&(e.stopPropagation(),e.preventDefault())},mt.addShortcut=function(e,t){return e=e.toLowerCase(),ae(t)?bt[e]=function(){return Me(xt[t],mt.commands[t]),!1}:bt[e]=t,mt},mt.removeShortcut=function(e){return delete bt[e.toLowerCase()],mt},$e=function(e){var t,n,o;if(!Ct.disableBlockRemove&&8===e.which&&(n=$.selectedRange())&&(t=n.startContainer,0===n.startOffset&&(o=ct()))){for(;t!==o;){for(;t.previousSibling;)if((t=t.previousSibling).nodeType!==fe||t.nodeValue)return;if(!(t=t.parentNode))return}o&&!E(o,"body")&&(mt.clearBlockFormatting(o),e.preventDefault())}},ct=function(){for(var e=G;!V(e)||j(e,!0);)if(!(e=e.parentNode)||E(e,"body"))return;return e},mt.clearBlockFormatting=function(e){return!(e=e||ct())||E(e,"body")?mt:($.saveRange(),e.className="",O=null,h(e,"style",""),E(e,"p,div,td")||P(e,"p"),$.restoreRange(),mt)},st=function(e){if(K&&(K.hasHandler("valuechangedEvent")||st.hasHandler)){var t,n=mt.sourceMode(),o=!n&&$.hasSelection();B=!1,e=!1!==e&&!k.getElementById("sceditor-start-marker"),L&&(clearTimeout(L),L=!1),o&&e&&$.saveRange(),(t=n?S.value:v.innerHTML)!==st.lastVal&&(st.lastVal=t,_(a,"valuechanged",{rawValue:n?mt.val():t})),o&&e&&$.removeMarkers()}},ut=function(){L&&st()},dt=function(e){var t=e.which,n=dt.lastChar,o=13===n||32===n,i=8===n||46===n;dt.lastChar=t,B||(13===t||32===t?o?dt.triggerNext=!0:st():8===t||46===t?i?dt.triggerNext=!0:st():dt.triggerNext&&(st(),dt.triggerNext=!1),clearTimeout(L),L=setTimeout(function(){B||st()},1500))},Qe=function(e){(B=/start/i.test(e.type))||st()},ft=function(){mt.updateOriginal()},Te()}e=e&&e.hasOwnProperty("default")?e.default:e;var ae=t.bind(null,"string"),le=t.bind(null,"undefined"),ce=t.bind(null,"function"),se=t.bind(null,"number"),ue={},de=1,fe=3,pe=!0,me="|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|",ge={toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:"#000000,#44B8FF,#1E92F7,#0074D9,#005DC2,#00369B,#b3d5f4|#444444,#C3FFFF,#9DF9FF,#7FDBFF,#68C4E8,#419DC1,#d9f4ff|#666666,#72FF84,#4CEA5E,#2ECC40,#17B529,#008E02,#c0f0c6|#888888,#FFFF44,#FFFA1E,#FFDC00,#E8C500,#C19E00,#fff5b3|#aaaaaa,#FFC95F,#FFA339,#FF851B,#E86E04,#C14700,#ffdbbb|#cccccc,#FF857A,#FF5F54,#FF4136,#E82A1F,#C10300,#ffc6c3|#eeeeee,#FF56FF,#FF30DC,#F012BE,#D900A7,#B20080,#fbb8ec|#ffffff,#F551FF,#CF2BE7,#B10DC9,#9A00B2,#9A00B2,#e8b6ef",locale:h(document.documentElement,"lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}},he=navigator.userAgent,ve=function(){var e=3,t=document,n=t.createElement("div"),o=n.getElementsByTagName("i");do{n.innerHTML="\x3c!--[if gt IE "+ ++e+"]><i></i><![endif]--\x3e"}while(o[0]);return t.documentMode&&t.all&&window.atob&&(e=10),4===e&&t.documentMode&&(e=11),e>4?e:void 0}(),ye="-ms-ime-align"in document.documentElement.style,be=/iPhone|iPod|iPad| wosbrowser\//i.test(he),xe=function(){var e,t,n=document.createElement("div");return n.contentEditable=!0,"contentEditable"in document.documentElement&&"true"===n.contentEditable&&(t=/Opera Mobi|Opera Mini/i.test(he),/Android/i.test(he)&&(t=!0,/Safari/.test(he)&&(t=!(e=/Safari\/(\d+)/.exec(he))||!e[1]||e[1]<534)),/ Silk\//i.test(he)&&(t=!(e=/AppleWebKit\/(\d+)/.exec(he))||!e[1]||e[1]<534),be&&(t=/OS [0-4](_\d)+ like Mac/i.test(he)),/Firefox/i.test(he)&&(t=!1),/OneBrowser/i.test(he)&&(t=!1),"UCWEB"===navigator.vendor&&(t=!1),ve<=9&&(t=!0),!t)}(),we=/^(https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(\/\/)|data:image\/(png|bmp|gif|p?jpe?g);/i,Ce={html:'<!DOCTYPE html><html{attrs}><head><style>.ie * {min-height: auto !important} .ie table td {height:15px} @supports (-ms-ime-align:auto) { * { min-height: auto !important; } }</style><meta http-equiv="Content-Type" content="text/html;charset={charset}" /><link rel="stylesheet" type="text/css" href="{style}" /></head><body contenteditable="true" {spellcheck}><p></p></body></html>',toolbarButton:'<a class="sceditor-button sceditor-button-{name}" data-sceditor-command="{name}" unselectable="on"><div unselectable="on">{dispName}</div></a>',emoticon:'<img src="{url}" data-sceditor-emoticon="{key}" alt="{key}" title="{tooltip}" />',fontOpt:'<a class="sceditor-font-option" href="#" data-font="{font}"><font face="{font}">{font}</font></a>',sizeOpt:'<a class="sceditor-fontsize-option" data-size="{size}" href="#"><font size="{size}">{size}</font></a>',pastetext:'<div><label for="txt">{label}</label> <textarea cols="20" rows="7" id="txt"></textarea></div><div><input type="button" class="button" value="{insert}" /></div>',table:'<div><label for="rows">{rows}</label><input type="text" id="rows" value="2" /></div><div><label for="cols">{cols}</label><input type="text" id="cols" value="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',image:'<div><label for="link">{url}</label> <input type="text" id="image" placeholder="https://" /></div><div><label for="width">{width}</label> <input type="text" id="width" size="2" /></div><div><label for="height">{height}</label> <input type="text" id="height" size="2" /></div><div><input type="button" class="button" value="{insert}" /></div>',email:'<div><label for="email">{label}</label> <input type="text" id="email" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{insert}" /></div>',link:'<div><label for="link">{url}</label> <input type="text" id="link" placeholder="https://" /></div><div><label for="des">{desc}</label> <input type="text" id="des" /></div><div><input type="button" class="button" value="{ins}" /></div>',youtubeMenu:'<div><label for="link">{label}</label> <input type="text" id="link" placeholder="https://" /></div><div><input type="button" class="button" value="{insert}" /></div>',youtube:'<iframe width="560" height="315" frameborder="0" allowfullscreensrc="https://www.youtube.com/embed/{id}?wmode=opaque&start={time}" data-youtube-id="{id}"></iframe>'},Ee=function(e,t,n){var o=Ce[e];return Object.keys(t).forEach(function(e){o=o.replace(new RegExp(G("{"+e+"}"),"g"),t[e])}),n&&(o=L(o)),o},ke=ve&&ve<11,Se={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(e,t,n){var o=l("div");m(o,"click","a",function(t){n(C(this,"font")),e.closeDropDown(!0),t.preventDefault()}),e.opts.fonts.split(",").forEach(function(e){f(o,Ee("fontOpt",{font:e},!0))}),e.createDropDown(t,"font-picker",o)},exec:function(e){var t=this;Se.font._dropDown(t,e,function(e){t.execCommand("fontname",e)})},tooltip:"Font Name"},size:{_dropDown:function(e,t,n){var o=l("div");m(o,"click","a",function(t){n(C(this,"size")),e.closeDropDown(!0),t.preventDefault()});for(var i=1;i<=7;i++)f(o,Ee("sizeOpt",{size:i},!0));e.createDropDown(t,"fontsize-picker",o)},exec:function(e){var t=this;Se.size._dropDown(t,e,function(e){t.execCommand("fontsize",e)})},tooltip:"Font Size"},color:{_dropDown:function(e,t,n){var o=l("div"),i="",r=Se.color;r._htmlCache||(e.opts.colors.split("|").forEach(function(e){i+='<div class="sceditor-color-column">',e.split(",").forEach(function(e){i+='<a href="#" class="sceditor-color-option" style="background-color: '+e+'" data-color="'+e+'"></a>'}),i+="</div>"}),r._htmlCache=i),f(o,L(r._htmlCache)),m(o,"click","a",function(t){n(C(this,"color")),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"color-picker",o)},exec:function(e){var t=this;Se.color._dropDown(t,e,function(e){t.execCommand("forecolor",e)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(e){var t,n=l("div"),o=this;f(n,Ee("pastetext",{label:o._("Paste your text inside the following box:"),insert:o._("Insert")},!0)),m(n,"click",".button",function(e){(t=p(n,"#txt")[0].value)&&o.wysiwygEditorInsertText(t),o.closeDropDown(!0),e.preventDefault()}),o.createDropDown(e,"pastetext",n)},tooltip:"Paste Text"},bulletlist:{exec:function(){Z(this),this.execCommand("insertunorderedlist")},tooltip:"Bullet list"},orderedlist:{exec:function(){Z(this),this.execCommand("insertorderedlist")},tooltip:"Numbered list"},indent:{state:function(e,t){var n,o,i,r=c(t,"ul,ol,menu");return r.length>1&&r[0].children.length>1?0:E(t,"ul,ol,menu")&&(n=this.getRangeHelper().selectedRange(),o=n.startContainer.parentNode,i=n.endContainer.parentNode,o!==o.parentNode.firstElementChild||E(i,"li")&&i!==i.parentNode.lastElementChild)?0:-1},exec:function(){var e=this,t=e.getRangeHelper().getFirstBlockParent();e.focus(),c(t,"ul,ol,menu")&&e.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(e,t){return u(t,"ul,ol,menu")>0?0:-1},exec:function(){c(this.getRangeHelper().getFirstBlockParent(),"ul,ol,menu")&&this.execCommand("outdent")},tooltip:"Remove one indent"},table:{exec:function(e){var t=this,n=l("div");f(n,Ee("table",{rows:t._("Rows:"),cols:t._("Cols:"),insert:t._("Insert")},!0)),m(n,"click",".button",function(e){var o=Number(p(n,"#rows")[0].value),i=Number(p(n,"#cols")[0].value),r="<table>";o>0&&i>0&&(r+=Array(o+1).join("<tr>"+Array(i+1).join("<td>"+(ke?"":"<br />")+"</td>")+"</tr>"),r+="</table>",t.wysiwygEditorInsertHtml(r),t.closeDropDown(!0),e.preventDefault())}),t.createDropDown(e,"inserttable",n)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{exec:function(){this.wysiwygEditorInsertHtml("<code>",(ke?"":"<br />")+"</code>")},tooltip:"Code"},image:{_dropDown:function(e,t,n,o){var i=l("div");f(i,Ee("image",{url:e._("URL:"),width:e._("Width (optional):"),height:e._("Height (optional):"),insert:e._("Insert")},!0));var r=p(i,"#image")[0];r.value=n,m(i,"click",".button",function(t){r.value&&o(r.value,p(i,"#width")[0].value,p(i,"#height")[0].value),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertimage",i)},exec:function(e){var t=this;Se.image._dropDown(t,e,"",function(e,n,o){var i="";n&&(i+=' width="'+n+'"'),o&&(i+=' height="'+o+'"'),t.wysiwygEditorInsertHtml("<img"+i+' src="'+e+'" />')})},tooltip:"Insert an image"},email:{_dropDown:function(e,t,n){var o=l("div");f(o,Ee("email",{label:e._("E-mail:"),desc:e._("Description (optional):"),insert:e._("Insert")},!0)),m(o,"click",".button",function(t){var i=p(o,"#email")[0].value;i&&n(i,p(o,"#des")[0].value),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertemail",o)},exec:function(e){var t=this;Se.email._dropDown(t,e,function(e,n){t.focus(),!t.getRangeHelper().selectedHtml()||n?t.wysiwygEditorInsertHtml('<a href="mailto:'+e+'">'+(n||e)+"</a>"):t.execCommand("createlink","mailto:"+e)})},tooltip:"Insert an email"},link:{_dropDown:function(e,t,n){function o(t){r.value&&n(r.value,p(i,"#des")[0].value),e.closeDropDown(!0),t.preventDefault()}var i=l("div");f(i,Ee("link",{url:e._("URL:"),desc:e._("Description (optional):"),ins:e._("Insert")},!0));var r=p(i,"#link")[0];m(i,"click",".button",o),m(i,"keypress",function(e){13===e.which&&r.value&&o(e)},pe),e.createDropDown(t,"insertlink",i)},exec:function(e){var t=this;Se.link._dropDown(t,e,function(e,n){t.focus(),!t.getRangeHelper().selectedHtml()||n?(n=n||e,t.wysiwygEditorInsertHtml('<a href="'+e+'">'+n+"</a>")):t.execCommand("createlink",e)})},tooltip:"Insert a link"},unlink:{state:function(){return u(this.currentNode(),"a")?0:-1},exec:function(){var e=u(this.currentNode(),"a");if(e){for(;e.firstChild;)T(e.firstChild,e);d(e)}},tooltip:"Unlink"},quote:{exec:function(e,t,n){var o="<blockquote>",i="</blockquote>";t?(o=o+(n=n?"<cite>"+n+"</cite>":"")+t+i,i=null):""===this.getRangeHelper().selectedHtml()&&(i=(ke?"":"<br />")+i),this.wysiwygEditorInsertHtml(o,i)},tooltip:"Insert a Quote"},emoticon:{exec:function(e){var t=this,n=function(i){var a,c=t.opts.emoticonsCompat,s=t.getRangeHelper(),u=c&&" "!==s.getOuterText(!0,1)?" ":"",d=c&&" "!==s.getOuterText(!1,1)?" ":"",p=l("div"),g=l("div"),v=0,y=o({},t.opts.emoticons.dropdown,i?t.opts.emoticons.more:{});return f(p,g),v=Math.sqrt(Object.keys(y).length),m(p,"click","img",function(e){t.insert(u+h(this,"alt")+d,null,!1).closeDropDown(!0),e.preventDefault()}),r(y,function(e,t){f(g,l("img",{src:t.url||t,alt:e,title:t.tooltip||e})),g.children.length>=v&&(g=l("div"),f(p,g))}),!i&&t.opts.emoticons.more&&(f(a=l("a",{className:"sceditor-more"}),document.createTextNode(t._("More"))),m(a,"click",function(o){t.createDropDown(e,"more-emoticons",n(!0)),o.preventDefault()}),f(p,a)),p};t.createDropDown(e,"emoticons",n(!1))},txtExec:function(e){Se.emoticon.exec.call(this,e)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(e,t,n){var o=l("div");f(o,Ee("youtubeMenu",{label:e._("Video URL:"),insert:e._("Insert")},!0)),m(o,"click",".button",function(t){var i=p(o,"#link")[0].value,a=i.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),l=i.match(/[&|?](?:star)?t=((\d+[hms]?){1,3})/),c=0;l&&r(l[1].split(/[hms]/),function(e,t){""!==t&&(c=60*c+Number(t))}),a&&/^[a-zA-Z0-9_\-]{11}$/.test(a[1])&&n(a[1],c),e.closeDropDown(!0),t.preventDefault()}),e.createDropDown(t,"insertlink",o)},exec:function(e){var t=this;Se.youtube._dropDown(t,e,function(e,n){t.wysiwygEditorInsertHtml(Ee("youtube",{id:e,time:n}))})},tooltip:"Insert a YouTube video"},date:{_date:function(e){var t=new Date,n=t.getYear(),o=t.getMonth()+1,i=t.getDate();return n<2e3&&(n=1900+n),o<10&&(o="0"+o),i<10&&(i="0"+i),e.opts.dateFormat.replace(/year/i,n).replace(/month/i,o).replace(/day/i,i)},exec:function(){this.insertText(Se.date._date(this))},txtExec:function(){this.insertText(Se.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var e=new Date,t=e.getHours(),n=e.getMinutes(),o=e.getSeconds();return t<10&&(t="0"+t),n<10&&(n="0"+n),o<10&&(o="0"+o),t+":"+n+":"+o},exec:function(){this.insertText(Se.time._time())},txtExec:function(){this.insertText(Se.time._time())},tooltip:"Insert current time"},ltr:{state:function(e,t){return t&&"ltr"===t.style.direction},exec:function(){var e=this,t=e.getRangeHelper(),n=t.getFirstBlockParent();e.focus(),(n&&!E(n,"body")||(e.execCommand("formatBlock","p"),(n=t.getFirstBlockParent())&&!E(n,"body")))&&w(n,"direction","ltr"===w(n,"direction")?"":"ltr")},tooltip:"Left-to-Right"},rtl:{state:function(e,t){return t&&"rtl"===t.style.direction},exec:function(){var e=this,t=e.getRangeHelper(),n=t.getFirstBlockParent();e.focus(),(n&&!E(n,"body")||(e.execCommand("formatBlock","p"),(n=t.getFirstBlockParent())&&!E(n,"body")))&&w(n,"direction","rtl"===w(n,"direction")?"":"rtl")},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}},Te={};ee.plugins=Te;var De=ve&&ve<11,Me=function(e,t,n){var o,i,r,a,l,c="",s=e.startContainer,u=e.startOffset;for(s&&3!==s.nodeType&&(s=s.childNodes[u],u=0),r=a=u;n>c.length&&s&&3===s.nodeType;)o=s.nodeValue,i=n-c.length,l&&(a=o.length,r=0),l=s,t?(u=r=Math.max(a-i,0),c=o.substr(r,a-r)+c,s=l.previousSibling):(u=r+(a=Math.min(i,o.length)),c+=o.substr(r,a),s=l.nextSibling);return{node:l||s,offset:u,text:c}},Ne=window,Re=document,He=ve,Fe=He&&He<11,ze=/^image\/(p?jpe?g|gif|png|bmp)$/i;re.locale={},re.formats={},re.icons={},re.command={get:function(e){return Se[e]||null},set:function(e,t){return!(!e||!t)&&(t=o(Se[e]||{},t),t.remove=function(){re.command.remove(e)},Se[e]=t,this)},remove:function(e){return Se[e]&&delete Se[e],this}},window.sceditor={command:re.command,commands:Se,defaultOptions:ge,ie:ve,ios:be,isWysiwygSupported:xe,regexEscape:G,escapeEntities:J,escapeUriScheme:function(e){var t,n=/^[^\/]*:/i,o=window.location;return e&&n.test(e)&&!we.test(e)?((t=o.pathname.split("/")).pop(),o.protocol+"//"+o.host+t.join("/")+"/"+e):e},dom:{css:w,attr:h,removeAttr:v,is:E,closest:u,width:F,height:z,traverse:B,rTraverse:I,parseHTML:L,hasStyling:V,convertElement:P,blockLevelList:me,canHaveChildren:W,isInline:j,copyCSS:q,fixNesting:U,findCommonAncestor:function(e,t){for(;e=e.parentNode;)if(k(e,t))return e},getSibling:$,removeWhiteSpace:Y,extractContents:K,getOffset:X,getStyle:Q,hasStyle:function(e,t,n){var o=Q(e,t);return!!o&&(!n||o===n||Array.isArray(n)&&n.indexOf(o)>-1)}},locale:re.locale,icons:re.icons,utils:{each:r,isEmptyObject:n,extend:o},plugins:ee.plugins,formats:re.formats,create:function(e,t){t=t||{},s(e,".sceditor-container")||(t.runWithoutWysiwygSupport||xe)&&new re(e,t)},instance:function(e){return e._sceditor}},e.sceditor=window.sceditor,e.fn.sceditor=function(t){var n,o=[];return this.each(function(){n=this._sceditor,"state"===t?o.push(!!n):"instance"===t?o.push(n):n||e.sceditor.create(this,t)}),o.length?1===o.length?o[0]:o:this}}(jQuery),function(e){"use strict";function t(){function o(e,t){v[e]&&v[e].forEach(function(n){n.tags[e]?u(n.tags[e],function(e,o){t.getAttributeNode&&(!(e=t.getAttributeNode(e))||o&&o.indexOf(e.value)<0||n.conv.call(h,t))}):n.conv&&n.conv.call(h,t)})}function r(e){n.traverse(e,function(e){var t=e.nodeName.toLowerCase();o("*",e),o(t,e)},!0)}function l(e,o){var i,r=e.childNodes,c=e.nodeName.toLowerCase(),s=e.nodeValue,u=r.length,d=t.allowedEmptyTags||[];if(o&&"br"===c)return!0;if(a(e,".sceditor-ignore"))return!0;if(d.indexOf(c)>-1||"td"===c||!n.canHaveChildren(e))return!1;if(s&&/\S|\u00A0/.test(s))return!1;for(;u--;)if(!l(r[u],o&&!e.previousSibling&&!e.nextSibling))return!1;return!e.getBoundingClientRect||!e.className&&!e.hasAttributes("style")||(!(i=e.getBoundingClientRect()).width||!i.height)}function c(e){n.traverse(e,function(o){var i,r=o.nodeName.toLowerCase(),a=o.parentNode,c=o.nodeType,s=!n.isInline(o),u=o.previousSibling,d=o.nextSibling,f=a===e,p=!u&&!d,m="iframe"!==r&&l(o,f&&p&&"br"!==r),g=o.ownerDocument,h=t.allowedTags,v=t.disallowedTags;if(3!==c&&(4===c?r="!cdata":"!"!==r&&8!==c||(r="!comment"),m?i=!0:h&&h.length?i=h.indexOf(r)<0:v&&v.length&&(i=v.indexOf(r)>-1),i)){if(!m){for(s&&u&&n.isInline(u)&&a.insertBefore(g.createTextNode(" "),o);o.firstChild;)a.insertBefore(o.firstChild,d);s&&d&&n.isInline(d)&&a.insertBefore(g.createTextNode(" "),d)}a.removeChild(o)}},!0)}function f(e,t){var n={};return e&&s(n,e),t?(u(t,function(e,t){Array.isArray(t)?n[e]=(n[e]||[]).concat(t):n[e]||(n[e]=null)}),n):n}function m(e){n.removeWhiteSpace(e);for(var t,o,i=e.firstChild;i;)o=i.nextSibling,n.isInline(i)&&!a(i,".sceditor-ignore")?(t||(t=e.ownerDocument.createElement("p"),i.parentNode.insertBefore(t,i)),t.appendChild(i)):t=null,i=o}function g(e){var o,i,r,a,l,c,s=t.allowedAttribs,u=s&&!d(s),p=t.disallowedAttribs,m=p&&!d(p);y={},n.traverse(e,function(e){if(e.attributes&&(o=e.nodeName.toLowerCase(),a=e.attributes.length))for(y[o]||(y[o]=u?f(s["*"],s[o]):f(p["*"],p[o]));a--;)i=e.attributes[a],r=i.name,l=y[o][r],c=!1,u?c=null!==l&&(!Array.isArray(l)||l.indexOf(i.value)<0):m&&(c=null===l||Array.isArray(l)&&l.indexOf(i.value)>-1),c&&e.removeAttribute(r)})}var h=this,v={},y={};h.init=function(){d(t.converters||{})||u(t.converters,function(e,t){u(t.tags,function(e){v[e]||(v[e]=[]),v[e].push(t)})}),this.commands=s(!0,{},p,this.commands)},h.toSource=function(t,n){var o,a=n.createElement("div");return a.innerHTML=t,i(a,"visibility","hidden"),n.body.appendChild(a),r(a),c(a),g(a),m(a),o=(new e.XHTMLSerializer).serialize(a,!0),n.body.removeChild(a),o},h.fragmentToSource=h.toSource}var n=e.dom,o=e.utils,i=n.css,r=n.attr,a=n.is,l=n.removeAttr,c=n.convertElement,s=o.extend,u=o.each,d=o.isEmptyObject,f=e.command.get,p={bold:{txtExec:["<strong>","</strong>"]},italic:{txtExec:["<em>","</em>"]},underline:{txtExec:['<span style="text-decoration:underline;">',"</span>"]},strike:{txtExec:['<span style="text-decoration:line-through;">',"</span>"]},subscript:{txtExec:["<sub>","</sub>"]},superscript:{txtExec:["<sup>","</sup>"]},left:{txtExec:['<div style="text-align:left;">',"</div>"]},center:{txtExec:['<div style="text-align:center;">',"</div>"]},right:{txtExec:['<div style="text-align:right;">',"</div>"]},justify:{txtExec:['<div style="text-align:justify;">',"</div>"]},font:{txtExec:function(e){var t=this;f("font")._dropDown(t,e,function(e){t.insertText('<span style="font-family:'+e+';">',"</span>")})}},size:{txtExec:function(e){var t=this;f("size")._dropDown(t,e,function(e){t.insertText('<span style="font-size:'+e+';">',"</span>")})}},color:{txtExec:function(e){var t=this;f("color")._dropDown(t,e,function(e){t.insertText('<span style="color:'+e+';">',"</span>")})}},bulletlist:{txtExec:["<ul><li>","</li></ul>"]},orderedlist:{txtExec:["<ol><li>","</li></ol>"]},table:{txtExec:["<table><tr><td>","</td></tr></table>"]},horizontalrule:{txtExec:["<hr />"]},code:{txtExec:["<code>","</code>"]},image:{txtExec:function(e,t){var n=this;f("image")._dropDown(n,e,t,function(e,t,o){var i="";t&&(i+=' width="'+t+'"'),o&&(i+=' height="'+o+'"'),n.insertText("<img"+i+' src="'+e+'" />')})}},email:{txtExec:function(e,t){var n=this;f("email")._dropDown(n,e,function(e,o){n.insertText('<a href="mailto:'+e+'">'+(o||t||e)+"</a>")})}},link:{txtExec:function(e,t){var n=this;f("link")._dropDown(n,e,function(e,o){n.insertText('<a href="'+e+'">'+(o||t||e)+"</a>")})}},quote:{txtExec:["<blockquote>","</blockquote>"]},youtube:{txtExec:function(e){var t=this;f("youtube")._dropDown(t,e,function(e,n){t.insertText('<iframe width="560" height="315" src="https://www.youtube.com/embed/{id}?wmode=opaque&start='+n+'" data-youtube-id="'+e+'" frameborder="0" allowfullscreen></iframe>')})}},rtl:{txtExec:['<div stlye="direction:rtl;">',"</div>"]},ltr:{txtExec:['<div stlye="direction:ltr;">',"</div>"]}};e.XHTMLSerializer=function(){function e(e){var t={"&":"&","<":"<",">":">",'"':"""," ":" "};return e?e.replace(/[&<>"\xa0]/g,function(e){return t[e]||e}):""}function t(e){return e.replace(/[\r\n]/," ").replace(/[^\S|\u00A0]+/g," ")}function o(e,t){switch(e.nodeType){case 1:"!"===e.nodeName.toLowerCase()?s(e):l(e,t);break;case 3:u(e,t);break;case 4:c(e);break;case 8:s(e);break;case 9:case 11:r(e)}}function r(e){for(var t=e.firstChild;t;)o(t),t=t.nextSibling}function l(t,r){var l,c,s,u=t.nodeName.toLowerCase(),p="iframe"===u,m=t.attributes.length,h=t.firstChild,v=r||/pre(?:\-wrap)?$/i.test(i(t,"whiteSpace")),y=!t.firstChild&&!n.canHaveChildren(t)&&!p;if(!a(t,".sceditor-ignore")){for(d("<"+u,!r&&f(t));m--;)s=(c=t.attributes[m]).value,d(" "+c.name.toLowerCase()+'="'+e(s)+'"',!1);for(d(y?" />":">",!1),p||(l=h);l;)g++,o(l,v),l=l.nextSibling,g--;y||d("</"+u+">",!v&&!p&&f(t)&&h&&f(h))}}function c(t){d("<![CDATA["+e(t.nodeValue)+"]]>")}function s(t){d("\x3c!-- "+e(t.nodeValue)+" --\x3e")}function u(n,o){var i=n.nodeValue;o||(i=t(i)),i&&d(e(i),!o&&f(n))}function d(e,t){var n=g;if(!1!==t)for(m.length&&m.push("\n");n--;)m.push(p.indentStr);m.push(e)}function f(e){var t=e.previousSibling;return 1!==e.nodeType&&t?!n.isInline(t):!t&&!n.isInline(e.parentNode)||!n.isInline(e)}var p={indentStr:"\t"},m=[],g=0;this.serialize=function(e,t){if(m=[],t)for(e=e.firstChild;e;)o(e),e=e.nextSibling;else o(e);return m.join("")}},t.converters=[{tags:{"*":{width:null}},conv:function(e){i(e,"width",r(e,"width")),l(e,"width")}},{tags:{"*":{height:null}},conv:function(e){i(e,"height",r(e,"height")),l(e,"height")}},{tags:{li:{value:null}},conv:function(e){l(e,"value")}},{tags:{"*":{text:null}},conv:function(e){i(e,"color",r(e,"text")),l(e,"text")}},{tags:{"*":{color:null}},conv:function(e){i(e,"color",r(e,"color")),l(e,"color")}},{tags:{"*":{face:null}},conv:function(e){i(e,"fontFamily",r(e,"face")),l(e,"face")}},{tags:{"*":{align:null}},conv:function(e){i(e,"textAlign",r(e,"align")),l(e,"align")}},{tags:{"*":{border:null}},conv:function(e){i(e,"borderWidth",r(e,"border")),l(e,"border")}},{tags:{applet:{name:null},img:{name:null},layer:{name:null},map:{name:null},object:{name:null},param:{name:null}},conv:function(e){r(e,"id")||r(e,"id",r(e,"name")),l(e,"name")}},{tags:{"*":{vspace:null}},conv:function(e){i(e,"marginTop",r(e,"vspace")-0),i(e,"marginBottom",r(e,"vspace")-0),l(e,"vspace")}},{tags:{"*":{hspace:null}},conv:function(e){i(e,"marginLeft",r(e,"hspace")-0),i(e,"marginRight",r(e,"hspace")-0),l(e,"hspace")}},{tags:{hr:{noshade:null}},conv:function(e){i(e,"borderStyle","solid"),l(e,"noshade")}},{tags:{"*":{nowrap:null}},conv:function(e){i(e,"whiteSpace","nowrap"),l(e,"nowrap")}},{tags:{big:null},conv:function(e){i(c(e,"span"),"fontSize","larger")}},{tags:{small:null},conv:function(e){i(c(e,"span"),"fontSize","smaller")}},{tags:{b:null},conv:function(e){c(e,"strong")}},{tags:{u:null},conv:function(e){i(c(e,"span"),"textDecoration","underline")}},{tags:{s:null,strike:null},conv:function(e){i(c(e,"span"),"textDecoration","line-through")}},{tags:{dir:null},conv:function(e){c(e,"ul")}},{tags:{center:null},conv:function(e){i(c(e,"div"),"textAlign","center")}},{tags:{font:{size:null}},conv:function(e){i(e,"fontSize",i(e,"fontSize")),l(e,"size")}},{tags:{font:null},conv:function(e){c(e,"span")}},{tags:{"*":{type:["_moz"]}},conv:function(e){l(e,"type")}},{tags:{"*":{_moz_dirty:null}},conv:function(e){l(e,"_moz_dirty")}},{tags:{"*":{_moz_editor_bogus_node:null}},conv:function(e){e.parentNode.removeChild(e)}}],t.allowedAttribs={},t.disallowedAttribs={},t.allowedTags=[],t.disallowedTags=[],t.allowedEmptyTags=[],e.formats.xhtml=t}(sceditor); |
@@ -1,2 +0,3 @@ | ||
/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ | ||
!function(a){"use strict";a.sceditor.plugins.format=function(){var b,c,d=this,e={p:"Paragraph",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",address:"Address",pre:"Preformatted Text"};d.init=function(){var b=this.opts,d=b.paragraphformat;b.plugins&&b.plugins.indexOf("bbcode")>-1||(d&&(d.tags&&(e=d.tags),d.excludeTags&&a.each(d.excludeTags,function(a,b){delete e[b]})),this.commands.format||(this.commands.format={exec:c,txtExec:c,tooltip:"Format Paragraph"}),b.toolbar===a.sceditor.defaultOptions.toolbar&&(b.toolbar=b.toolbar.replace(",color,",",color,format,")))},b=function(a,b){a.sourceMode()?a.insert("<"+b+">","</"+b+">"):a.execCommand("formatblock","<"+b+">")},c=function(c){var d=this,f=a("<div />");a.each(e,function(c,e){a('<a class="sceditor-option" href="#">'+(e.name||e)+"</a>").click(function(){return d.closeDropDown(!0),e.exec?e.exec(d):b(d,c),!1}).appendTo(f)}),d.createDropDown(c,"format",f)}}}(jQuery); | ||
/* SCEditor v2.0.0-beta1 | (C) 2017, Sam Clarke | sceditor.com/license */ | ||
!function(e){"use strict";e.plugins.format=function(){var t,a,o={p:"Paragraph",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",address:"Address",pre:"Preformatted Text"};this.init=function(){var t=this.opts,n=t.paragraphformat;t.plugins&&t.plugins.indexOf("bbcode")>-1||(n&&(n.tags&&(o=n.tags),n.excludeTags&&n.excludeTags.forEach(function(e){delete o[e]})),this.commands.format||(this.commands.format={exec:a,txtExec:a,tooltip:"Format Paragraph"}),t.toolbar===e.defaultOptions.toolbar&&(t.toolbar=t.toolbar.replace(",color,",",color,format,")))},t=function(e,t){e.sourceMode()?e.insert("<"+t+">","</"+t+">"):e.execCommand("formatblock","<"+t+">")},a=function(a){var n=this,r=document.createElement("div");e.utils.each(o,function(e,a){var o=document.createElement("a");o.className="sceditor-option",o.textContent=a.name||a,o.addEventListener("click",function(o){n.closeDropDown(!0),a.exec?a.exec(n):t(n,e),o.preventDefault()}),r.appendChild(o)}),n.createDropDown(a,"format",r)}}}(sceditor); |
@@ -1,2 +0,3 @@ | ||
/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ | ||
!function(a){"use strict";a.sceditor.plugins.undo=function(){var a,b,c=this,d=0,e=50,f=[],g=[],h=!1,i=function(c){h=!0,b=c.value,a.sourceMode(c.sourceMode),a.val(c.value,!1),a.focus(),c.sourceMode?a.sourceEditorCaret(c.caret):a.getRangeHelper().restoreRange(),h=!1},j=function(a,b){var c,d,e,f,g=a.length,h=b.length,i=Math.max(g,h);for(c=0;c<i&&a.charAt(c)===b.charAt(c);c++);for(e=g<h?h-g:0,f=h<g?g-h:0,d=i-1;d>=0&&a.charAt(d-e)===b.charAt(d-f);d--);return d-c+1};c.init=function(){a=this,e=a.undoLimit||e,a.addShortcut("ctrl+z",c.undo),a.addShortcut("ctrl+shift+z",c.redo),a.addShortcut("ctrl+y",c.redo)},c.undo=function(){var b=g.pop(),c=a.val(null,!1);return b&&!f.length&&c===b.value&&(b=g.pop()),b&&(f.length||f.push({caret:a.sourceEditorCaret(),sourceMode:a.sourceMode(),value:c}),f.push(b),i(b)),!1},c.redo=function(){var a=f.pop();return g.length||(g.push(a),a=f.pop()),a&&(g.push(a),i(a)),!1},c.signalReady=function(){var c=a.val(null,!1);b=c,g.push({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:c})},c.signalValuechangedEvent=function(c){var i=c.rawValue;e>0&&g.length>e&&g.shift(),!h&&b&&b!==i&&(f.length=0,d+=j(b,i),d<20||d<50&&!/\s$/g.test(c.rawValue)||(g.push({caret:a.sourceEditorCaret(),sourceMode:a.sourceMode(),value:i}),d=0,b=i))}}}(jQuery); | ||
/* SCEditor v2.0.0-beta1 | (C) 2017, Sam Clarke | sceditor.com/license */ | ||
!function(e){"use strict";e.plugins.undo=function(){var e,t,r=this,o=0,u=50,a=[],n=[],c=!1,s=function(r){c=!0,t=r.value,e.sourceMode(r.sourceMode),e.val(r.value,!1),e.focus(),r.sourceMode?e.sourceEditorCaret(r.caret):e.getRangeHelper().restoreRange(),c=!1},l=function(e,t){var r,o,u,a,n=e.length,c=t.length,s=Math.max(n,c);for(r=0;r<s&&e.charAt(r)===t.charAt(r);r++);for(u=n<c?c-n:0,a=c<n?n-c:0,o=s-1;o>=0&&e.charAt(o-u)===t.charAt(o-a);o--);return o-r+1};r.init=function(){u=(e=this).undoLimit||u,e.addShortcut("ctrl+z",r.undo),e.addShortcut("ctrl+shift+z",r.redo),e.addShortcut("ctrl+y",r.redo)},r.undo=function(){var t=n.pop(),r=e.val(null,!1);return t&&!a.length&&r===t.value&&(t=n.pop()),t&&(a.length||a.push({caret:e.sourceEditorCaret(),sourceMode:e.sourceMode(),value:r}),a.push(t),s(t)),!1},r.redo=function(){var e=a.pop();return n.length||(n.push(e),e=a.pop()),e&&(n.push(e),s(e)),!1},r.signalReady=function(){var r=e.val(null,!1);t=r,n.push({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:r})},r.signalValuechangedEvent=function(r){var s=r.detail.rawValue;u>0&&n.length>u&&n.shift(),!c&&t&&t!==s&&(a.length=0,(o+=l(t,s))<20||o<50&&!/\s$/g.test(r.rawValue)||(n.push({caret:e.sourceEditorCaret(),sourceMode:e.sourceMode(),value:s}),o=0,t=s))}}}(sceditor); |
{ | ||
"name": "sceditor", | ||
"version": "1.5.2", | ||
"version": "2.0.0-beta1", | ||
"description": "A lightweight HTML and BBCode WYSIWYG editor.", | ||
@@ -41,27 +41,29 @@ "homepage": "http://www.sceditor.com/", | ||
"scripts": { | ||
"test": "grunt test" | ||
"test": "grunt test", | ||
"build": "grunt build", | ||
"dev": "node ./tests/dev-server.js" | ||
}, | ||
"devDependencies": { | ||
"autoprefixer": "^7.1.6", | ||
"grunt": "~1.0.1", | ||
"grunt-postcss": "^0.8.0", | ||
"autoprefixer": "^6.3.1", | ||
"grunt-contrib-clean": "^1.0.0", | ||
"grunt-contrib-compress": "^1.3.0", | ||
"grunt-contrib-clean": "^1.1.0", | ||
"grunt-contrib-compress": "^1.4.3", | ||
"grunt-contrib-concat": "~1.0.1", | ||
"grunt-contrib-connect": "^1.0.2", | ||
"grunt-contrib-copy": "^1.0.0", | ||
"grunt-contrib-cssmin": "^1.0.2", | ||
"grunt-contrib-jshint": "^1.0.0", | ||
"grunt-contrib-less": "^1.2.0", | ||
"grunt-contrib-qunit": "^1.2.0", | ||
"grunt-contrib-uglify": "^2.0.0", | ||
"grunt-dev-update": "^2.0.0", | ||
"grunt-contrib-less": "^1.4.1", | ||
"grunt-contrib-qunit": "^2.0.0", | ||
"grunt-contrib-uglify": "^3.1.0", | ||
"grunt-dev-update": "^2.3.0", | ||
"grunt-eslint": "^20.1.0", | ||
"grunt-githooks": "^0.6.0", | ||
"grunt-jscs": "^3.0.1", | ||
"grunt-postcss": "^0.9.0", | ||
"grunt-rollup": "^6.0.0", | ||
"grunt-saucelabs": "^9.0.0", | ||
"grunt-webpack": "^1.0.11", | ||
"time-grunt": "^1.3.0", | ||
"webpack": "^1.13.0", | ||
"webpack-dev-server": "^1.14.1" | ||
"istanbul": "^0.4.5", | ||
"istanbul-instrumenter-loader": "^3.0.0", | ||
"postcss-clean": "^1.1.0", | ||
"time-grunt": "^1.4.0", | ||
"webpack": "^3.8.1", | ||
"webpack-dev-server": "^2.9.4" | ||
} | ||
} | ||
} |
@@ -6,3 +6,3 @@ # [SCEditor](http://www.sceditor.com/) v1.5.2 | ||
[![SemVer](http://img.shields.io/:semver-✓-brightgreen.svg?style=flat-square)](http://semver.org) | ||
[![License](http://img.shields.io/npm/l/sceditor.svg?style=flat-square)](https://github.com/samclarke/SCEditor/blob/master/MIT.txt) | ||
[![License](http://img.shields.io/npm/l/sceditor.svg?style=flat-square)](https://github.com/samclarke/SCEditor/blob/master/LICENSE.md) | ||
@@ -16,24 +16,30 @@ A lightweight WYSIWYG BBCode and XHTML editor. | ||
Include the JQuery and SCEditor JavaScript | ||
Include the JQuery and SCEditor JavaScript: | ||
<link rel="stylesheet" href="minified/jquery.sceditor.min.css" type="text/css" media="all" /> | ||
<script type="text/javascript" src="minified/jquery.sceditor.bbcode.min.js"></script> | ||
```html | ||
<link rel="stylesheet" href="minified/jquery.sceditor.min.css" /> | ||
<script src="minified/jquery.sceditor.bbcode.min.js"></script> | ||
``` | ||
Then to change all textareas to WYSIWYG editors, simply do: | ||
$(function() { | ||
$("textarea").sceditor({ | ||
plugins: 'xhtml', | ||
style: 'minified/jquery.sceditor.default.min.css' | ||
}); | ||
```js | ||
$(function() { | ||
$('textarea').sceditor({ | ||
plugins: 'xhtml', | ||
style: 'minified/jquery.sceditor.default.min.css' | ||
}); | ||
}); | ||
``` | ||
or for a BBCode WYSIWYG editor do: | ||
$(function() { | ||
$("textarea").sceditor({ | ||
plugins: 'bbcode', | ||
style: 'minified/jquery.sceditor.default.min.css' | ||
}); | ||
```js | ||
$(function() { | ||
$('textarea').sceditor({ | ||
plugins: 'bbcode', | ||
style: 'minified/jquery.sceditor.default.min.css' | ||
}); | ||
}); | ||
``` | ||
@@ -52,16 +58,35 @@ | ||
npm install -g grunt-cli | ||
```bash | ||
npm install -g grunt-cli | ||
``` | ||
Next, to install the SCEditor dev dependencies run: | ||
npm install | ||
```bash | ||
npm install | ||
``` | ||
That's it! You can now build and test SCEditor with the following commands: | ||
grunt build # Minifies the JS and converts the LESS to CSS | ||
grunt test # Runs the linter and unit tests | ||
grunt release # Creates the distributable ZIP file | ||
```bash | ||
# Minify the JS and convert the LESS to CSS | ||
grunt build | ||
# Run the linter, unit tests and coverage | ||
grunt test | ||
# Creates the final distributable ZIP file | ||
grunt release | ||
``` | ||
You can also run the dev server to test changes without having to do a full | ||
build by running: | ||
```bash | ||
npm run dev | ||
``` | ||
and then going to http://localhost:9000/tests/ | ||
## Contribute | ||
@@ -68,0 +93,0 @@ |
@@ -5,3 +5,3 @@ /** | ||
* | ||
* Copyright (C) 2014, Sam Clarke (samclarke.com) | ||
* Copyright (C) 2017, Sam Clarke (samclarke.com) | ||
* | ||
@@ -15,92 +15,55 @@ * SCEditor is licensed under the MIT license: | ||
*/ | ||
define(function (require) { | ||
'use strict'; | ||
var $ = require('jquery'); | ||
var SCEditor = require('./lib/SCEditor'); | ||
var PluginManager = require('./lib/PluginManager'); | ||
var browser = require('./lib/browser'); | ||
var escape = require('./lib/escape'); | ||
import $ from 'jquery'; | ||
import './sceditor.js'; | ||
// For backwards compatibility | ||
$.sceditor = SCEditor; | ||
// For backwards compatibility | ||
$.sceditor = window.sceditor; | ||
SCEditor.commands = require('./lib/defaultCommands'); | ||
SCEditor.defaultOptions = require('./lib/defaultOptions'); | ||
SCEditor.RangeHelper = require('./lib/RangeHelper'); | ||
SCEditor.dom = require('./lib/dom'); | ||
/** | ||
* Creates an instance of sceditor on all textareas | ||
* matched by the jQuery selector. | ||
* | ||
* If options is set to "state" it will return bool value | ||
* indicating if the editor has been initialised on the | ||
* matched textarea(s). If there is only one textarea | ||
* it will return the bool value for that textarea. | ||
* If more than one textarea is matched it will | ||
* return an array of bool values for each textarea. | ||
* | ||
* If options is set to "instance" it will return the | ||
* current editor instance for the textarea(s). Like the | ||
* state option, if only one textarea is matched this will | ||
* return just the instance for that textarea. If more than | ||
* one textarea is matched it will return an array of | ||
* instances each textarea. | ||
* | ||
* @param {Object|string} [options] Should either be an Object of options or | ||
* the strings "state" or "instance" | ||
* @return {this|Array<SCEditor>|Array<boolean>|SCEditor|boolean} | ||
*/ | ||
$.fn.sceditor = function (options) { | ||
var instance; | ||
var ret = []; | ||
SCEditor.ie = browser.ie; | ||
SCEditor.ios = browser.ios; | ||
SCEditor.isWysiwygSupported = browser.isWysiwygSupported; | ||
this.each(function () { | ||
instance = this._sceditor; | ||
SCEditor.regexEscape = escape.regex; | ||
SCEditor.escapeEntities = escape.entities; | ||
SCEditor.escapeUriScheme = escape.uriScheme; | ||
SCEditor.PluginManager = PluginManager; | ||
SCEditor.plugins = PluginManager.plugins; | ||
/** | ||
* Creates an instance of sceditor on all textareas | ||
* matched by the jQuery selector. | ||
* | ||
* If options is set to "state" it will return bool value | ||
* indicating if the editor has been initialised on the | ||
* matched textarea(s). If there is only one textarea | ||
* it will return the bool value for that textarea. | ||
* If more than one textarea is matched it will | ||
* return an array of bool values for each textarea. | ||
* | ||
* If options is set to "instance" it will return the | ||
* current editor instance for the textarea(s). Like the | ||
* state option, if only one textarea is matched this will | ||
* return just the instance for that textarea. If more than | ||
* one textarea is matched it will return an array of | ||
* instances each textarea. | ||
* | ||
* @param {Object|String} options Should either be an Object of options or | ||
* the strings "state" or "instance" | ||
* @return {this|Array|jQuery.sceditor|Bool} | ||
*/ | ||
$.fn.sceditor = function (options) { | ||
var $this, instance, | ||
ret = []; | ||
options = options || {}; | ||
if (!options.runWithoutWysiwygSupport && !browser.isWysiwygSupported) { | ||
return; | ||
// Add state of instance to ret if that is what options is set to | ||
if (options === 'state') { | ||
ret.push(!!instance); | ||
} else if (options === 'instance') { | ||
ret.push(instance); | ||
} else if (!instance) { | ||
$.sceditor.create(this, options); | ||
} | ||
}); | ||
this.each(function () { | ||
$this = this.jquery ? this : $(this); | ||
instance = $this.data('sceditor'); | ||
// If nothing in the ret array then must be init so return this | ||
if (!ret.length) { | ||
return this; | ||
} | ||
// Don't allow the editor to be initialised | ||
// on it's own source editor | ||
if ($this.parents('.sceditor-container').length > 0) { | ||
return; | ||
} | ||
// Add state of instance to ret if that is what options is set to | ||
if (options === 'state') { | ||
ret.push(!!instance); | ||
} else if (options === 'instance') { | ||
ret.push(instance); | ||
} else if (!instance) { | ||
/*jshint -W031*/ | ||
(new SCEditor(this, options)); | ||
} | ||
}); | ||
// If nothing in the ret array then must be init so return this | ||
if (!ret.length) { | ||
return this; | ||
} | ||
return ret.length === 1 ? ret[0] : $(ret); | ||
}; | ||
}); | ||
return ret.length === 1 ? ret[0] : ret; | ||
}; |
@@ -1,128 +0,132 @@ | ||
define(function (require, exports) { | ||
'use strict'; | ||
var USER_AGENT = navigator.userAgent; | ||
var $ = require('jquery'); | ||
/** | ||
* Detects the version of IE is being used if any. | ||
* | ||
* Will be the IE version number or undefined if the | ||
* browser is not IE. | ||
* | ||
* Source: https://gist.github.com/527683 with extra code | ||
* for IE 10 & 11 detection. | ||
* | ||
* @function | ||
* @name ie | ||
* @type {number} | ||
*/ | ||
export var ie = (function () { | ||
var undef, | ||
v = 3, | ||
doc = document, | ||
div = doc.createElement('div'), | ||
all = div.getElementsByTagName('i'); | ||
var USER_AGENT = navigator.userAgent; | ||
do { | ||
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->'; | ||
} while (all[0]); | ||
/** | ||
* Detects the version of IE is being used if any. | ||
* | ||
* Will be the IE version number or undefined if the | ||
* browser is not IE. | ||
* | ||
* Source: https://gist.github.com/527683 with extra code | ||
* for IE 10 & 11 detection. | ||
* | ||
* @function | ||
* @name ie | ||
* @type {int} | ||
*/ | ||
exports.ie = (function () { | ||
var undef, | ||
v = 3, | ||
doc = document, | ||
div = doc.createElement('div'), | ||
all = div.getElementsByTagName('i'); | ||
// Detect IE 10 as it doesn't support conditional comments. | ||
if ((doc.documentMode && doc.all && window.atob)) { | ||
v = 10; | ||
} | ||
do { | ||
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->'; | ||
} while (all[0]); | ||
// Detect IE 11 | ||
if (v === 4 && doc.documentMode) { | ||
v = 11; | ||
} | ||
// Detect IE 10 as it doesn't support conditional comments. | ||
if ((doc.documentMode && doc.all && window.atob)) { | ||
v = 10; | ||
} | ||
return v > 4 ? v : undef; | ||
}()); | ||
// Detect IE 11 | ||
if (v === 4 && doc.documentMode) { | ||
v = 11; | ||
} | ||
export var edge = '-ms-ime-align' in document.documentElement.style; | ||
return v > 4 ? v : undef; | ||
}()); | ||
/** | ||
* Detects if the browser is iOS | ||
* | ||
* Needed to fix iOS specific bugs | ||
* | ||
* @function | ||
* @name ios | ||
* @memberOf jQuery.sceditor | ||
* @type {boolean} | ||
*/ | ||
export var ios = /iPhone|iPod|iPad| wosbrowser\//i.test(USER_AGENT); | ||
/** | ||
* <p>Detects if the browser is iOS</p> | ||
* | ||
* <p>Needed to fix iOS specific bugs/</p> | ||
* | ||
* @function | ||
* @name ios | ||
* @memberOf jQuery.sceditor | ||
* @type {Boolean} | ||
*/ | ||
exports.ios = /iPhone|iPod|iPad| wosbrowser\//i.test(USER_AGENT); | ||
/** | ||
* If the browser supports WYSIWYG editing (e.g. older mobile browsers). | ||
* | ||
* @function | ||
* @name isWysiwygSupported | ||
* @return {boolean} | ||
*/ | ||
export var isWysiwygSupported = (function () { | ||
var match, isUnsupported; | ||
/** | ||
* If the browser supports WYSIWYG editing (e.g. older mobile browsers). | ||
* | ||
* @function | ||
* @name isWysiwygSupported | ||
* @return {Boolean} | ||
*/ | ||
exports.isWysiwygSupported = (function () { | ||
var match, isUnsupported, undef, | ||
editableAttr = $('<p contenteditable="true">')[0].contentEditable; | ||
var div = document.createElement('div'); | ||
div.contentEditable = true ; | ||
// Check if the contenteditable attribute is supported | ||
if (editableAttr === undef || editableAttr === 'inherit') { | ||
return false; | ||
} | ||
// Check if the contentEditable attribute is supported | ||
if (!('contentEditable' in document.documentElement) || | ||
div.contentEditable !== 'true') { | ||
return false; | ||
} | ||
// I think blackberry supports contentEditable or will at least | ||
// give a valid value for the contentEditable detection above | ||
// so it isn't included in the below tests. | ||
// I think blackberry supports contentEditable or will at least | ||
// give a valid value for the contentEditable detection above | ||
// so it isn't included in the below tests. | ||
// I hate having to do UA sniffing but some mobile browsers say they | ||
// support contentediable when it isn't usable, i.e. you can't enter | ||
// text. | ||
// This is the only way I can think of to detect them which is also how | ||
// every other editor I've seen deals with this issue. | ||
// I hate having to do UA sniffing but some mobile browsers say they | ||
// support contentediable when it isn't usable, i.e. you can't enter | ||
// text. | ||
// This is the only way I can think of to detect them which is also how | ||
// every other editor I've seen deals with this issue. | ||
// Exclude Opera mobile and mini | ||
isUnsupported = /Opera Mobi|Opera Mini/i.test(USER_AGENT); | ||
// Exclude Opera mobile and mini | ||
isUnsupported = /Opera Mobi|Opera Mini/i.test(USER_AGENT); | ||
if (/Android/i.test(USER_AGENT)) { | ||
isUnsupported = true; | ||
if (/Android/i.test(USER_AGENT)) { | ||
isUnsupported = true; | ||
if (/Safari/.test(USER_AGENT)) { | ||
// Android browser 534+ supports content editable | ||
// This also matches Chrome which supports content editable too | ||
match = /Safari\/(\d+)/.exec(USER_AGENT); | ||
isUnsupported = (!match || !match[1] ? true : match[1] < 534); | ||
} | ||
} | ||
// The current version of Amazon Silk supports it, older versions didn't | ||
// As it uses webkit like Android, assume it's the same and started | ||
// working at versions >= 534 | ||
if (/ Silk\//i.test(USER_AGENT)) { | ||
match = /AppleWebKit\/(\d+)/.exec(USER_AGENT); | ||
if (/Safari/.test(USER_AGENT)) { | ||
// Android browser 534+ supports content editable | ||
// This also matches Chrome which supports content editable too | ||
match = /Safari\/(\d+)/.exec(USER_AGENT); | ||
isUnsupported = (!match || !match[1] ? true : match[1] < 534); | ||
} | ||
} | ||
// iOS 5+ supports content editable | ||
if (exports.ios) { | ||
// Block any version <= 4_x(_x) | ||
isUnsupported = /OS [0-4](_\d)+ like Mac/i.test(USER_AGENT); | ||
} | ||
// The current version of Amazon Silk supports it, older versions didn't | ||
// As it uses webkit like Android, assume it's the same and started | ||
// working at versions >= 534 | ||
if (/ Silk\//i.test(USER_AGENT)) { | ||
match = /AppleWebKit\/(\d+)/.exec(USER_AGENT); | ||
isUnsupported = (!match || !match[1] ? true : match[1] < 534); | ||
} | ||
// FireFox does support WYSIWYG on mobiles so override | ||
// any previous value if using FF | ||
if (/Firefox/i.test(USER_AGENT)) { | ||
isUnsupported = false; | ||
} | ||
// iOS 5+ supports content editable | ||
if (ios) { | ||
// Block any version <= 4_x(_x) | ||
isUnsupported = /OS [0-4](_\d)+ like Mac/i.test(USER_AGENT); | ||
} | ||
if (/OneBrowser/i.test(USER_AGENT)) { | ||
isUnsupported = false; | ||
} | ||
// Firefox does support WYSIWYG on mobiles so override | ||
// any previous value if using FF | ||
if (/Firefox/i.test(USER_AGENT)) { | ||
isUnsupported = false; | ||
} | ||
// UCBrowser works but doesn't give a unique user agent | ||
if (navigator.vendor === 'UCWEB') { | ||
isUnsupported = false; | ||
} | ||
if (/OneBrowser/i.test(USER_AGENT)) { | ||
isUnsupported = false; | ||
} | ||
return !isUnsupported; | ||
}()); | ||
}); | ||
// UCBrowser works but doesn't give a unique user agent | ||
if (navigator.vendor === 'UCWEB') { | ||
isUnsupported = false; | ||
} | ||
// IE <= 9 is not supported any more | ||
if (ie <= 9) { | ||
isUnsupported = true; | ||
} | ||
return !isUnsupported; | ||
}()); |
@@ -1,421 +0,400 @@ | ||
define(function (require) { | ||
'use strict'; | ||
import * as dom from './dom.js'; | ||
import * as utils from './utils.js'; | ||
import { ie as IE_VER } from './browser.js'; | ||
import _tmpl from './templates.js'; | ||
var $ = require('jquery'); | ||
var IE_VER = require('./browser').ie; | ||
var _tmpl = require('./templates'); | ||
// In IE < 11 a BR at the end of a block level element | ||
// causes a line break. In all other browsers it's collapsed. | ||
var IE_BR_FIX = IE_VER && IE_VER < 11; | ||
// In IE < 11 a BR at the end of a block level element | ||
// causes a line break. In all other browsers it's collapsed. | ||
var IE_BR_FIX = IE_VER && IE_VER < 11; | ||
/** | ||
* Fixes a bug in FF where it sometimes wraps | ||
* new lines in their own list item. | ||
* See issue #359 | ||
*/ | ||
function fixFirefoxListBug(editor) { | ||
// Only apply to Firefox as will break other browsers. | ||
if ('mozHidden' in document) { | ||
var node = editor.getBody(); | ||
var next; | ||
while (node) { | ||
next = node; | ||
/** | ||
* Map of all the commands for SCEditor | ||
* @type {Object} | ||
* @name commands | ||
* @memberOf jQuery.sceditor | ||
*/ | ||
var defaultCommnds = { | ||
// START_COMMAND: Bold | ||
bold: { | ||
exec: 'bold', | ||
tooltip: 'Bold', | ||
shortcut: 'Ctrl+B' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Italic | ||
italic: { | ||
exec: 'italic', | ||
tooltip: 'Italic', | ||
shortcut: 'Ctrl+I' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Underline | ||
underline: { | ||
exec: 'underline', | ||
tooltip: 'Underline', | ||
shortcut: 'Ctrl+U' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Strikethrough | ||
strike: { | ||
exec: 'strikethrough', | ||
tooltip: 'Strikethrough' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Subscript | ||
subscript: { | ||
exec: 'subscript', | ||
tooltip: 'Subscript' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Superscript | ||
superscript: { | ||
exec: 'superscript', | ||
tooltip: 'Superscript' | ||
}, | ||
// END_COMMAND | ||
if (next.firstChild) { | ||
next = next.firstChild; | ||
} else { | ||
// START_COMMAND: Left | ||
left: { | ||
exec: 'justifyleft', | ||
tooltip: 'Align left' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Centre | ||
center: { | ||
exec: 'justifycenter', | ||
tooltip: 'Center' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Right | ||
right: { | ||
exec: 'justifyright', | ||
tooltip: 'Align right' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Justify | ||
justify: { | ||
exec: 'justifyfull', | ||
tooltip: 'Justify' | ||
}, | ||
// END_COMMAND | ||
while (next && !next.nextSibling) { | ||
next = next.parentNode; | ||
} | ||
// START_COMMAND: Font | ||
font: { | ||
_dropDown: function (editor, caller, callback) { | ||
var fontIdx = 0, | ||
fonts = editor.opts.fonts.split(','), | ||
content = $('<div />'), | ||
/** @private */ | ||
clickFunc = function () { | ||
callback($(this).data('font')); | ||
editor.closeDropDown(true); | ||
return false; | ||
}; | ||
if (next) { | ||
next = next.nextSibling; | ||
} | ||
} | ||
for (; fontIdx < fonts.length; fontIdx++) { | ||
content.append( | ||
_tmpl('fontOpt', { | ||
font: fonts[fontIdx] | ||
}, true).click(clickFunc) | ||
); | ||
if (node.nodeType === 3 && /[\n\r\t]+/.test(node.nodeValue)) { | ||
// Only remove if newlines are collapsed | ||
if (!/^pre/.test(dom.css(node.parentNode, 'whiteSpace'))) { | ||
dom.remove(node); | ||
} | ||
} | ||
editor.createDropDown(caller, 'font-picker', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
node = next; | ||
} | ||
} | ||
} | ||
defaultCommnds.font._dropDown( | ||
editor, | ||
caller, | ||
function (fontName) { | ||
editor.execCommand('fontname', fontName); | ||
} | ||
); | ||
}, | ||
tooltip: 'Font Name' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Size | ||
size: { | ||
_dropDown: function (editor, caller, callback) { | ||
var content = $('<div />'), | ||
/** @private */ | ||
clickFunc = function (e) { | ||
callback($(this).data('size')); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}; | ||
for (var i = 1; i <= 7; i++) { | ||
content.append(_tmpl('sizeOpt', { | ||
size: i | ||
}, true).click(clickFunc)); | ||
} | ||
/** | ||
* Map of all the commands for SCEditor | ||
* @type {Object} | ||
* @name commands | ||
* @memberOf jQuery.sceditor | ||
*/ | ||
var defaultCmds = { | ||
// START_COMMAND: Bold | ||
bold: { | ||
exec: 'bold', | ||
tooltip: 'Bold', | ||
shortcut: 'Ctrl+B' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Italic | ||
italic: { | ||
exec: 'italic', | ||
tooltip: 'Italic', | ||
shortcut: 'Ctrl+I' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Underline | ||
underline: { | ||
exec: 'underline', | ||
tooltip: 'Underline', | ||
shortcut: 'Ctrl+U' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Strikethrough | ||
strike: { | ||
exec: 'strikethrough', | ||
tooltip: 'Strikethrough' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Subscript | ||
subscript: { | ||
exec: 'subscript', | ||
tooltip: 'Subscript' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Superscript | ||
superscript: { | ||
exec: 'superscript', | ||
tooltip: 'Superscript' | ||
}, | ||
// END_COMMAND | ||
editor.createDropDown(caller, 'fontsize-picker', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
// START_COMMAND: Left | ||
left: { | ||
exec: 'justifyleft', | ||
tooltip: 'Align left' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Centre | ||
center: { | ||
exec: 'justifycenter', | ||
tooltip: 'Center' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Right | ||
right: { | ||
exec: 'justifyright', | ||
tooltip: 'Align right' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Justify | ||
justify: { | ||
exec: 'justifyfull', | ||
tooltip: 'Justify' | ||
}, | ||
// END_COMMAND | ||
defaultCommnds.size._dropDown( | ||
editor, | ||
caller, | ||
function (fontSize) { | ||
editor.execCommand('fontsize', fontSize); | ||
} | ||
); | ||
}, | ||
tooltip: 'Font Size' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Colour | ||
color: { | ||
_dropDown: function (editor, caller, callback) { | ||
var i, x, color, colors, | ||
genColor = {r: 255, g: 255, b: 255}, | ||
content = $('<div />'), | ||
colorColumns = editor.opts.colors ? | ||
editor.opts.colors.split('|') : new Array(21), | ||
// IE is slow at string concatenation so use an array | ||
html = [], | ||
cmd = defaultCommnds.color; | ||
// START_COMMAND: Font | ||
font: { | ||
_dropDown: function (editor, caller, callback) { | ||
var content = dom.createElement('div'); | ||
if (!cmd._htmlCache) { | ||
for (i = 0; i < colorColumns.length; ++i) { | ||
colors = colorColumns[i] ? | ||
colorColumns[i].split(',') : new Array(21); | ||
dom.on(content, 'click', 'a', function (e) { | ||
callback(dom.data(this, 'font')); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
html.push('<div class="sceditor-color-column">'); | ||
editor.opts.fonts.split(',').forEach(function (font) { | ||
dom.appendChild(content, _tmpl('fontOpt', { | ||
font: font | ||
}, true)); | ||
}); | ||
for (x = 0; x < colors.length; ++x) { | ||
// use pre defined colour if can otherwise use the | ||
// generated color | ||
color = colors[x] || '#' + | ||
genColor.r.toString(16) + | ||
genColor.g.toString(16) + | ||
genColor.b.toString(16); | ||
editor.createDropDown(caller, 'font-picker', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
html.push( | ||
'<a href="#" class="sceditor-color-option"' + | ||
' style="background-color: ' + color + '"' + | ||
' data-color="' + color + '"></a>' | ||
); | ||
defaultCmds.font._dropDown(editor, caller, function (fontName) { | ||
editor.execCommand('fontname', fontName); | ||
}); | ||
}, | ||
tooltip: 'Font Name' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Size | ||
size: { | ||
_dropDown: function (editor, caller, callback) { | ||
var content = dom.createElement('div'); | ||
if (x % 5 === 0) { | ||
genColor.g -= 51; | ||
genColor.b = 255; | ||
} else { | ||
genColor.b -= 51; | ||
} | ||
} | ||
dom.on(content, 'click', 'a', function (e) { | ||
callback(dom.data(this, 'size')); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
html.push('</div>'); | ||
for (var i = 1; i <= 7; i++) { | ||
dom.appendChild(content, _tmpl('sizeOpt', { | ||
size: i | ||
}, true)); | ||
} | ||
if (i % 5 === 0) { | ||
genColor.r -= 51; | ||
genColor.g = 255; | ||
genColor.b = 255; | ||
} else { | ||
genColor.g = 255; | ||
genColor.b = 255; | ||
} | ||
} | ||
editor.createDropDown(caller, 'fontsize-picker', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
cmd._htmlCache = html.join(''); | ||
} | ||
defaultCmds.size._dropDown(editor, caller, function (fontSize) { | ||
editor.execCommand('fontsize', fontSize); | ||
}); | ||
}, | ||
tooltip: 'Font Size' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Colour | ||
color: { | ||
_dropDown: function (editor, caller, callback) { | ||
var content = dom.createElement('div'), | ||
html = '', | ||
cmd = defaultCmds.color; | ||
content.append(cmd._htmlCache) | ||
.find('a') | ||
.click(function (e) { | ||
callback($(this).attr('data-color')); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
if (!cmd._htmlCache) { | ||
editor.opts.colors.split('|').forEach(function (column) { | ||
html += '<div class="sceditor-color-column">'; | ||
column.split(',').forEach(function (color) { | ||
html += | ||
'<a href="#" class="sceditor-color-option"' + | ||
' style="background-color: ' + color + '"' + | ||
' data-color="' + color + '"></a>'; | ||
}); | ||
editor.createDropDown(caller, 'color-picker', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
html += '</div>'; | ||
}); | ||
defaultCommnds.color._dropDown( | ||
editor, | ||
caller, | ||
function (color) { | ||
editor.execCommand('forecolor', color); | ||
} | ||
); | ||
}, | ||
tooltip: 'Font Color' | ||
cmd._htmlCache = html; | ||
} | ||
dom.appendChild(content, dom.parseHTML(cmd._htmlCache)); | ||
dom.on(content, 'click', 'a', function (e) { | ||
callback(dom.data(this, 'color')); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
editor.createDropDown(caller, 'color-picker', content); | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Remove Format | ||
removeformat: { | ||
exec: 'removeformat', | ||
tooltip: 'Remove Formatting' | ||
}, | ||
// END_COMMAND | ||
exec: function (caller) { | ||
var editor = this; | ||
// START_COMMAND: Cut | ||
cut: { | ||
exec: 'cut', | ||
tooltip: 'Cut', | ||
errorMessage: 'Your browser does not allow the cut command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-X' | ||
defaultCmds.color._dropDown(editor, caller, function (color) { | ||
editor.execCommand('forecolor', color); | ||
}); | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Copy | ||
copy: { | ||
exec: 'copy', | ||
tooltip: 'Copy', | ||
errorMessage: 'Your browser does not allow the copy command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-C' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Paste | ||
paste: { | ||
exec: 'paste', | ||
tooltip: 'Paste', | ||
errorMessage: 'Your browser does not allow the paste command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-V' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Paste Text | ||
pastetext: { | ||
exec: function (caller) { | ||
var val, content, | ||
editor = this; | ||
tooltip: 'Font Color' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Remove Format | ||
removeformat: { | ||
exec: 'removeformat', | ||
tooltip: 'Remove Formatting' | ||
}, | ||
// END_COMMAND | ||
content = _tmpl('pastetext', { | ||
label: editor._( | ||
'Paste your text inside the following box:' | ||
), | ||
insert: editor._('Insert') | ||
}, true); | ||
// START_COMMAND: Cut | ||
cut: { | ||
exec: 'cut', | ||
tooltip: 'Cut', | ||
errorMessage: 'Your browser does not allow the cut command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-X' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Copy | ||
copy: { | ||
exec: 'copy', | ||
tooltip: 'Copy', | ||
errorMessage: 'Your browser does not allow the copy command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-C' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Paste | ||
paste: { | ||
exec: 'paste', | ||
tooltip: 'Paste', | ||
errorMessage: 'Your browser does not allow the paste command. ' + | ||
'Please use the keyboard shortcut Ctrl/Cmd-V' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Paste Text | ||
pastetext: { | ||
exec: function (caller) { | ||
var val, | ||
content = dom.createElement('div'), | ||
editor = this; | ||
content.find('.button').click(function (e) { | ||
val = content.find('#txt').val(); | ||
dom.appendChild(content, _tmpl('pastetext', { | ||
label: editor._( | ||
'Paste your text inside the following box:' | ||
), | ||
insert: editor._('Insert') | ||
}, true)); | ||
if (val) { | ||
editor.wysiwygEditorInsertText(val); | ||
} | ||
dom.on(content, 'click', '.button', function (e) { | ||
val = dom.find(content, '#txt')[0].value; | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
if (val) { | ||
editor.wysiwygEditorInsertText(val); | ||
} | ||
editor.createDropDown(caller, 'pastetext', content); | ||
}, | ||
tooltip: 'Paste Text' | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
editor.createDropDown(caller, 'pastetext', content); | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Bullet List | ||
bulletlist: { | ||
exec: 'insertunorderedlist', | ||
tooltip: 'Bullet list' | ||
tooltip: 'Paste Text' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Bullet List | ||
bulletlist: { | ||
exec: function () { | ||
fixFirefoxListBug(this); | ||
this.execCommand('insertunorderedlist'); | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Ordered List | ||
orderedlist: { | ||
exec: 'insertorderedlist', | ||
tooltip: 'Numbered list' | ||
tooltip: 'Bullet list' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Ordered List | ||
orderedlist: { | ||
exec: function () { | ||
fixFirefoxListBug(this); | ||
this.execCommand('insertorderedlist'); | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Indent | ||
indent: { | ||
state: function (parents, firstBlock) { | ||
// Only works with lists, for now | ||
// This is a nested list, so it will always work | ||
var range, startParent, endParent, | ||
$firstBlock = $(firstBlock), | ||
parentLists = $firstBlock.parents('ul,ol,menu'), | ||
parentList = parentLists.first(); | ||
tooltip: 'Numbered list' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Indent | ||
indent: { | ||
state: function (parents, firstBlock) { | ||
// Only works with lists, for now | ||
var range, startParent, endParent, | ||
parentLists = dom.parents(firstBlock, 'ul,ol,menu'); | ||
// in case it's a list with only a single <li> | ||
if (parentLists.length > 1 || | ||
parentList.children().length > 1) { | ||
return 0; | ||
} | ||
// in case it's a list with only a single <li> | ||
if (parentLists.length > 1 && parentLists[0].children.length > 1) { | ||
return 0; | ||
} | ||
if ($firstBlock.is('ul,ol,menu')) { | ||
// if the whole list is selected, then this must be | ||
// invalidated because the browser will place a | ||
// <blockquote> there | ||
range = this.getRangeHelper().selectedRange(); | ||
if (dom.is(firstBlock, 'ul,ol,menu')) { | ||
// if the whole list is selected, then this must be | ||
// invalidated because the browser will place a | ||
// <blockquote> there | ||
range = this.getRangeHelper().selectedRange(); | ||
if (window.Range && range instanceof Range) { | ||
startParent = range.startContainer.parentNode; | ||
endParent = range.endContainer.parentNode; | ||
startParent = range.startContainer.parentNode; | ||
endParent = range.endContainer.parentNode; | ||
// TODO: could use nodeType for this? | ||
// Maybe just check the firstBlock contains both the start and end containers | ||
// Select the tag, not the textNode | ||
// (that's why the parentNode) | ||
if (startParent !== | ||
startParent.parentNode.firstElementChild || | ||
// work around a bug in FF | ||
($(endParent).is('li') && endParent !== | ||
endParent.parentNode.lastElementChild)) { | ||
return 0; | ||
} | ||
// it's IE... As it is impossible to know well when to | ||
// accept, better safe than sorry | ||
} else { | ||
return $firstBlock.is('li,ul,ol,menu') ? 0 : -1; | ||
} | ||
// TODO: could use nodeType for this? | ||
// Maybe just check the firstBlock contains both the start | ||
//and end containers | ||
// Select the tag, not the textNode | ||
// (that's why the parentNode) | ||
if (startParent !== | ||
startParent.parentNode.firstElementChild || | ||
// work around a bug in FF | ||
(dom.is(endParent, 'li') && endParent !== | ||
endParent.parentNode.lastElementChild)) { | ||
return 0; | ||
} | ||
} | ||
return -1; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
$elm = $(editor.getRangeHelper().getFirstBlockParent()); | ||
return -1; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
block = editor.getRangeHelper().getFirstBlockParent(); | ||
editor.focus(); | ||
editor.focus(); | ||
// An indent system is quite complicated as there are loads | ||
// of complications and issues around how to indent text | ||
// As default, let's just stay with indenting the lists, | ||
// at least, for now. | ||
if ($elm.parents('ul,ol,menu')) { | ||
editor.execCommand('indent'); | ||
} | ||
}, | ||
tooltip: 'Add indent' | ||
// An indent system is quite complicated as there are loads | ||
// of complications and issues around how to indent text | ||
// As default, let's just stay with indenting the lists, | ||
// at least, for now. | ||
if (dom.parents(block, 'ul,ol,menu')) { | ||
editor.execCommand('indent'); | ||
} | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Outdent | ||
outdent: { | ||
state: function (parents, firstBlock) { | ||
return $(firstBlock).is('ul,ol,menu') || | ||
$(firstBlock).parents('ul,ol,menu').length > 0 ? 0 : -1; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
$elm = $(editor.getRangeHelper().getFirstBlockParent()); | ||
tooltip: 'Add indent' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Outdent | ||
outdent: { | ||
state: function (parents, firstBlock) { | ||
return dom.closest(firstBlock, 'ul,ol,menu') > 0 ? 0 : -1; | ||
}, | ||
exec: function () { | ||
var block = this.getRangeHelper().getFirstBlockParent(); | ||
if ($elm.parents('ul,ol,menu')) { | ||
editor.execCommand('outdent'); | ||
} | ||
}, | ||
tooltip: 'Remove one indent' | ||
if (dom.parents(block, 'ul,ol,menu')) { | ||
this.execCommand('outdent'); | ||
} | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Remove one indent' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Table | ||
table: { | ||
forceNewLineAfter: ['table'], | ||
exec: function (caller) { | ||
var editor = this, | ||
content = _tmpl('table', { | ||
rows: editor._('Rows:'), | ||
cols: editor._('Cols:'), | ||
insert: editor._('Insert') | ||
}, true); | ||
// START_COMMAND: Table | ||
table: { | ||
exec: function (caller) { | ||
var editor = this, | ||
content = dom.createElement('div'); | ||
content.find('.button').click(function (e) { | ||
var row, col, | ||
rows = content.find('#rows').val() - 0, | ||
cols = content.find('#cols').val() - 0, | ||
html = '<table>'; | ||
dom.appendChild(content, _tmpl('table', { | ||
rows: editor._('Rows:'), | ||
cols: editor._('Cols:'), | ||
insert: editor._('Insert') | ||
}, true)); | ||
if (rows < 1 || cols < 1) { | ||
return; | ||
} | ||
dom.on(content, 'click', '.button', function (e) { | ||
var rows = Number(dom.find(content, '#rows')[0].value), | ||
cols = Number(dom.find(content, '#cols')[0].value), | ||
html = '<table>'; | ||
for (row = 0; row < rows; row++) { | ||
html += '<tr>'; | ||
if (rows > 0 && cols > 0) { | ||
html += Array(rows + 1).join( | ||
'<tr>' + | ||
Array(cols + 1).join( | ||
'<td>' + (IE_BR_FIX ? '' : '<br />') + '</td>' | ||
) + | ||
'</tr>' | ||
); | ||
for (col = 0; col < cols; col++) { | ||
html += '<td>' + | ||
(IE_BR_FIX ? '' : '<br />') + | ||
'</td>'; | ||
} | ||
html += '</tr>'; | ||
} | ||
html += '</table>'; | ||
@@ -426,47 +405,72 @@ | ||
e.preventDefault(); | ||
}); | ||
} | ||
}); | ||
editor.createDropDown(caller, 'inserttable', content); | ||
}, | ||
tooltip: 'Insert a table' | ||
editor.createDropDown(caller, 'inserttable', content); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Insert a table' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Horizontal Rule | ||
horizontalrule: { | ||
exec: 'inserthorizontalrule', | ||
tooltip: 'Insert a horizontal rule' | ||
// START_COMMAND: Horizontal Rule | ||
horizontalrule: { | ||
exec: 'inserthorizontalrule', | ||
tooltip: 'Insert a horizontal rule' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Code | ||
code: { | ||
exec: function () { | ||
this.wysiwygEditorInsertHtml( | ||
'<code>', | ||
(IE_BR_FIX ? '' : '<br />') + '</code>' | ||
); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Code' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Code | ||
code: { | ||
forceNewLineAfter: ['code'], | ||
exec: function () { | ||
this.wysiwygEditorInsertHtml( | ||
'<code>', | ||
(IE_BR_FIX ? '' : '<br />') + '</code>' | ||
); | ||
}, | ||
tooltip: 'Code' | ||
// START_COMMAND: Image | ||
image: { | ||
_dropDown: function (editor, caller, selected, cb) { | ||
var content = dom.createElement('div'); | ||
dom.appendChild(content, _tmpl('image', { | ||
url: editor._('URL:'), | ||
width: editor._('Width (optional):'), | ||
height: editor._('Height (optional):'), | ||
insert: editor._('Insert') | ||
}, true)); | ||
var urlInput = dom.find(content, '#image')[0]; | ||
urlInput.value = selected; | ||
dom.on(content, 'click', '.button', function (e) { | ||
if (urlInput.value) { | ||
cb( | ||
urlInput.value, | ||
dom.find(content, '#width')[0].value, | ||
dom.find(content, '#height')[0].value | ||
); | ||
} | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
editor.createDropDown(caller, 'insertimage', content); | ||
}, | ||
// END_COMMAND | ||
exec: function (caller) { | ||
var editor = this; | ||
// START_COMMAND: Image | ||
image: { | ||
exec: function (caller) { | ||
var editor = this, | ||
content = _tmpl('image', { | ||
url: editor._('URL:'), | ||
width: editor._('Width (optional):'), | ||
height: editor._('Height (optional):'), | ||
insert: editor._('Insert') | ||
}, true); | ||
defaultCmds.image._dropDown( | ||
editor, | ||
caller, | ||
'', | ||
function (url, width, height) { | ||
var attrs = ''; | ||
content.find('.button').click(function (e) { | ||
var val = content.find('#image').val(), | ||
width = content.find('#width').val(), | ||
height = content.find('#height').val(), | ||
attrs = ''; | ||
if (width) { | ||
@@ -480,464 +484,460 @@ attrs += ' width="' + width + '"'; | ||
if (val) { | ||
editor.wysiwygEditorInsertHtml( | ||
'<img' + attrs + ' src="' + val + '" />' | ||
); | ||
} | ||
editor.wysiwygEditorInsertHtml( | ||
'<img' + attrs + ' src="' + url + '" />' | ||
); | ||
} | ||
); | ||
}, | ||
tooltip: 'Insert an image' | ||
}, | ||
// END_COMMAND | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
// START_COMMAND: E-mail | ||
email: { | ||
_dropDown: function (editor, caller, cb) { | ||
var content = dom.createElement('div'); | ||
editor.createDropDown(caller, 'insertimage', content); | ||
}, | ||
tooltip: 'Insert an image' | ||
}, | ||
// END_COMMAND | ||
dom.appendChild(content, _tmpl('email', { | ||
label: editor._('E-mail:'), | ||
desc: editor._('Description (optional):'), | ||
insert: editor._('Insert') | ||
}, true)); | ||
// START_COMMAND: E-mail | ||
email: { | ||
exec: function (caller) { | ||
var editor = this, | ||
content = _tmpl('email', { | ||
label: editor._('E-mail:'), | ||
desc: editor._('Description (optional):'), | ||
insert: editor._('Insert') | ||
}, true); | ||
dom.on(content, 'click', '.button', function (e) { | ||
var email = dom.find(content, '#email')[0].value; | ||
content.find('.button').click(function (e) { | ||
var val = content.find('#email').val(), | ||
description = content.find('#des').val(); | ||
if (email) { | ||
cb(email, dom.find(content, '#des')[0].value); | ||
} | ||
if (val) { | ||
// needed for IE to reset the last range | ||
editor.focus(); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
if (!editor.getRangeHelper().selectedHtml() || | ||
description) { | ||
description = description || val; | ||
editor.createDropDown(caller, 'insertemail', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
editor.wysiwygEditorInsertHtml( | ||
'<a href="' + 'mailto:' + val + '">' + | ||
description + | ||
'</a>' | ||
); | ||
} else { | ||
editor.execCommand('createlink', 'mailto:' + val); | ||
} | ||
defaultCmds.email._dropDown( | ||
editor, | ||
caller, | ||
function (email, text) { | ||
// needed for IE to reset the last range | ||
editor.focus(); | ||
if (!editor.getRangeHelper().selectedHtml() || text) { | ||
editor.wysiwygEditorInsertHtml( | ||
'<a href="' + 'mailto:' + email + '">' + | ||
(text || email) + | ||
'</a>' | ||
); | ||
} else { | ||
editor.execCommand('createlink', 'mailto:' + email); | ||
} | ||
} | ||
); | ||
}, | ||
tooltip: 'Insert an email' | ||
}, | ||
// END_COMMAND | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
// START_COMMAND: Link | ||
link: { | ||
_dropDown: function (editor, caller, cb) { | ||
var content = dom.createElement('div'); | ||
editor.createDropDown(caller, 'insertemail', content); | ||
}, | ||
tooltip: 'Insert an email' | ||
}, | ||
// END_COMMAND | ||
dom.appendChild(content, _tmpl('link', { | ||
url: editor._('URL:'), | ||
desc: editor._('Description (optional):'), | ||
ins: editor._('Insert') | ||
}, true)); | ||
// START_COMMAND: Link | ||
link: { | ||
exec: function (caller) { | ||
var editor = this, | ||
content = _tmpl('link', { | ||
url: editor._('URL:'), | ||
desc: editor._('Description (optional):'), | ||
ins: editor._('Insert') | ||
}, true); | ||
var linkInput = dom.find(content, '#link')[0]; | ||
content.find('.button').click(function (e) { | ||
var val = content.find('#link').val(), | ||
description = content.find('#des').val(); | ||
function insertUrl(e) { | ||
if (linkInput.value) { | ||
cb(linkInput.value, dom.find(content, '#des')[0].value); | ||
} | ||
if (val) { | ||
// needed for IE to restore the last range | ||
editor.focus(); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
} | ||
// If there is no selected text then must set the URL as | ||
// the text. Most browsers do this automatically, sadly | ||
// IE doesn't. | ||
if (!editor.getRangeHelper().selectedHtml() || | ||
description) { | ||
description = description || val; | ||
dom.on(content, 'click', '.button', insertUrl); | ||
dom.on(content, 'keypress', function (e) { | ||
// 13 = enter key | ||
if (e.which === 13 && linkInput.value) { | ||
insertUrl(e); | ||
} | ||
}, dom.EVENT_CAPTURE); | ||
editor.wysiwygEditorInsertHtml( | ||
'<a href="' + val + '">' + description + '</a>' | ||
); | ||
} else { | ||
editor.execCommand('createlink', val); | ||
} | ||
} | ||
editor.createDropDown(caller, 'insertlink', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
defaultCmds.link._dropDown(editor, caller, function (url, text) { | ||
// needed for IE to restore the last range | ||
editor.focus(); | ||
editor.createDropDown(caller, 'insertlink', content); | ||
}, | ||
tooltip: 'Insert a link' | ||
// If there is no selected text then must set the URL as | ||
// the text. Most browsers do this automatically, sadly | ||
// IE doesn't. | ||
if (!editor.getRangeHelper().selectedHtml() || text) { | ||
text = text || url; | ||
editor.wysiwygEditorInsertHtml( | ||
'<a href="' + url + '">' + text + '</a>' | ||
); | ||
} else { | ||
editor.execCommand('createlink', url); | ||
} | ||
}); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Insert a link' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Unlink | ||
unlink: { | ||
state: function () { | ||
var $current = $(this.currentNode()); | ||
return $current.is('a') || | ||
$current.parents('a').length > 0 ? 0 : -1; | ||
}, | ||
exec: function () { | ||
var $current = $(this.currentNode()), | ||
$anchor = $current.is('a') ? $current : | ||
$current.parents('a').first(); | ||
// START_COMMAND: Unlink | ||
unlink: { | ||
state: function () { | ||
return dom.closest(this.currentNode(), 'a') ? 0 : -1; | ||
}, | ||
exec: function () { | ||
var anchor = dom.closest(this.currentNode(), 'a'); | ||
if ($anchor.length) { | ||
$anchor.replaceWith($anchor.contents()); | ||
if (anchor) { | ||
while (anchor.firstChild) { | ||
dom.insertBefore(anchor.firstChild, anchor); | ||
} | ||
}, | ||
tooltip: 'Unlink' | ||
dom.remove(anchor); | ||
} | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Unlink' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Quote | ||
quote: { | ||
forceNewLineAfter: ['blockquote'], | ||
exec: function (caller, html, author) { | ||
var before = '<blockquote>', | ||
end = '</blockquote>'; | ||
// START_COMMAND: Quote | ||
quote: { | ||
exec: function (caller, html, author) { | ||
var before = '<blockquote>', | ||
end = '</blockquote>'; | ||
// if there is HTML passed set end to null so any selected | ||
// text is replaced | ||
if (html) { | ||
author = (author ? '<cite>' + author + '</cite>' : ''); | ||
before = before + author + html + end; | ||
end = null; | ||
// if not add a newline to the end of the inserted quote | ||
} else if (this.getRangeHelper().selectedHtml() === '') { | ||
end = (IE_BR_FIX ? '' : '<br />') + end; | ||
} | ||
// if there is HTML passed set end to null so any selected | ||
// text is replaced | ||
if (html) { | ||
author = (author ? '<cite>' + author + '</cite>' : ''); | ||
before = before + author + html + end; | ||
end = null; | ||
// if not add a newline to the end of the inserted quote | ||
} else if (this.getRangeHelper().selectedHtml() === '') { | ||
end = (IE_BR_FIX ? '' : '<br />') + end; | ||
} | ||
this.wysiwygEditorInsertHtml(before, end); | ||
}, | ||
tooltip: 'Insert a Quote' | ||
this.wysiwygEditorInsertHtml(before, end); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Insert a Quote' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Emoticons | ||
emoticon: { | ||
exec: function (caller) { | ||
var editor = this; | ||
// START_COMMAND: Emoticons | ||
emoticon: { | ||
exec: function (caller) { | ||
var editor = this; | ||
var createContent = function (includeMore) { | ||
var $moreLink, | ||
emoticonsCompat = editor.opts.emoticonsCompat, | ||
rangeHelper = editor.getRangeHelper(), | ||
startSpace = emoticonsCompat && | ||
rangeHelper.getOuterText(true, 1) !== ' ' ? | ||
' ' : '', | ||
endSpace = emoticonsCompat && | ||
rangeHelper.getOuterText(false, 1) !== ' ' ? | ||
' ' : '', | ||
$content = $('<div />'), | ||
$line = $('<div />').appendTo($content), | ||
perLine = 0, | ||
emoticons = $.extend( | ||
{}, | ||
editor.opts.emoticons.dropdown, | ||
includeMore ? editor.opts.emoticons.more : {} | ||
); | ||
var createContent = function (includeMore) { | ||
var moreLink, | ||
emoticonsCompat = editor.opts.emoticonsCompat, | ||
rangeHelper = editor.getRangeHelper(), | ||
startSpace = emoticonsCompat && | ||
rangeHelper.getOuterText(true, 1) !== ' ' ? ' ' : '', | ||
endSpace = emoticonsCompat && | ||
rangeHelper.getOuterText(false, 1) !== ' ' ? ' ' : '', | ||
content = dom.createElement('div'), | ||
line = dom.createElement('div'), | ||
perLine = 0, | ||
emoticons = utils.extend( | ||
{}, | ||
editor.opts.emoticons.dropdown, | ||
includeMore ? editor.opts.emoticons.more : {} | ||
); | ||
$.each(emoticons, function () { | ||
perLine++; | ||
dom.appendChild(content, line); | ||
perLine = Math.sqrt(Object.keys(emoticons).length); | ||
dom.on(content, 'click', 'img', function (e) { | ||
editor.insert(startSpace + dom.attr(this, 'alt') + endSpace, | ||
null, false).closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
utils.each(emoticons, function (code, emoticon) { | ||
dom.appendChild(line, dom.createElement('img', { | ||
src: emoticon.url || emoticon, | ||
alt: code, | ||
title: emoticon.tooltip || code | ||
})); | ||
if (line.children.length >= perLine) { | ||
line = dom.createElement('div'); | ||
dom.appendChild(content, line); | ||
} | ||
}); | ||
if (!includeMore && editor.opts.emoticons.more) { | ||
moreLink = dom.createElement('a', { | ||
className: 'sceditor-more' | ||
}); | ||
perLine = Math.sqrt(perLine); | ||
$.each(emoticons, function (code, emoticon) { | ||
$line.append( | ||
$('<img />').attr({ | ||
src: emoticon.url || emoticon, | ||
alt: code, | ||
title: emoticon.tooltip || code | ||
}).click(function () { | ||
editor.insert(startSpace + $(this).attr('alt') + | ||
endSpace, null, false).closeDropDown(true); | ||
dom.appendChild(moreLink, | ||
document.createTextNode(editor._('More'))); | ||
return false; | ||
}) | ||
dom.on(moreLink, 'click', function (e) { | ||
editor.createDropDown( | ||
caller, 'more-emoticons', createContent(true) | ||
); | ||
if ($line.children().length >= perLine) { | ||
$line = $('<div />').appendTo($content); | ||
} | ||
e.preventDefault(); | ||
}); | ||
if (!includeMore && editor.opts.emoticons.more) { | ||
$moreLink = $( | ||
'<a class="sceditor-more">' + | ||
editor._('More') + '</a>' | ||
).click(function () { | ||
editor.createDropDown( | ||
caller, | ||
'more-emoticons', | ||
createContent(true) | ||
); | ||
dom.appendChild(content, moreLink); | ||
} | ||
return false; | ||
}); | ||
return content; | ||
}; | ||
$content.append($moreLink); | ||
} | ||
return $content; | ||
}; | ||
editor.createDropDown( | ||
caller, | ||
'emoticons', | ||
createContent(false) | ||
); | ||
}, | ||
txtExec: function (caller) { | ||
defaultCommnds.emoticon.exec.call(this, caller); | ||
}, | ||
tooltip: 'Insert an emoticon' | ||
editor.createDropDown(caller, 'emoticons', createContent(false)); | ||
}, | ||
// END_COMMAND | ||
txtExec: function (caller) { | ||
defaultCmds.emoticon.exec.call(this, caller); | ||
}, | ||
tooltip: 'Insert an emoticon' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: YouTube | ||
youtube: { | ||
_dropDown: function (editor, caller, handleIdFunc) { | ||
var matches, | ||
content = _tmpl('youtubeMenu', { | ||
label: editor._('Video URL:'), | ||
insert: editor._('Insert') | ||
}, true); | ||
// START_COMMAND: YouTube | ||
youtube: { | ||
_dropDown: function (editor, caller, callback) { | ||
var content = dom.createElement('div'); | ||
content.find('.button').click(function (e) { | ||
var val = content | ||
.find('#link') | ||
.val(); | ||
dom.appendChild(content, _tmpl('youtubeMenu', { | ||
label: editor._('Video URL:'), | ||
insert: editor._('Insert') | ||
}, true)); | ||
if (val) { | ||
matches = val.match( | ||
/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/ | ||
); | ||
dom.on(content, 'click', '.button', function (e) { | ||
var val = dom.find(content, '#link')[0].value; | ||
var idMatch = val.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/); | ||
var timeMatch = val.match(/[&|?](?:star)?t=((\d+[hms]?){1,3})/); | ||
var time = 0; | ||
if (matches) { | ||
val = matches[1]; | ||
if (timeMatch) { | ||
utils.each(timeMatch[1].split(/[hms]/), function (i, val) { | ||
if (val !== '') { | ||
time = (time * 60) + Number(val); | ||
} | ||
}); | ||
} | ||
if (/^[a-zA-Z0-9_\-]{11}$/.test(val)) { | ||
handleIdFunc(val); | ||
} else { | ||
/*global alert:false*/ | ||
alert('Invalid YouTube video'); | ||
} | ||
} | ||
if (idMatch && /^[a-zA-Z0-9_\-]{11}$/.test(idMatch[1])) { | ||
callback(idMatch[1], time); | ||
} | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
editor.closeDropDown(true); | ||
e.preventDefault(); | ||
}); | ||
editor.createDropDown(caller, 'insertlink', content); | ||
}, | ||
exec: function (caller) { | ||
var editor = this; | ||
editor.createDropDown(caller, 'insertlink', content); | ||
}, | ||
exec: function (btn) { | ||
var editor = this; | ||
defaultCommnds.youtube._dropDown( | ||
editor, | ||
caller, | ||
function (id) { | ||
editor.wysiwygEditorInsertHtml(_tmpl('youtube', { | ||
id: id | ||
})); | ||
} | ||
); | ||
}, | ||
tooltip: 'Insert a YouTube video' | ||
defaultCmds.youtube._dropDown(editor, btn, function (id, time) { | ||
editor.wysiwygEditorInsertHtml(_tmpl('youtube', { | ||
id: id, | ||
time: time | ||
})); | ||
}); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Insert a YouTube video' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Date | ||
date: { | ||
_date: function (editor) { | ||
var now = new Date(), | ||
year = now.getYear(), | ||
month = now.getMonth() + 1, | ||
day = now.getDate(); | ||
// START_COMMAND: Date | ||
date: { | ||
_date: function (editor) { | ||
var now = new Date(), | ||
year = now.getYear(), | ||
month = now.getMonth() + 1, | ||
day = now.getDate(); | ||
if (year < 2000) { | ||
year = 1900 + year; | ||
} | ||
if (year < 2000) { | ||
year = 1900 + year; | ||
} | ||
if (month < 10) { | ||
month = '0' + month; | ||
} | ||
if (month < 10) { | ||
month = '0' + month; | ||
} | ||
if (day < 10) { | ||
day = '0' + day; | ||
} | ||
if (day < 10) { | ||
day = '0' + day; | ||
} | ||
return editor.opts.dateFormat | ||
.replace(/year/i, year) | ||
.replace(/month/i, month) | ||
.replace(/day/i, day); | ||
}, | ||
exec: function () { | ||
this.insertText(defaultCommnds.date._date(this)); | ||
}, | ||
txtExec: function () { | ||
this.insertText(defaultCommnds.date._date(this)); | ||
}, | ||
tooltip: 'Insert current date' | ||
return editor.opts.dateFormat | ||
.replace(/year/i, year) | ||
.replace(/month/i, month) | ||
.replace(/day/i, day); | ||
}, | ||
// END_COMMAND | ||
exec: function () { | ||
this.insertText(defaultCmds.date._date(this)); | ||
}, | ||
txtExec: function () { | ||
this.insertText(defaultCmds.date._date(this)); | ||
}, | ||
tooltip: 'Insert current date' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Time | ||
time: { | ||
_time: function () { | ||
var now = new Date(), | ||
hours = now.getHours(), | ||
mins = now.getMinutes(), | ||
secs = now.getSeconds(); | ||
// START_COMMAND: Time | ||
time: { | ||
_time: function () { | ||
var now = new Date(), | ||
hours = now.getHours(), | ||
mins = now.getMinutes(), | ||
secs = now.getSeconds(); | ||
if (hours < 10) { | ||
hours = '0' + hours; | ||
} | ||
if (hours < 10) { | ||
hours = '0' + hours; | ||
} | ||
if (mins < 10) { | ||
mins = '0' + mins; | ||
} | ||
if (mins < 10) { | ||
mins = '0' + mins; | ||
} | ||
if (secs < 10) { | ||
secs = '0' + secs; | ||
} | ||
if (secs < 10) { | ||
secs = '0' + secs; | ||
} | ||
return hours + ':' + mins + ':' + secs; | ||
}, | ||
exec: function () { | ||
this.insertText(defaultCommnds.time._time()); | ||
}, | ||
txtExec: function () { | ||
this.insertText(defaultCommnds.time._time()); | ||
}, | ||
tooltip: 'Insert current time' | ||
return hours + ':' + mins + ':' + secs; | ||
}, | ||
// END_COMMAND | ||
exec: function () { | ||
this.insertText(defaultCmds.time._time()); | ||
}, | ||
txtExec: function () { | ||
this.insertText(defaultCmds.time._time()); | ||
}, | ||
tooltip: 'Insert current time' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Ltr | ||
ltr: { | ||
state: function (parents, firstBlock) { | ||
return firstBlock && firstBlock.style.direction === 'ltr'; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
elm = editor.getRangeHelper().getFirstBlockParent(), | ||
$elm = $(elm); | ||
// START_COMMAND: Ltr | ||
ltr: { | ||
state: function (parents, firstBlock) { | ||
return firstBlock && firstBlock.style.direction === 'ltr'; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
rangeHelper = editor.getRangeHelper(), | ||
node = rangeHelper.getFirstBlockParent(); | ||
editor.focus(); | ||
editor.focus(); | ||
if (!elm || $elm.is('body')) { | ||
editor.execCommand('formatBlock', 'p'); | ||
if (!node || dom.is(node, 'body')) { | ||
editor.execCommand('formatBlock', 'p'); | ||
elm = editor.getRangeHelper().getFirstBlockParent(); | ||
$elm = $(elm); | ||
node = rangeHelper.getFirstBlockParent(); | ||
if (!elm || $elm.is('body')) { | ||
return; | ||
} | ||
if (!node || dom.is(node, 'body')) { | ||
return; | ||
} | ||
} | ||
if ($elm.css('direction') === 'ltr') { | ||
$elm.css('direction', ''); | ||
} else { | ||
$elm.css('direction', 'ltr'); | ||
} | ||
}, | ||
tooltip: 'Left-to-Right' | ||
var toggleValue = dom.css(node, 'direction') === 'ltr' ? '' : 'ltr'; | ||
dom.css(node, 'direction', toggleValue); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Left-to-Right' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Rtl | ||
rtl: { | ||
state: function (parents, firstBlock) { | ||
return firstBlock && firstBlock.style.direction === 'rtl'; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
elm = editor.getRangeHelper().getFirstBlockParent(), | ||
$elm = $(elm); | ||
// START_COMMAND: Rtl | ||
rtl: { | ||
state: function (parents, firstBlock) { | ||
return firstBlock && firstBlock.style.direction === 'rtl'; | ||
}, | ||
exec: function () { | ||
var editor = this, | ||
rangeHelper = editor.getRangeHelper(), | ||
node = rangeHelper.getFirstBlockParent(); | ||
editor.focus(); | ||
editor.focus(); | ||
if (!elm || $elm.is('body')) { | ||
editor.execCommand('formatBlock', 'p'); | ||
if (!node || dom.is(node, 'body')) { | ||
editor.execCommand('formatBlock', 'p'); | ||
elm = editor.getRangeHelper().getFirstBlockParent(); | ||
$elm = $(elm); | ||
node = rangeHelper.getFirstBlockParent(); | ||
if (!elm || $elm.is('body')) { | ||
return; | ||
} | ||
if (!node || dom.is(node, 'body')) { | ||
return; | ||
} | ||
} | ||
if ($elm.css('direction') === 'rtl') { | ||
$elm.css('direction', ''); | ||
} else { | ||
$elm.css('direction', 'rtl'); | ||
} | ||
}, | ||
tooltip: 'Right-to-Left' | ||
var toggleValue = dom.css(node, 'direction') === 'rtl' ? '' : 'rtl'; | ||
dom.css(node, 'direction', toggleValue); | ||
}, | ||
// END_COMMAND | ||
tooltip: 'Right-to-Left' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Print | ||
print: { | ||
exec: 'print', | ||
tooltip: 'Print' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Print | ||
print: { | ||
exec: 'print', | ||
tooltip: 'Print' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Maximize | ||
maximize: { | ||
state: function () { | ||
return this.maximize(); | ||
}, | ||
exec: function () { | ||
this.maximize(!this.maximize()); | ||
}, | ||
txtExec: function () { | ||
this.maximize(!this.maximize()); | ||
}, | ||
tooltip: 'Maximize', | ||
shortcut: 'Ctrl+Shift+M' | ||
// START_COMMAND: Maximize | ||
maximize: { | ||
state: function () { | ||
return this.maximize(); | ||
}, | ||
// END_COMMAND | ||
exec: function () { | ||
this.maximize(!this.maximize()); | ||
}, | ||
txtExec: function () { | ||
this.maximize(!this.maximize()); | ||
}, | ||
tooltip: 'Maximize', | ||
shortcut: 'Ctrl+Shift+M' | ||
}, | ||
// END_COMMAND | ||
// START_COMMAND: Source | ||
source: { | ||
state: function () { | ||
return this.sourceMode(); | ||
}, | ||
exec: function () { | ||
this.toggleSourceMode(); | ||
}, | ||
txtExec: function () { | ||
this.toggleSourceMode(); | ||
}, | ||
tooltip: 'View source', | ||
shortcut: 'Ctrl+Shift+S' | ||
// START_COMMAND: Source | ||
source: { | ||
state: function () { | ||
return this.sourceMode(); | ||
}, | ||
// END_COMMAND | ||
exec: function () { | ||
this.toggleSourceMode(); | ||
}, | ||
txtExec: function () { | ||
this.toggleSourceMode(); | ||
}, | ||
tooltip: 'View source', | ||
shortcut: 'Ctrl+Shift+S' | ||
}, | ||
// END_COMMAND | ||
// this is here so that commands above can be removed | ||
// without having to remove the , after the last one. | ||
// Needed for IE. | ||
ignore: {} | ||
}; | ||
// this is here so that commands above can be removed | ||
// without having to remove the , after the last one. | ||
// Needed for IE. | ||
ignore: {} | ||
}; | ||
return defaultCommnds; | ||
}); | ||
export default defaultCmds; |
@@ -1,359 +0,361 @@ | ||
define(function (require) { | ||
'use strict'; | ||
import { attr } from './dom'; | ||
var $ = require('jquery'); | ||
/** | ||
* Default options for SCEditor | ||
* @type {Object} | ||
*/ | ||
export default { | ||
/** @lends jQuery.sceditor.defaultOptions */ | ||
/** | ||
* Toolbar buttons order and groups. Should be comma separated and | ||
* have a bar | to separate groups | ||
* | ||
* @type {string} | ||
*/ | ||
toolbar: 'bold,italic,underline,strike,subscript,superscript|' + | ||
'left,center,right,justify|font,size,color,removeformat|' + | ||
'cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|' + | ||
'table|code,quote|horizontalrule,image,email,link,unlink|' + | ||
'emoticon,youtube,date,time|ltr,rtl|print,maximize,source', | ||
/** | ||
* Comma separated list of commands to excludes from the toolbar | ||
* | ||
* @type {string} | ||
*/ | ||
toolbarExclude: null, | ||
/** | ||
* Default options for SCEditor | ||
* @type {Object} | ||
* Stylesheet to include in the WYSIWYG editor. This is what will style | ||
* the WYSIWYG elements | ||
* | ||
* @type {string} | ||
*/ | ||
return { | ||
/** @lends jQuery.sceditor.defaultOptions */ | ||
/** | ||
* Toolbar buttons order and groups. Should be comma separated and | ||
* have a bar | to separate groups | ||
* | ||
* @type {String} | ||
*/ | ||
toolbar: 'bold,italic,underline,strike,subscript,superscript|' + | ||
'left,center,right,justify|font,size,color,removeformat|' + | ||
'cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|' + | ||
'table|code,quote|horizontalrule,image,email,link,unlink|' + | ||
'emoticon,youtube,date,time|ltr,rtl|print,maximize,source', | ||
style: 'jquery.sceditor.default.css', | ||
/** | ||
* Comma separated list of commands to excludes from the toolbar | ||
* | ||
* @type {String} | ||
*/ | ||
toolbarExclude: null, | ||
/** | ||
* Comma separated list of fonts for the font selector | ||
* | ||
* @type {string} | ||
*/ | ||
fonts: 'Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,' + | ||
'Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana', | ||
/** | ||
* Stylesheet to include in the WYSIWYG editor. This is what will style | ||
* the WYSIWYG elements | ||
* | ||
* @type {String} | ||
*/ | ||
style: 'jquery.sceditor.default.css', | ||
/** | ||
* Colors should be comma separated and have a bar | to signal a new | ||
* column. | ||
* | ||
* If null the colors will be auto generated. | ||
* | ||
* @type {string} | ||
*/ | ||
colors: '#000000,#44B8FF,#1E92F7,#0074D9,#005DC2,#00369B,#b3d5f4|' + | ||
'#444444,#C3FFFF,#9DF9FF,#7FDBFF,#68C4E8,#419DC1,#d9f4ff|' + | ||
'#666666,#72FF84,#4CEA5E,#2ECC40,#17B529,#008E02,#c0f0c6|' + | ||
'#888888,#FFFF44,#FFFA1E,#FFDC00,#E8C500,#C19E00,#fff5b3|' + | ||
'#aaaaaa,#FFC95F,#FFA339,#FF851B,#E86E04,#C14700,#ffdbbb|' + | ||
'#cccccc,#FF857A,#FF5F54,#FF4136,#E82A1F,#C10300,#ffc6c3|' + | ||
'#eeeeee,#FF56FF,#FF30DC,#F012BE,#D900A7,#B20080,#fbb8ec|' + | ||
'#ffffff,#F551FF,#CF2BE7,#B10DC9,#9A00B2,#9A00B2,#e8b6ef', | ||
/** | ||
* Comma separated list of fonts for the font selector | ||
* | ||
* @type {String} | ||
*/ | ||
fonts: 'Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,' + | ||
'Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana', | ||
/** | ||
* The locale to use. | ||
* @type {string} | ||
*/ | ||
locale: attr(document.documentElement, 'lang') || 'en', | ||
/** | ||
* Colors should be comma separated and have a bar | to signal a new | ||
* column. | ||
* | ||
* If null the colors will be auto generated. | ||
* | ||
* @type {string} | ||
*/ | ||
colors: null, | ||
/** | ||
* The Charset to use | ||
* @type {string} | ||
*/ | ||
charset: 'utf-8', | ||
/** | ||
* The locale to use. | ||
* @type {String} | ||
*/ | ||
locale: $('html').attr('lang') || 'en', | ||
/** | ||
* Compatibility mode for emoticons. | ||
* | ||
* Helps if you have emoticons such as :/ which would put an emoticon | ||
* inside http:// | ||
* | ||
* This mode requires emoticons to be surrounded by whitespace or end of | ||
* line chars. This mode has limited As You Type emoticon conversion | ||
* support. It will not replace AYT for end of line chars, only | ||
* emoticons surrounded by whitespace. They will still be replaced | ||
* correctly when loaded just not AYT. | ||
* | ||
* @type {boolean} | ||
*/ | ||
emoticonsCompat: false, | ||
/** | ||
* The Charset to use | ||
* @type {String} | ||
*/ | ||
charset: 'utf-8', | ||
/** | ||
* If to enable emoticons. Can be changes at runtime using the | ||
* emoticons() method. | ||
* | ||
* @type {boolean} | ||
* @since 1.4.2 | ||
*/ | ||
emoticonsEnabled: true, | ||
/** | ||
* Compatibility mode for emoticons. | ||
* | ||
* Helps if you have emoticons such as :/ which would put an emoticon | ||
* inside http:// | ||
* | ||
* This mode requires emoticons to be surrounded by whitespace or end of | ||
* line chars. This mode has limited As You Type emoticon conversion | ||
* support. It will not replace AYT for end of line chars, only | ||
* emoticons surrounded by whitespace. They will still be replaced | ||
* correctly when loaded just not AYT. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
emoticonsCompat: false, | ||
/** | ||
* If to enable emoticons. Can be changes at runtime using the | ||
* emoticons() method. | ||
* | ||
* @type {Boolean} | ||
* @since 1.4.2 | ||
*/ | ||
emoticonsEnabled: true, | ||
/** | ||
* Emoticon root URL | ||
* | ||
* @type {String} | ||
*/ | ||
emoticonsRoot: '', | ||
emoticons: { | ||
dropdown: { | ||
':)': 'emoticons/smile.png', | ||
':angel:': 'emoticons/angel.png', | ||
':angry:': 'emoticons/angry.png', | ||
'8-)': 'emoticons/cool.png', | ||
':\'(': 'emoticons/cwy.png', | ||
':ermm:': 'emoticons/ermm.png', | ||
':D': 'emoticons/grin.png', | ||
'<3': 'emoticons/heart.png', | ||
':(': 'emoticons/sad.png', | ||
':O': 'emoticons/shocked.png', | ||
':P': 'emoticons/tongue.png', | ||
';)': 'emoticons/wink.png' | ||
}, | ||
more: { | ||
':alien:': 'emoticons/alien.png', | ||
':blink:': 'emoticons/blink.png', | ||
':blush:': 'emoticons/blush.png', | ||
':cheerful:': 'emoticons/cheerful.png', | ||
':devil:': 'emoticons/devil.png', | ||
':dizzy:': 'emoticons/dizzy.png', | ||
':getlost:': 'emoticons/getlost.png', | ||
':happy:': 'emoticons/happy.png', | ||
':kissing:': 'emoticons/kissing.png', | ||
':ninja:': 'emoticons/ninja.png', | ||
':pinch:': 'emoticons/pinch.png', | ||
':pouty:': 'emoticons/pouty.png', | ||
':sick:': 'emoticons/sick.png', | ||
':sideways:': 'emoticons/sideways.png', | ||
':silly:': 'emoticons/silly.png', | ||
':sleeping:': 'emoticons/sleeping.png', | ||
':unsure:': 'emoticons/unsure.png', | ||
':woot:': 'emoticons/w00t.png', | ||
':wassat:': 'emoticons/wassat.png' | ||
}, | ||
hidden: { | ||
':whistling:': 'emoticons/whistling.png', | ||
':love:': 'emoticons/wub.png' | ||
} | ||
/** | ||
* Emoticon root URL | ||
* | ||
* @type {string} | ||
*/ | ||
emoticonsRoot: '', | ||
emoticons: { | ||
dropdown: { | ||
':)': 'emoticons/smile.png', | ||
':angel:': 'emoticons/angel.png', | ||
':angry:': 'emoticons/angry.png', | ||
'8-)': 'emoticons/cool.png', | ||
':\'(': 'emoticons/cwy.png', | ||
':ermm:': 'emoticons/ermm.png', | ||
':D': 'emoticons/grin.png', | ||
'<3': 'emoticons/heart.png', | ||
':(': 'emoticons/sad.png', | ||
':O': 'emoticons/shocked.png', | ||
':P': 'emoticons/tongue.png', | ||
';)': 'emoticons/wink.png' | ||
}, | ||
more: { | ||
':alien:': 'emoticons/alien.png', | ||
':blink:': 'emoticons/blink.png', | ||
':blush:': 'emoticons/blush.png', | ||
':cheerful:': 'emoticons/cheerful.png', | ||
':devil:': 'emoticons/devil.png', | ||
':dizzy:': 'emoticons/dizzy.png', | ||
':getlost:': 'emoticons/getlost.png', | ||
':happy:': 'emoticons/happy.png', | ||
':kissing:': 'emoticons/kissing.png', | ||
':ninja:': 'emoticons/ninja.png', | ||
':pinch:': 'emoticons/pinch.png', | ||
':pouty:': 'emoticons/pouty.png', | ||
':sick:': 'emoticons/sick.png', | ||
':sideways:': 'emoticons/sideways.png', | ||
':silly:': 'emoticons/silly.png', | ||
':sleeping:': 'emoticons/sleeping.png', | ||
':unsure:': 'emoticons/unsure.png', | ||
':woot:': 'emoticons/w00t.png', | ||
':wassat:': 'emoticons/wassat.png' | ||
}, | ||
hidden: { | ||
':whistling:': 'emoticons/whistling.png', | ||
':love:': 'emoticons/wub.png' | ||
} | ||
}, | ||
/** | ||
* Width of the editor. Set to null for automatic with | ||
* | ||
* @type {int} | ||
*/ | ||
width: null, | ||
/** | ||
* Width of the editor. Set to null for automatic with | ||
* | ||
* @type {?number} | ||
*/ | ||
width: null, | ||
/** | ||
* Height of the editor including toolbar. Set to null for automatic | ||
* height | ||
* | ||
* @type {int} | ||
*/ | ||
height: null, | ||
/** | ||
* Height of the editor including toolbar. Set to null for automatic | ||
* height | ||
* | ||
* @type {?number} | ||
*/ | ||
height: null, | ||
/** | ||
* If to allow the editor to be resized | ||
* | ||
* @type {Boolean} | ||
*/ | ||
resizeEnabled: true, | ||
/** | ||
* If to allow the editor to be resized | ||
* | ||
* @type {boolean} | ||
*/ | ||
resizeEnabled: true, | ||
/** | ||
* Min resize to width, set to null for half textarea width or -1 for | ||
* unlimited | ||
* | ||
* @type {int} | ||
*/ | ||
resizeMinWidth: null, | ||
/** | ||
* Min resize to height, set to null for half textarea height or -1 for | ||
* unlimited | ||
* | ||
* @type {int} | ||
*/ | ||
resizeMinHeight: null, | ||
/** | ||
* Max resize to height, set to null for double textarea height or -1 | ||
* for unlimited | ||
* | ||
* @type {int} | ||
*/ | ||
resizeMaxHeight: null, | ||
/** | ||
* Max resize to width, set to null for double textarea width or -1 for | ||
* unlimited | ||
* | ||
* @type {int} | ||
*/ | ||
resizeMaxWidth: null, | ||
/** | ||
* If resizing by height is enabled | ||
* | ||
* @type {Boolean} | ||
*/ | ||
resizeHeight: true, | ||
/** | ||
* If resizing by width is enabled | ||
* | ||
* @type {Boolean} | ||
*/ | ||
resizeWidth: true, | ||
/** | ||
* Min resize to width, set to null for half textarea width or -1 for | ||
* unlimited | ||
* | ||
* @type {?number} | ||
*/ | ||
resizeMinWidth: null, | ||
/** | ||
* Min resize to height, set to null for half textarea height or -1 for | ||
* unlimited | ||
* | ||
* @type {?number} | ||
*/ | ||
resizeMinHeight: null, | ||
/** | ||
* Max resize to height, set to null for double textarea height or -1 | ||
* for unlimited | ||
* | ||
* @type {?number} | ||
*/ | ||
resizeMaxHeight: null, | ||
/** | ||
* Max resize to width, set to null for double textarea width or -1 for | ||
* unlimited | ||
* | ||
* @type {?number} | ||
*/ | ||
resizeMaxWidth: null, | ||
/** | ||
* If resizing by height is enabled | ||
* | ||
* @type {boolean} | ||
*/ | ||
resizeHeight: true, | ||
/** | ||
* If resizing by width is enabled | ||
* | ||
* @type {boolean} | ||
*/ | ||
resizeWidth: true, | ||
/** | ||
* Date format, will be overridden if locale specifies one. | ||
* | ||
* The words year, month and day will be replaced with the users current | ||
* year, month and day. | ||
* | ||
* @type {String} | ||
*/ | ||
dateFormat: 'year-month-day', | ||
/** | ||
* Date format, will be overridden if locale specifies one. | ||
* | ||
* The words year, month and day will be replaced with the users current | ||
* year, month and day. | ||
* | ||
* @type {string} | ||
*/ | ||
dateFormat: 'year-month-day', | ||
/** | ||
* Element to inset the toolbar into. | ||
* | ||
* @type {HTMLElement} | ||
*/ | ||
toolbarContainer: null, | ||
/** | ||
* Element to inset the toolbar into. | ||
* | ||
* @type {HTMLElement} | ||
*/ | ||
toolbarContainer: null, | ||
/** | ||
* If to enable paste filtering. This is currently experimental, please | ||
* report any issues. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
enablePasteFiltering: false, | ||
/** | ||
* If to enable paste filtering. This is currently experimental, please | ||
* report any issues. | ||
* | ||
* @type {boolean} | ||
*/ | ||
enablePasteFiltering: false, | ||
/** | ||
* If to completely disable pasting into the editor | ||
* | ||
* @type {Boolean} | ||
*/ | ||
disablePasting: false, | ||
/** | ||
* If to completely disable pasting into the editor | ||
* | ||
* @type {boolean} | ||
*/ | ||
disablePasting: false, | ||
/** | ||
* If the editor is read only. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
readOnly: false, | ||
/** | ||
* If the editor is read only. | ||
* | ||
* @type {boolean} | ||
*/ | ||
readOnly: false, | ||
/** | ||
* If to set the editor to right-to-left mode. | ||
* | ||
* If set to null the direction will be automatically detected. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
rtl: false, | ||
/** | ||
* If to set the editor to right-to-left mode. | ||
* | ||
* If set to null the direction will be automatically detected. | ||
* | ||
* @type {boolean} | ||
*/ | ||
rtl: false, | ||
/** | ||
* If to auto focus the editor on page load | ||
* | ||
* @type {Boolean} | ||
*/ | ||
autofocus: false, | ||
/** | ||
* If to auto focus the editor on page load | ||
* | ||
* @type {boolean} | ||
*/ | ||
autofocus: false, | ||
/** | ||
* If to auto focus the editor to the end of the content | ||
* | ||
* @type {Boolean} | ||
*/ | ||
autofocusEnd: true, | ||
/** | ||
* If to auto focus the editor to the end of the content | ||
* | ||
* @type {boolean} | ||
*/ | ||
autofocusEnd: true, | ||
/** | ||
* If to auto expand the editor to fix the content | ||
* | ||
* @type {Boolean} | ||
*/ | ||
autoExpand: false, | ||
/** | ||
* If to auto expand the editor to fix the content | ||
* | ||
* @type {boolean} | ||
*/ | ||
autoExpand: false, | ||
/** | ||
* If to auto update original textbox on blur | ||
* | ||
* @type {Boolean} | ||
*/ | ||
autoUpdate: false, | ||
/** | ||
* If to auto update original textbox on blur | ||
* | ||
* @type {boolean} | ||
*/ | ||
autoUpdate: false, | ||
/** | ||
* If to enable the browsers built in spell checker | ||
* | ||
* @type {Boolean} | ||
*/ | ||
spellcheck: true, | ||
/** | ||
* If to enable the browsers built in spell checker | ||
* | ||
* @type {boolean} | ||
*/ | ||
spellcheck: true, | ||
/** | ||
* If to run the source editor when there is no WYSIWYG support. Only | ||
* really applies to mobile OS's. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
runWithoutWysiwygSupport: false, | ||
/** | ||
* If to run the source editor when there is no WYSIWYG support. Only | ||
* really applies to mobile OS's. | ||
* | ||
* @type {boolean} | ||
*/ | ||
runWithoutWysiwygSupport: false, | ||
/** | ||
* If to load the editor in source mode and still allow switching | ||
* between WYSIWYG and source mode | ||
* | ||
* @type {Boolean} | ||
*/ | ||
startInSourceMode: false, | ||
/** | ||
* If to load the editor in source mode and still allow switching | ||
* between WYSIWYG and source mode | ||
* | ||
* @type {boolean} | ||
*/ | ||
startInSourceMode: false, | ||
/** | ||
* Optional ID to give the editor. | ||
* | ||
* @type {String} | ||
*/ | ||
id: null, | ||
/** | ||
* Optional ID to give the editor. | ||
* | ||
* @type {string} | ||
*/ | ||
id: null, | ||
/** | ||
* Comma separated list of plugins | ||
* | ||
* @type {String} | ||
*/ | ||
plugins: '', | ||
/** | ||
* Comma separated list of plugins | ||
* | ||
* @type {string} | ||
*/ | ||
plugins: '', | ||
/** | ||
* z-index to set the editor container to. Needed for jQuery UI dialog. | ||
* | ||
* @type {Int} | ||
*/ | ||
zIndex: null, | ||
/** | ||
* z-index to set the editor container to. Needed for jQuery UI dialog. | ||
* | ||
* @type {?number} | ||
*/ | ||
zIndex: null, | ||
/** | ||
* If to trim the BBCode. Removes any spaces at the start and end of the | ||
* BBCode string. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
bbcodeTrim: false, | ||
/** | ||
* If to trim the BBCode. Removes any spaces at the start and end of the | ||
* BBCode string. | ||
* | ||
* @type {boolean} | ||
*/ | ||
bbcodeTrim: false, | ||
/** | ||
* If to disable removing block level elements by pressing backspace at | ||
* the start of them | ||
* | ||
* @type {Boolean} | ||
*/ | ||
disableBlockRemove: false, | ||
/** | ||
* If to disable removing block level elements by pressing backspace at | ||
* the start of them | ||
* | ||
* @type {boolean} | ||
*/ | ||
disableBlockRemove: false, | ||
/** | ||
* BBCode parser options, only applies if using the editor in BBCode | ||
* mode. | ||
* | ||
* See SCEditor.BBCodeParser.defaults for list of valid options | ||
* | ||
* @type {Object} | ||
*/ | ||
parserOptions: { }, | ||
/** | ||
* BBCode parser options, only applies if using the editor in BBCode | ||
* mode. | ||
* | ||
* See SCEditor.BBCodeParser.defaults for list of valid options | ||
* | ||
* @type {Object} | ||
*/ | ||
parserOptions: { }, | ||
/** | ||
* CSS that will be added to the to dropdown menu (eg. z-index) | ||
* | ||
* @type {Object} | ||
*/ | ||
dropDownCss: { } | ||
}; | ||
}); | ||
/** | ||
* CSS that will be added to the to dropdown menu (eg. z-index) | ||
* | ||
* @type {Object} | ||
*/ | ||
dropDownCss: { } | ||
}; |
1367
src/lib/dom.js
@@ -1,502 +0,1031 @@ | ||
define(function (require) { | ||
'use strict'; | ||
import * as utils from './utils.js'; | ||
var $ = require('jquery'); | ||
var browser = require('./browser'); | ||
/** | ||
* Cache of camelCase CSS property names | ||
* @type {Object<string, string>} | ||
*/ | ||
var cssPropertyNameCache = {}; | ||
var _propertyNameCache = {}; | ||
/** | ||
* Node type constant for element nodes | ||
* | ||
* @type {number} | ||
*/ | ||
export var ELEMENT_NODE = 1; | ||
var dom = { | ||
/** | ||
* Loop all child nodes of the passed node | ||
* | ||
* The function should accept 1 parameter being the node. | ||
* If the function returns false the loop will be exited. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {Function} func Callback which is called with every | ||
* child node as the first argument. | ||
* @param {bool} innermostFirst If the innermost node should be passed | ||
* to the function before it's parents. | ||
* @param {bool} siblingsOnly If to only traverse the nodes siblings | ||
* @param {bool} reverse If to traverse the nodes in reverse | ||
*/ | ||
/*jshint maxparams: false*/ | ||
traverse: function (node, func, innermostFirst, siblingsOnly, reverse) { | ||
if (node) { | ||
node = reverse ? node.lastChild : node.firstChild; | ||
/** | ||
* Node type constant for text nodes | ||
* | ||
* @type {number} | ||
*/ | ||
export var TEXT_NODE = 3; | ||
while (node) { | ||
var next = reverse ? | ||
node.previousSibling : | ||
node.nextSibling; | ||
/** | ||
* Node type constant for comment nodes | ||
* | ||
* @type {number} | ||
*/ | ||
export var COMMENT_NODE = 8; | ||
if ( | ||
(!innermostFirst && func(node) === false) || | ||
(!siblingsOnly && dom.traverse( | ||
node, func, innermostFirst, siblingsOnly, reverse | ||
) === false) || | ||
(innermostFirst && func(node) === false) | ||
) { | ||
return false; | ||
} | ||
/** | ||
* Node type document nodes | ||
* | ||
* @type {number} | ||
*/ | ||
export var DOCUMENT_NODE = 9; | ||
// move to next child | ||
node = next; | ||
} | ||
} | ||
}, | ||
/** | ||
* Node type constant for document fragments | ||
* | ||
* @type {number} | ||
*/ | ||
export var DOCUMENT_FRAGMENT_NODE = 11; | ||
/** | ||
* Like traverse but loops in reverse | ||
* @see traverse | ||
*/ | ||
rTraverse: function (node, func, innermostFirst, siblingsOnly) { | ||
this.traverse(node, func, innermostFirst, siblingsOnly, true); | ||
}, | ||
function toFloat(value) { | ||
value = parseFloat(value); | ||
/** | ||
* Parses HTML | ||
* | ||
* @param {String} html | ||
* @param {Document} context | ||
* @since 1.4.4 | ||
* @return {Array} | ||
*/ | ||
parseHTML: function (html, context) { | ||
var ret = [], | ||
tmp = (context || document).createElement('div'); | ||
return isFinite(value) ? value : 0; | ||
} | ||
tmp.innerHTML = html; | ||
/** | ||
* Creates an element with the specified attributes | ||
* | ||
* Will create it in the current document unless context | ||
* is specified. | ||
* | ||
* @param {!string} tag | ||
* @param {!Object<string, string>} [attributes] | ||
* @param {!Document} [context] | ||
* @returns {!HTMLElement} | ||
*/ | ||
export function createElement(tag, attributes, context) { | ||
var node = (context || document).createElement(tag); | ||
$.merge(ret, tmp.childNodes); | ||
utils.each(attributes || {}, function (key, value) { | ||
if (key === 'style') { | ||
node.style.cssText = value; | ||
} else if (key in node) { | ||
node[key] = value; | ||
} else { | ||
node.setAttribute(key, value); | ||
} | ||
}); | ||
return ret; | ||
}, | ||
return node; | ||
} | ||
/** | ||
* Checks if an element has any styling. | ||
* | ||
* It has styling if it is not a plain <div> or <p> or | ||
* if it has a class, style attribute or data. | ||
* | ||
* @param {HTMLElement} elm | ||
* @return {Boolean} | ||
* @since 1.4.4 | ||
*/ | ||
hasStyling: function (elm) { | ||
var $elm = $(elm); | ||
/** | ||
* Returns an array of parents that matches the selector | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} [selector] | ||
* @returns {Array<HTMLElement>} | ||
*/ | ||
export function parents(node, selector) { | ||
var parents = []; | ||
var parent = node || {}; | ||
return elm && (!$elm.is('p,div') || elm.className || | ||
$elm.attr('style') || !$.isEmptyObject($elm.data())); | ||
}, | ||
while ((parent = parent.parentNode) && !/(9|11)/.test(parent.nodeType)) { | ||
if (!selector || is(parent, selector)) { | ||
parents.push(parent); | ||
} | ||
} | ||
/** | ||
* Converts an element from one type to another. | ||
* | ||
* For example it can convert the element <b> to <strong> | ||
* | ||
* @param {HTMLElement} oldElm | ||
* @param {String} toTagName | ||
* @return {HTMLElement} | ||
* @since 1.4.4 | ||
*/ | ||
convertElement: function (oldElm, toTagName) { | ||
var child, attr, | ||
oldAttrs = oldElm.attributes, | ||
attrsIdx = oldAttrs.length, | ||
newElm = oldElm.ownerDocument.createElement(toTagName); | ||
return parents; | ||
} | ||
while (attrsIdx--) { | ||
attr = oldAttrs[attrsIdx]; | ||
/** | ||
* Gets the first parent node that matches the selector | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} [selector] | ||
* @returns {HTMLElement|undefined} | ||
*/ | ||
export function parent(node, selector) { | ||
var parent = node || {}; | ||
// IE < 8 returns all possible attributes instead of just | ||
// the specified ones so have to check it is specified. | ||
if (!browser.ie || attr.specified) { | ||
// IE < 8 doesn't return the CSS for the style attribute | ||
// so must copy it manually | ||
if (browser.ie < 8 && /style/i.test(attr.name)) { | ||
dom.copyCSS(oldElm, newElm); | ||
} else { | ||
// Some browsers parse invalid attributes names like | ||
// 'size"2' which throw an exception when set, just | ||
// ignore these. | ||
try { | ||
newElm.setAttribute(attr.name, attr.value); | ||
} catch (ex) {} | ||
while ((parent = parent.parentNode) && !/(9|11)/.test(parent.nodeType)) { | ||
if (!selector || is(parent, selector)) { | ||
return parent; | ||
} | ||
} | ||
} | ||
/** | ||
* Checks the passed node and all parents and | ||
* returns the first matching node if any. | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} selector | ||
* @returns {HTMLElement|undefined} | ||
*/ | ||
export function closest(node, selector) { | ||
return is(node, selector) ? node : parent(node, selector); | ||
} | ||
/** | ||
* Removes the node from the DOM | ||
* | ||
* @param {!HTMLElement} node | ||
*/ | ||
export function remove(node) { | ||
node.parentNode.removeChild(node); | ||
} | ||
/** | ||
* Appends child to parent node | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!HTMLElement} child | ||
*/ | ||
export function appendChild(node, child) { | ||
node.appendChild(child); | ||
} | ||
/** | ||
* Finds any child nodes that match the selector | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} selector | ||
* @returns {NodeList} | ||
*/ | ||
export function find(node, selector) { | ||
return node.querySelectorAll(selector); | ||
} | ||
/** | ||
* For on() and off() if to add/remove the event | ||
* to the capture phase | ||
* | ||
* @type {boolean} | ||
*/ | ||
export var EVENT_CAPTURE = true; | ||
/** | ||
* For on() and off() if to add/remove the event | ||
* to the bubble phase | ||
* | ||
* @type {boolean} | ||
*/ | ||
export var EVENT_BUBBLE = false; | ||
/** | ||
* Adds an event listener for the specified events. | ||
* | ||
* Events should be a space separated list of events. | ||
* | ||
* If selector is specified the handler will only be | ||
* called when the event target matches the selector. | ||
* | ||
* @param {!Node} node | ||
* @param {string} events | ||
* @param {string} [selector] | ||
* @param {function(Object)} fn | ||
* @param {boolean} [capture=false] | ||
* @see off() | ||
*/ | ||
// eslint-disable-next-line max-params | ||
export function on(node, events, selector, fn, capture) { | ||
events.split(' ').forEach(function (event) { | ||
var handler; | ||
if (utils.isString(selector)) { | ||
handler = fn['_sce-event-' + event + selector] || function (e) { | ||
var target = e.target; | ||
while (target && target !== node) { | ||
if (is(target, selector)) { | ||
fn.call(target, e); | ||
return; | ||
} | ||
target = target.parentNode; | ||
} | ||
} | ||
}; | ||
while ((child = oldElm.firstChild)) { | ||
newElm.appendChild(child); | ||
} | ||
fn['_sce-event-' + event + selector] = handler; | ||
} else { | ||
handler = selector; | ||
capture = fn; | ||
} | ||
oldElm.parentNode.replaceChild(newElm, oldElm); | ||
node.addEventListener(event, handler, capture || false); | ||
}); | ||
} | ||
return newElm; | ||
}, | ||
/** | ||
* Removes an event listener for the specified events. | ||
* | ||
* @param {!Node} node | ||
* @param {string} events | ||
* @param {string} [selector] | ||
* @param {function(Object)} fn | ||
* @param {boolean} [capture=false] | ||
* @see on() | ||
*/ | ||
// eslint-disable-next-line max-params | ||
export function off(node, events, selector, fn, capture) { | ||
events.split(' ').forEach(function (event) { | ||
var handler; | ||
/** | ||
* List of block level elements separated by bars (|) | ||
* @type {string} | ||
*/ | ||
blockLevelList: '|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|' + | ||
'table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|', | ||
if (utils.isString(selector)) { | ||
handler = fn['_sce-event-' + event + selector]; | ||
} else { | ||
handler = selector; | ||
capture = fn; | ||
} | ||
/** | ||
* List of elements that do not allow children separated by bars (|) | ||
* | ||
* @param {Node} node | ||
* @return {bool} | ||
* @since 1.4.5 | ||
*/ | ||
canHaveChildren: function (node) { | ||
// 1 = Element | ||
// 9 = Document | ||
// 11 = Document Fragment | ||
if (!/11?|9/.test(node.nodeType)) { | ||
return false; | ||
} | ||
node.removeEventListener(event, handler, capture || false); | ||
}); | ||
} | ||
// List of empty HTML tags separated by bar (|) character. | ||
// Source: http://www.w3.org/TR/html4/index/elements.html | ||
// Source: http://www.w3.org/TR/html5/syntax.html#void-elements | ||
return ('|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr' + | ||
'|isindex|link|meta|param|command|embed|keygen|source|track|' + | ||
'object|').indexOf('|' + node.nodeName.toLowerCase() + '|') < 0; | ||
}, | ||
/** | ||
* If only attr param is specified it will get | ||
* the value of the attr param. | ||
* | ||
* If value is specified but null the attribute | ||
* will be removed otherwise the attr value will | ||
* be set to the passed value. | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} attr | ||
* @param {?string} [value] | ||
*/ | ||
export function attr(node, attr, value) { | ||
if (arguments.length < 3) { | ||
return node.getAttribute(attr); | ||
} | ||
/** | ||
* Checks if an element is inline | ||
* | ||
* @return {bool} | ||
*/ | ||
isInline: function (elm, includeCodeAsBlock) { | ||
var tagName, | ||
nodeType = (elm || {}).nodeType || 3; | ||
// eslint-disable-next-line eqeqeq, no-eq-null | ||
if (value == null) { | ||
removeAttr(node, attr); | ||
} else { | ||
node.setAttribute(attr, value); | ||
} | ||
} | ||
if (nodeType !== 1) { | ||
return nodeType === 3; | ||
} | ||
/** | ||
* Removes the specified attribute | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!string} attr | ||
*/ | ||
export function removeAttr(node, attr) { | ||
node.removeAttribute(attr); | ||
} | ||
tagName = elm.tagName.toLowerCase(); | ||
/** | ||
* Sets the passed elements display to none | ||
* | ||
* @param {!HTMLElement} node | ||
*/ | ||
export function hide(node) { | ||
css(node, 'display', 'none'); | ||
} | ||
if (tagName === 'code') { | ||
return !includeCodeAsBlock; | ||
} | ||
/** | ||
* Sets the passed elements display to default | ||
* | ||
* @param {!HTMLElement} node | ||
*/ | ||
export function show(node) { | ||
css(node, 'display', ''); | ||
} | ||
return dom.blockLevelList.indexOf('|' + tagName + '|') < 0; | ||
}, | ||
/** | ||
* Toggles an elements visibility | ||
* | ||
* @param {!HTMLElement} node | ||
*/ | ||
export function toggle(node) { | ||
if (isVisible(node)) { | ||
hide(node); | ||
} else { | ||
show(node); | ||
} | ||
} | ||
/** | ||
* <p>Copys the CSS from 1 node to another.</p> | ||
* | ||
* <p>Only copies CSS defined on the element e.g. style attr.</p> | ||
* | ||
* @param {HTMLElement} from | ||
* @param {HTMLElement} to | ||
*/ | ||
copyCSS: function (from, to) { | ||
to.style.cssText = from.style.cssText + to.style.cssText; | ||
}, | ||
/** | ||
* Gets a computed CSS values or sets an inline CSS value | ||
* | ||
* Rules should be in camelCase format and not | ||
* hyphenated like CSS properties. | ||
* | ||
* @param {!HTMLElement} node | ||
* @param {!Object|string} rule | ||
* @param {string|number} [value] | ||
* @return {string|number|undefined} | ||
*/ | ||
export function css(node, rule, value) { | ||
if (arguments.length < 3) { | ||
if (utils.isString(rule)) { | ||
return getComputedStyle(node)[rule]; | ||
} | ||
/** | ||
* Fixes block level elements inside in inline elements. | ||
* | ||
* @param {HTMLElement} node | ||
*/ | ||
fixNesting: function (node) { | ||
var getLastInlineParent = function (node) { | ||
while (dom.isInline(node.parentNode, true)) { | ||
node = node.parentNode; | ||
} | ||
utils.each(rule, function (key, value) { | ||
css(node, key, value); | ||
}); | ||
} else { | ||
// isNaN returns false for null, false and empty strings | ||
// so need to check it's truthy or 0 | ||
var isNumeric = (value || value === 0) && !isNaN(value); | ||
node.style[rule] = isNumeric ? value + 'px' : value; | ||
} | ||
} | ||
return node; | ||
}; | ||
dom.traverse(node, function (node) { | ||
// Any blocklevel element inside an inline element needs fixing. | ||
if (node.nodeType === 1 && !dom.isInline(node, true) && | ||
dom.isInline(node.parentNode, true)) { | ||
var parent = getLastInlineParent(node), | ||
rParent = parent.parentNode, | ||
before = dom.extractContents(parent, node), | ||
middle = node; | ||
/** | ||
* Gets or sets thee data attributes on a node | ||
* | ||
* Unlike the jQuery version this only stores data | ||
* in the DOM attributes which means only strings | ||
* can be stored. | ||
* | ||
* @param {Node} node | ||
* @param {string} [key] | ||
* @param {string} [value] | ||
* @return {Object|undefined} | ||
*/ | ||
export function data(node, key, value) { | ||
var argsLength = arguments.length; | ||
var data = {}; | ||
// copy current styling so when moved out of the parent | ||
// it still has the same styling | ||
dom.copyCSS(parent, middle); | ||
rParent.insertBefore(before, parent); | ||
rParent.insertBefore(middle, parent); | ||
if (node.nodeType === ELEMENT_NODE) { | ||
if (argsLength === 1) { | ||
utils.each(node.attributes, function (_, attr) { | ||
if (/^data\-/i.test(attr.name)) { | ||
data[attr.name.substr(5)] = attr.value; | ||
} | ||
}); | ||
}, | ||
/** | ||
* Finds the common parent of two nodes | ||
* | ||
* @param {HTMLElement} node1 | ||
* @param {HTMLElement} node2 | ||
* @return {HTMLElement} | ||
*/ | ||
findCommonAncestor: function (node1, node2) { | ||
// Not as fast as making two arrays of parents and comparing | ||
// but is a lot smaller and as it's currently only used with | ||
// fixing invalid nesting it doesn't need to be very fast | ||
return $(node1).parents().has($(node2)).first(); | ||
}, | ||
return data; | ||
} | ||
getSibling: function (node, previous) { | ||
if (!node) { | ||
return null; | ||
if (argsLength === 2) { | ||
return attr(node, 'data-' + key); | ||
} | ||
attr(node, 'data-' + key, String(value)); | ||
} | ||
} | ||
/** | ||
* Checks if node matches the given selector. | ||
* | ||
* @param {?HTMLElement} node | ||
* @param {string} selector | ||
* @returns {boolean} | ||
*/ | ||
export function is(node, selector) { | ||
var result = false; | ||
if (node && node.nodeType === ELEMENT_NODE) { | ||
var parent, nextSibling, isAppended; | ||
result = (node.matches || node.msMatchesSelector || | ||
node.webkitMatchesSelector).call(node, selector); | ||
// Put node back where it came from after IE 9 fix | ||
if (isAppended) { | ||
remove(node); | ||
if (parent) { | ||
parent.insertBefore(node, nextSibling); | ||
} | ||
} | ||
} | ||
return (previous ? node.previousSibling : node.nextSibling) || | ||
dom.getSibling(node.parentNode, previous); | ||
}, | ||
return result; | ||
} | ||
/** | ||
* Removes unused whitespace from the root and all it's children | ||
* | ||
* @name removeWhiteSpace^1 | ||
* @param {HTMLElement} root | ||
*/ | ||
/** | ||
* Removes unused whitespace from the root and all it's children. | ||
* | ||
* If preserveNewLines is true, new line characters will not be removed | ||
* | ||
* @name removeWhiteSpace^2 | ||
* @param {HTMLElement} root | ||
* @param {boolean} preserveNewLines | ||
* @since 1.4.3 | ||
*/ | ||
removeWhiteSpace: function (root, preserveNewLines) { | ||
var nodeValue, nodeType, next, previous, previousSibling, | ||
cssWhiteSpace, nextNode, trimStart, | ||
getSibling = dom.getSibling, | ||
isInline = dom.isInline, | ||
node = root.firstChild; | ||
while (node) { | ||
nextNode = node.nextSibling; | ||
nodeValue = node.nodeValue; | ||
nodeType = node.nodeType; | ||
/** | ||
* Returns true if node contains child otherwise false. | ||
* | ||
* This differs from the DOM contains() method in that | ||
* if node and child are equal this will return false. | ||
* | ||
* @param {!Node} node | ||
* @param {HTMLElement} child | ||
* @returns {boolean} | ||
*/ | ||
export function contains(node, child) { | ||
return node !== child && node.contains && node.contains(child); | ||
} | ||
// 1 = element | ||
if (nodeType === 1 && node.firstChild) { | ||
cssWhiteSpace = $(node).css('whiteSpace'); | ||
/** | ||
* @param {Node} node | ||
* @param {string} [selector] | ||
* @returns {?HTMLElement} | ||
*/ | ||
export function previousElementSibling(node, selector) { | ||
var prev = node.previousElementSibling; | ||
// Skip all pre & pre-wrap with any vendor prefix | ||
if (!/pre(\-wrap)?$/i.test(cssWhiteSpace)) { | ||
dom.removeWhiteSpace( | ||
node, | ||
/line$/i.test(cssWhiteSpace) | ||
); | ||
} | ||
} | ||
if (selector && prev) { | ||
return is(prev, selector) ? prev : null; | ||
} | ||
// 3 = textnode | ||
if (nodeType === 3 && nodeValue) { | ||
next = getSibling(node); | ||
previous = getSibling(node, true); | ||
trimStart = false; | ||
return prev; | ||
} | ||
while ($(previous).hasClass('sceditor-ignore')) { | ||
previous = getSibling(previous, true); | ||
} | ||
// If previous sibling isn't inline or is a textnode that | ||
// ends in whitespace, time the start whitespace | ||
if (isInline(node) && previous) { | ||
previousSibling = previous; | ||
/** | ||
* @param {!Node} node | ||
* @param {!Node} refNode | ||
* @returns {Node} | ||
*/ | ||
export function insertBefore(node, refNode) { | ||
return refNode.parentNode.insertBefore(node, refNode); | ||
} | ||
while (previousSibling.lastChild) { | ||
previousSibling = previousSibling.lastChild; | ||
} | ||
/** | ||
* @param {?HTMLElement} node | ||
* @returns {!Array.<string>} | ||
*/ | ||
function classes(node) { | ||
return node.className.trim().split(/\s+/); | ||
} | ||
trimStart = previousSibling.nodeType === 3 ? | ||
/[\t\n\r ]$/.test(previousSibling.nodeValue) : | ||
!isInline(previousSibling); | ||
} | ||
/** | ||
* @param {?HTMLElement} node | ||
* @param {string} className | ||
* @returns {boolean} | ||
*/ | ||
export function hasClass(node, className) { | ||
return is(node, '.' + className); | ||
} | ||
// Clear zero width spaces | ||
nodeValue = nodeValue.replace(/\u200B/g, ''); | ||
/** | ||
* @param {!HTMLElement} node | ||
* @param {string} className | ||
*/ | ||
export function addClass(node, className) { | ||
var classList = classes(node); | ||
// Strip leading whitespace | ||
if (!previous || !isInline(previous) || trimStart) { | ||
nodeValue = nodeValue.replace( | ||
preserveNewLines ? /^[\t ]+/ : /^[\t\n\r ]+/, | ||
'' | ||
); | ||
} | ||
if (classList.indexOf(className) < 0) { | ||
classList.push(className); | ||
} | ||
// Strip trailing whitespace | ||
if (!next || !isInline(next)) { | ||
nodeValue = nodeValue.replace( | ||
preserveNewLines ? /[\t ]+$/ : /[\t\n\r ]+$/, | ||
'' | ||
); | ||
} | ||
node.className = classList.join(' '); | ||
} | ||
// Remove empty text nodes | ||
if (!nodeValue.length) { | ||
root.removeChild(node); | ||
} else { | ||
node.nodeValue = nodeValue.replace( | ||
preserveNewLines ? /[\t ]+/g : /[\t\n\r ]+/g, | ||
' ' | ||
); | ||
} | ||
} | ||
/** | ||
* @param {!HTMLElement} node | ||
* @param {string} className | ||
*/ | ||
export function removeClass(node, className) { | ||
var classList = classes(node); | ||
node = nextNode; | ||
} | ||
}, | ||
utils.arrayRemove(classList, className); | ||
/** | ||
* Extracts all the nodes between the start and end nodes | ||
* | ||
* @param {HTMLElement} startNode The node to start extracting at | ||
* @param {HTMLElement} endNode The node to stop extracting at | ||
* @return {DocumentFragment} | ||
*/ | ||
extractContents: function (startNode, endNode) { | ||
var extract, | ||
commonAncestor = dom | ||
.findCommonAncestor(startNode, endNode) | ||
.get(0), | ||
startReached = false, | ||
endReached = false; | ||
node.className = classList.join(' '); | ||
} | ||
extract = function (root) { | ||
var clone, | ||
docFrag = startNode.ownerDocument.createDocumentFragment(); | ||
/** | ||
* Toggles a class on node. | ||
* | ||
* If state is specified and is truthy it will add | ||
* the class. | ||
* | ||
* If state is specified and is falsey it will remove | ||
* the class. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {string} className | ||
* @param {boolean} [state] | ||
*/ | ||
export function toggleClass(node, className, state) { | ||
state = utils.isUndefined(state) ? !hasClass(node, className) : state; | ||
dom.traverse(root, function (node) { | ||
// if end has been reached exit loop | ||
if (endReached || node === endNode) { | ||
endReached = true; | ||
if (state) { | ||
addClass(node, className); | ||
} else { | ||
removeClass(node, className); | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* Gets or sets the width of the passed node. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {number|string} [value] | ||
* @returns {number|undefined} | ||
*/ | ||
export function width(node, value) { | ||
if (utils.isUndefined(value)) { | ||
var cs = getComputedStyle(node); | ||
var padding = toFloat(cs.paddingLeft) + toFloat(cs.paddingRight); | ||
var border = toFloat(cs.borderLeftWidth) + toFloat(cs.borderRightWidth); | ||
if (node === startNode) { | ||
startReached = true; | ||
} | ||
return node.offsetWidth - padding - border; | ||
} | ||
// if the start has been reached and this elm contains | ||
// the end node then clone it | ||
// if this node contains the start node then add it | ||
if ($.contains(node, startNode) || | ||
(startReached && $.contains(node, endNode))) { | ||
clone = node.cloneNode(false); | ||
css(node, 'width', value); | ||
} | ||
clone.appendChild(extract(node)); | ||
docFrag.appendChild(clone); | ||
/** | ||
* Gets or sets the height of the passed node. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {number|string} [value] | ||
* @returns {number|undefined} | ||
*/ | ||
export function height(node, value) { | ||
if (utils.isUndefined(value)) { | ||
var cs = getComputedStyle(node); | ||
var padding = toFloat(cs.paddingTop) + toFloat(cs.paddingBottom); | ||
var border = toFloat(cs.borderTopWidth) + toFloat(cs.borderBottomWidth); | ||
// otherwise move it if its parent isn't already part of it | ||
} else if (startReached && !$.contains(docFrag, node)) { | ||
docFrag.appendChild(node); | ||
} | ||
}, false); | ||
return node.offsetHeight - padding - border; | ||
} | ||
return docFrag; | ||
}; | ||
css(node, 'height', value); | ||
} | ||
return extract(commonAncestor); | ||
}, | ||
/** | ||
* Triggers a custom event with the specified name and | ||
* sets the detail property to the data object passed. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {string} eventName | ||
* @param {Object} [data] | ||
*/ | ||
export function trigger(node, eventName, data) { | ||
var event; | ||
/** | ||
* Gets the offset position of an element | ||
* | ||
* @param {HTMLElement} obj | ||
* @return {Object} An object with left and top properties | ||
*/ | ||
getOffset: function (obj) { | ||
var pLeft = 0, | ||
pTop = 0; | ||
if (utils.isFunction(window.CustomEvent)) { | ||
event = new CustomEvent(eventName, { | ||
bubbles: true, | ||
cancelable: true, | ||
detail: data | ||
}); | ||
} else { | ||
event = node.ownerDocument.createEvent('CustomEvent'); | ||
event.initCustomEvent(eventName, true, true, data); | ||
} | ||
while (obj) { | ||
pLeft += obj.offsetLeft; | ||
pTop += obj.offsetTop; | ||
obj = obj.offsetParent; | ||
} | ||
node.dispatchEvent(event); | ||
} | ||
return { | ||
left: pLeft, | ||
top: pTop | ||
}; | ||
}, | ||
/** | ||
* Returns if a node is visible. | ||
* | ||
* @param {HTMLElement} | ||
* @returns {boolean} | ||
*/ | ||
export function isVisible(node) { | ||
return !!node.getClientRects().length; | ||
} | ||
/** | ||
* Gets the value of a CSS property from the elements style attribute | ||
* | ||
* @param {HTMLElement} elm | ||
* @param {String} property | ||
* @return {String} | ||
*/ | ||
getStyle: function (elm, property) { | ||
var $elm, direction, styleValue, | ||
elmStyle = elm.style; | ||
/** | ||
* Convert CSS property names into camel case | ||
* | ||
* @param {string} string | ||
* @returns {string} | ||
*/ | ||
function camelCase(string) { | ||
return string | ||
.replace(/^-ms-/, 'ms-') | ||
.replace(/-(\w)/g, function (match, char) { | ||
return char.toUpperCase(); | ||
}); | ||
} | ||
if (!elmStyle) { | ||
return ''; | ||
} | ||
if (!_propertyNameCache[property]) { | ||
_propertyNameCache[property] = $.camelCase(property); | ||
/** | ||
* Loop all child nodes of the passed node | ||
* | ||
* The function should accept 1 parameter being the node. | ||
* If the function returns false the loop will be exited. | ||
* | ||
* @param {HTMLElement} node | ||
* @param {function} func Callback which is called with every | ||
* child node as the first argument. | ||
* @param {boolean} innermostFirst If the innermost node should be passed | ||
* to the function before it's parents. | ||
* @param {boolean} siblingsOnly If to only traverse the nodes siblings | ||
* @param {boolean} [reverse=false] If to traverse the nodes in reverse | ||
*/ | ||
// eslint-disable-next-line max-params | ||
export function traverse(node, func, innermostFirst, siblingsOnly, reverse) { | ||
node = reverse ? node.lastChild : node.firstChild; | ||
while (node) { | ||
var next = reverse ? node.previousSibling : node.nextSibling; | ||
if ( | ||
(!innermostFirst && func(node) === false) || | ||
(!siblingsOnly && traverse( | ||
node, func, innermostFirst, siblingsOnly, reverse | ||
) === false) || | ||
(innermostFirst && func(node) === false) | ||
) { | ||
return false; | ||
} | ||
node = next; | ||
} | ||
} | ||
/** | ||
* Like traverse but loops in reverse | ||
* @see traverse | ||
*/ | ||
export function rTraverse(node, func, innermostFirst, siblingsOnly) { | ||
traverse(node, func, innermostFirst, siblingsOnly, true); | ||
} | ||
/** | ||
* Parses HTML into a document fragment | ||
* | ||
* @param {string} html | ||
* @param {Document} [context] | ||
* @since 1.4.4 | ||
* @return {DocumentFragment} | ||
*/ | ||
export function parseHTML(html, context) { | ||
context = context || document; | ||
var ret = context.createDocumentFragment(); | ||
var tmp = createElement('div', {}, context); | ||
tmp.innerHTML = html; | ||
while (tmp.firstChild) { | ||
appendChild(ret, tmp.firstChild); | ||
} | ||
return ret; | ||
} | ||
/** | ||
* Checks if an element has any styling. | ||
* | ||
* It has styling if it is not a plain <div> or <p> or | ||
* if it has a class, style attribute or data. | ||
* | ||
* @param {HTMLElement} elm | ||
* @return {boolean} | ||
* @since 1.4.4 | ||
*/ | ||
export function hasStyling(node) { | ||
return node && (!is(node, 'p,div') || node.className || | ||
attr(node, 'style') || !utils.isEmptyObject(data(node))); | ||
} | ||
/** | ||
* Converts an element from one type to another. | ||
* | ||
* For example it can convert the element <b> to <strong> | ||
* | ||
* @param {HTMLElement} element | ||
* @param {string} toTagName | ||
* @return {HTMLElement} | ||
* @since 1.4.4 | ||
*/ | ||
export function convertElement(element, toTagName) { | ||
var newElement = createElement(toTagName, {}, element.ownerDocument); | ||
utils.each(element.attributes, function (_, attribute) { | ||
// Some browsers parse invalid attributes names like | ||
// 'size"2' which throw an exception when set, just | ||
// ignore these. | ||
try { | ||
attr(newElement, attribute.name, attribute.value); | ||
} catch (ex) {} | ||
}); | ||
while (element.firstChild) { | ||
appendChild(newElement, element.firstChild); | ||
} | ||
element.parentNode.replaceChild(newElement, element); | ||
return newElement; | ||
} | ||
/** | ||
* List of block level elements separated by bars (|) | ||
* | ||
* @type {string} | ||
*/ | ||
export var blockLevelList = '|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|' + | ||
'form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|'; | ||
/** | ||
* List of elements that do not allow children separated by bars (|) | ||
* | ||
* @param {Node} node | ||
* @return {boolean} | ||
* @since 1.4.5 | ||
*/ | ||
export function canHaveChildren(node) { | ||
// 1 = Element | ||
// 9 = Document | ||
// 11 = Document Fragment | ||
if (!/11?|9/.test(node.nodeType)) { | ||
return false; | ||
} | ||
// List of empty HTML tags separated by bar (|) character. | ||
// Source: http://www.w3.org/TR/html4/index/elements.html | ||
// Source: http://www.w3.org/TR/html5/syntax.html#void-elements | ||
return ('|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr' + | ||
'|isindex|link|meta|param|command|embed|keygen|source|track|' + | ||
'object|').indexOf('|' + node.nodeName.toLowerCase() + '|') < 0; | ||
} | ||
/** | ||
* Checks if an element is inline | ||
* | ||
* @param {HTMLElement} elm | ||
* @param {boolean} [includeCodeAsBlock=false] | ||
* @return {boolean} | ||
*/ | ||
export function isInline(elm, includeCodeAsBlock) { | ||
var tagName, | ||
nodeType = (elm || {}).nodeType || TEXT_NODE; | ||
if (nodeType !== ELEMENT_NODE) { | ||
return nodeType === TEXT_NODE; | ||
} | ||
tagName = elm.tagName.toLowerCase(); | ||
if (tagName === 'code') { | ||
return !includeCodeAsBlock; | ||
} | ||
return blockLevelList.indexOf('|' + tagName + '|') < 0; | ||
} | ||
/** | ||
* Copy the CSS from 1 node to another. | ||
* | ||
* Only copies CSS defined on the element e.g. style attr. | ||
* | ||
* @param {HTMLElement} from | ||
* @param {HTMLElement} to | ||
*/ | ||
export function copyCSS(from, to) { | ||
to.style.cssText = from.style.cssText + to.style.cssText; | ||
} | ||
/** | ||
* Fixes block level elements inside in inline elements. | ||
* | ||
* Also fixes invalid list nesting by placing nested lists | ||
* inside the previous li tag or wrapping them in an li tag. | ||
* | ||
* @param {HTMLElement} node | ||
*/ | ||
export function fixNesting(node) { | ||
var getLastInlineParent = function (node) { | ||
while (isInline(node.parentNode, true)) { | ||
node = node.parentNode; | ||
} | ||
return node; | ||
}; | ||
traverse(node, function (node) { | ||
var list = 'ul,ol', | ||
isBlock = !isInline(node, true); | ||
// Any blocklevel element inside an inline element needs fixing. | ||
if (isBlock && isInline(node.parentNode, true)) { | ||
var parent = getLastInlineParent(node), | ||
before = extractContents(parent, node), | ||
middle = node; | ||
// copy current styling so when moved out of the parent | ||
// it still has the same styling | ||
copyCSS(parent, middle); | ||
insertBefore(before, parent); | ||
insertBefore(middle, parent); | ||
} | ||
// Fix invalid nested lists which should be wrapped in an li tag | ||
if (isBlock && is(node, list) && is(node.parentNode, list)) { | ||
var li = previousElementSibling(node, 'li'); | ||
if (!li) { | ||
li = createElement('li'); | ||
insertBefore(li, node); | ||
} | ||
property = _propertyNameCache[property]; | ||
styleValue = elmStyle[property]; | ||
appendChild(li, node); | ||
} | ||
}); | ||
} | ||
// Add an exception for text-align | ||
if ('textAlign' === property) { | ||
$elm = $(elm); | ||
direction = elmStyle.direction; | ||
styleValue = styleValue || $elm.css(property); | ||
/** | ||
* Finds the common parent of two nodes | ||
* | ||
* @param {!HTMLElement} node1 | ||
* @param {!HTMLElement} node2 | ||
* @return {?HTMLElement} | ||
*/ | ||
export function findCommonAncestor(node1, node2) { | ||
while ((node1 = node1.parentNode)) { | ||
if (contains(node1, node2)) { | ||
return node1; | ||
} | ||
} | ||
} | ||
if ($elm.parent().css(property) === styleValue || | ||
$elm.css('display') !== 'block' || | ||
$elm.is('hr') || $elm.is('th')) { | ||
return ''; | ||
/** | ||
* @param {?Node} | ||
* @param {boolean} [previous=false] | ||
* @returns {?Node} | ||
*/ | ||
export function getSibling(node, previous) { | ||
if (!node) { | ||
return null; | ||
} | ||
return (previous ? node.previousSibling : node.nextSibling) || | ||
getSibling(node.parentNode, previous); | ||
} | ||
/** | ||
* Removes unused whitespace from the root and all it's children. | ||
* | ||
* @param {!HTMLElement} root | ||
* @since 1.4.3 | ||
*/ | ||
export function removeWhiteSpace(root) { | ||
var nodeValue, nodeType, next, previous, previousSibling, | ||
nextNode, trimStart, | ||
cssWhiteSpace = css(root, 'whiteSpace'), | ||
// Preserve newlines if is pre-line | ||
preserveNewLines = /line$/i.test(cssWhiteSpace), | ||
node = root.firstChild; | ||
// Skip pre & pre-wrap with any vendor prefix | ||
if (/pre(\-wrap)?$/i.test(cssWhiteSpace)) { | ||
return; | ||
} | ||
while (node) { | ||
nextNode = node.nextSibling; | ||
nodeValue = node.nodeValue; | ||
nodeType = node.nodeType; | ||
if (nodeType === ELEMENT_NODE && node.firstChild) { | ||
removeWhiteSpace(node); | ||
} | ||
if (nodeType === TEXT_NODE) { | ||
next = getSibling(node); | ||
previous = getSibling(node, true); | ||
trimStart = false; | ||
while (hasClass(previous, 'sceditor-ignore')) { | ||
previous = getSibling(previous, true); | ||
} | ||
// If previous sibling isn't inline or is a textnode that | ||
// ends in whitespace, time the start whitespace | ||
if (isInline(node) && previous) { | ||
previousSibling = previous; | ||
while (previousSibling.lastChild) { | ||
previousSibling = previousSibling.lastChild; | ||
} | ||
// check all works with changes and merge with prev? | ||
// IE changes text-align to the same as the current direction | ||
// so skip unless its not the same | ||
if ((/right/i.test(styleValue) && direction === 'rtl') || | ||
(/left/i.test(styleValue) && direction === 'ltr')) { | ||
return ''; | ||
} | ||
trimStart = previousSibling.nodeType === TEXT_NODE ? | ||
/[\t\n\r ]$/.test(previousSibling.nodeValue) : | ||
!isInline(previousSibling); | ||
} | ||
return styleValue; | ||
}, | ||
// Clear zero width spaces | ||
nodeValue = nodeValue.replace(/\u200B/g, ''); | ||
/** | ||
* Tests if an element has a style. | ||
* | ||
* If values are specified it will check that the styles value | ||
* matches one of the values | ||
* | ||
* @param {HTMLElement} elm | ||
* @param {String} property | ||
* @param {String|Array} values | ||
* @return {Boolean} | ||
*/ | ||
hasStyle: function (elm, property, values) { | ||
var styleValue = dom.getStyle(elm, property); | ||
// Strip leading whitespace | ||
if (!previous || !isInline(previous) || trimStart) { | ||
nodeValue = nodeValue.replace( | ||
preserveNewLines ? /^[\t ]+/ : /^[\t\n\r ]+/, | ||
'' | ||
); | ||
} | ||
if (!styleValue) { | ||
return false; | ||
// Strip trailing whitespace | ||
if (!next || !isInline(next)) { | ||
nodeValue = nodeValue.replace( | ||
preserveNewLines ? /[\t ]+$/ : /[\t\n\r ]+$/, | ||
'' | ||
); | ||
} | ||
return !values || styleValue === values || | ||
($.isArray(values) && $.inArray(styleValue, values) > -1); | ||
// Remove empty text nodes | ||
if (!nodeValue.length) { | ||
remove(node); | ||
} else { | ||
node.nodeValue = nodeValue.replace( | ||
preserveNewLines ? /[\t ]+/g : /[\t\n\r ]+/g, | ||
' ' | ||
); | ||
} | ||
} | ||
node = nextNode; | ||
} | ||
} | ||
/** | ||
* Extracts all the nodes between the start and end nodes | ||
* | ||
* @param {HTMLElement} startNode The node to start extracting at | ||
* @param {HTMLElement} endNode The node to stop extracting at | ||
* @return {DocumentFragment} | ||
*/ | ||
export function extractContents(startNode, endNode) { | ||
var range = startNode.ownerDocument.createRange(); | ||
range.setStartBefore(startNode); | ||
range.setEndAfter(endNode); | ||
return range.extractContents(); | ||
} | ||
/** | ||
* Gets the offset position of an element | ||
* | ||
* @param {HTMLElement} node | ||
* @return {Object} An object with left and top properties | ||
*/ | ||
export function getOffset(node) { | ||
var left = 0, | ||
top = 0; | ||
while (node) { | ||
left += node.offsetLeft; | ||
top += node.offsetTop; | ||
node = node.offsetParent; | ||
} | ||
return { | ||
left: left, | ||
top: top | ||
}; | ||
} | ||
return dom; | ||
}); | ||
/** | ||
* Gets the value of a CSS property from the elements style attribute | ||
* | ||
* @param {HTMLElement} elm | ||
* @param {string} property | ||
* @return {string} | ||
*/ | ||
export function getStyle(elm, property) { | ||
var direction, styleValue, | ||
elmStyle = elm.style; | ||
if (!cssPropertyNameCache[property]) { | ||
cssPropertyNameCache[property] = camelCase(property); | ||
} | ||
property = cssPropertyNameCache[property]; | ||
styleValue = elmStyle[property]; | ||
// Add an exception for text-align | ||
if ('textAlign' === property) { | ||
direction = elmStyle.direction; | ||
styleValue = styleValue || css(elm, property); | ||
if (css(elm.parentNode, property) === styleValue || | ||
css(elm, 'display') !== 'block' || is(elm, 'hr,th')) { | ||
return ''; | ||
} | ||
// IE changes text-align to the same as the current direction | ||
// so skip unless its not the same | ||
if ((/right/i.test(styleValue) && direction === 'rtl') || | ||
(/left/i.test(styleValue) && direction === 'ltr')) { | ||
return ''; | ||
} | ||
} | ||
return styleValue; | ||
} | ||
/** | ||
* Tests if an element has a style. | ||
* | ||
* If values are specified it will check that the styles value | ||
* matches one of the values | ||
* | ||
* @param {HTMLElement} elm | ||
* @param {string} property | ||
* @param {string|array} [values] | ||
* @return {boolean} | ||
*/ | ||
export function hasStyle(elm, property, values) { | ||
var styleValue = getStyle(elm, property); | ||
if (!styleValue) { | ||
return false; | ||
} | ||
return !values || styleValue === values || | ||
(Array.isArray(values) && values.indexOf(styleValue) > -1); | ||
} |
@@ -1,104 +0,104 @@ | ||
define(function (require, exports) { | ||
'use strict'; | ||
// Must start with a valid scheme | ||
// ^ | ||
// Schemes that are considered safe | ||
// (https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):| | ||
// Relative schemes (//:) are considered safe | ||
// (\\/\\/)| | ||
// Image data URI's are considered safe | ||
// data:image\\/(png|bmp|gif|p?jpe?g); | ||
var VALID_SCHEME_REGEX = | ||
/^(https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(\/\/)|data:image\/(png|bmp|gif|p?jpe?g);/i; | ||
var VALID_SCHEME_REGEX = | ||
/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i; | ||
/** | ||
* Escapes a string so it's safe to use in regex | ||
* | ||
* @param {string} str | ||
* @return {string} | ||
*/ | ||
export function regex(str) { | ||
return str.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); | ||
}; | ||
/** | ||
* Escapes a string so it's safe to use in regex | ||
* | ||
* @param {String} str | ||
* @return {String} | ||
* @name regex | ||
*/ | ||
exports.regex = function (str) { | ||
return str.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); | ||
/** | ||
* Escapes all HTML entities in a string | ||
* | ||
* If noQuotes is set to false, all single and double | ||
* quotes will also be escaped | ||
* | ||
* @param {string} str | ||
* @param {boolean} [noQuotes=true] | ||
* @return {string} | ||
* @since 1.4.1 | ||
*/ | ||
export function entities(str, noQuotes) { | ||
if (!str) { | ||
return str; | ||
} | ||
var replacements = { | ||
'&': '&', | ||
'<': '<', | ||
'>': '>', | ||
' ': ' ', | ||
'\r\n': '<br />', | ||
'\r': '<br />', | ||
'\n': '<br />' | ||
}; | ||
/** | ||
* Escapes all HTML entities in a string | ||
* | ||
* If noQuotes is set to false, all single and double | ||
* quotes will also be escaped | ||
* | ||
* @param {String} str | ||
* @param {Boolean} [noQuotes=false] | ||
* @return {String} | ||
* @name entities | ||
* @since 1.4.1 | ||
*/ | ||
exports.entities = function (str, noQuotes) { | ||
if (!str) { | ||
return str; | ||
} | ||
if (noQuotes !== false) { | ||
replacements['"'] = '"'; | ||
replacements['\''] = '''; | ||
replacements['`'] = '`'; | ||
} | ||
var replacements = { | ||
'&': '&', | ||
'<': '<', | ||
'>': '>', | ||
' ': ' ', | ||
'\r\n': '\n', | ||
'\r': '\n', | ||
'\n': '<br />' | ||
}; | ||
str = str.replace(/ {2}|\r\n|[&<>\r\n'"`]/g, function (match) { | ||
return replacements[match] || match; | ||
}); | ||
if (noQuotes !== false) { | ||
replacements['"'] = '"'; | ||
replacements['\''] = '''; | ||
replacements['`'] = '`'; | ||
} | ||
return str; | ||
}; | ||
str = str.replace(/ {2}|\r\n|[&<>\r\n'"`]/g, function (match) { | ||
return replacements[match] || match; | ||
}); | ||
/** | ||
* Escape URI scheme. | ||
* | ||
* Appends the current URL to a url if it has a scheme that is not: | ||
* | ||
* http | ||
* https | ||
* sftp | ||
* ftp | ||
* mailto | ||
* spotify | ||
* skype | ||
* ssh | ||
* teamspeak | ||
* tel | ||
* // | ||
* data:image/(png|jpeg|jpg|pjpeg|bmp|gif); | ||
* | ||
* **IMPORTANT**: This does not escape any HTML in a url, for | ||
* that use the escape.entities() method. | ||
* | ||
* @param {string} url | ||
* @return {string} | ||
* @since 1.4.5 | ||
*/ | ||
export function uriScheme(url) { | ||
var path, | ||
// If there is a : before a / then it has a scheme | ||
hasScheme = /^[^\/]*:/i, | ||
location = window.location; | ||
return str; | ||
}; | ||
// Has no scheme or a valid scheme | ||
if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) { | ||
return url; | ||
} | ||
/** | ||
* Escape URI scheme. | ||
* | ||
* Appends the current URL to a url if it has a scheme that is not: | ||
* | ||
* http | ||
* https | ||
* sftp | ||
* ftp | ||
* mailto | ||
* spotify | ||
* skype | ||
* ssh | ||
* teamspeak | ||
* tel | ||
* // | ||
* | ||
* **IMPORTANT**: This does not escape any HTML in a url, for | ||
* that use the escape.entities() method. | ||
* | ||
* @param {String} url | ||
* @return {String} | ||
* @name escapeUriScheme | ||
* @memberOf jQuery.sceditor | ||
* @since 1.4.5 | ||
*/ | ||
exports.uriScheme = function (url) { | ||
/*jshint maxlen:false*/ | ||
var path, | ||
// If there is a : before a / then it has a scheme | ||
hasScheme = /^[^\/]*:/i, | ||
location = window.location; | ||
path = location.pathname.split('/'); | ||
path.pop(); | ||
// Has no scheme or a valid scheme | ||
if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) { | ||
return url; | ||
} | ||
path = location.pathname.split('/'); | ||
path.pop(); | ||
return location.protocol + '//' + | ||
location.host + | ||
path.join('/') + '/' + | ||
url; | ||
}; | ||
}); | ||
return location.protocol + '//' + | ||
location.host + | ||
path.join('/') + '/' + | ||
url; | ||
}; |
@@ -1,242 +0,235 @@ | ||
define(function () { | ||
'use strict'; | ||
var plugins = {}; | ||
var plugins = {}; | ||
/** | ||
* Plugin Manager class | ||
* @class PluginManager | ||
* @name PluginManager | ||
*/ | ||
export default function PluginManager(thisObj) { | ||
/** | ||
* Alias of this | ||
* | ||
* @private | ||
* @type {Object} | ||
*/ | ||
var base = this; | ||
/** | ||
* Plugin Manager class | ||
* @class PluginManager | ||
* @name PluginManager | ||
* Array of all currently registered plugins | ||
* | ||
* @type {Array} | ||
* @private | ||
*/ | ||
var PluginManager = function (thisObj) { | ||
/** | ||
* Alias of this | ||
* | ||
* @private | ||
* @type {Object} | ||
*/ | ||
var base = this; | ||
var registeredPlugins = []; | ||
/** | ||
* Array of all currently registered plugins | ||
* | ||
* @type {Array} | ||
* @private | ||
*/ | ||
var registeredPlugins = []; | ||
/** | ||
* Changes a signals name from "name" into "signalName". | ||
* | ||
* @param {string} signal | ||
* @return {string} | ||
* @private | ||
*/ | ||
var formatSignalName = function (signal) { | ||
return 'signal' + signal.charAt(0).toUpperCase() + signal.slice(1); | ||
}; | ||
/** | ||
* Changes a signals name from "name" into "signalName". | ||
* | ||
* @param {String} signal | ||
* @return {String} | ||
* @private | ||
*/ | ||
var formatSignalName = function (signal) { | ||
return 'signal' + signal.charAt(0).toUpperCase() + signal.slice(1); | ||
}; | ||
/** | ||
* Calls handlers for a signal | ||
* | ||
* @see call() | ||
* @see callOnlyFirst() | ||
* @param {Array} args | ||
* @param {boolean} returnAtFirst | ||
* @return {*} | ||
* @private | ||
*/ | ||
var callHandlers = function (args, returnAtFirst) { | ||
args = [].slice.call(args); | ||
/** | ||
* Calls handlers for a signal | ||
* | ||
* @see call() | ||
* @see callOnlyFirst() | ||
* @param {Array} args | ||
* @param {Boolean} returnAtFirst | ||
* @return {Mixed} | ||
* @private | ||
*/ | ||
var callHandlers = function (args, returnAtFirst) { | ||
args = [].slice.call(args); | ||
var idx, ret, | ||
signal = formatSignalName(args.shift()); | ||
var idx, ret, | ||
signal = formatSignalName(args.shift()); | ||
for (idx = 0; idx < registeredPlugins.length; idx++) { | ||
if (signal in registeredPlugins[idx]) { | ||
ret = registeredPlugins[idx][signal].apply(thisObj, args); | ||
for (idx = 0; idx < registeredPlugins.length; idx++) { | ||
if (signal in registeredPlugins[idx]) { | ||
ret = registeredPlugins[idx][signal].apply(thisObj, args); | ||
if (returnAtFirst) { | ||
return ret; | ||
} | ||
if (returnAtFirst) { | ||
return ret; | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
/** | ||
* Calls all handlers for the passed signal | ||
* | ||
* @param {String} signal | ||
* @param {...String} args | ||
* @return {Void} | ||
* @function | ||
* @name call | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.call = function () { | ||
callHandlers(arguments, false); | ||
}; | ||
/** | ||
* Calls all handlers for the passed signal | ||
* | ||
* @param {string} signal | ||
* @param {...string} args | ||
* @function | ||
* @name call | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.call = function () { | ||
callHandlers(arguments, false); | ||
}; | ||
/** | ||
* Calls the first handler for a signal, and returns the | ||
* | ||
* @param {String} signal | ||
* @param {...String} args | ||
* @return {Mixed} The result of calling the handler | ||
* @function | ||
* @name callOnlyFirst | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.callOnlyFirst = function () { | ||
return callHandlers(arguments, true); | ||
}; | ||
/** | ||
* Calls the first handler for a signal, and returns the | ||
* | ||
* @param {string} signal | ||
* @param {...string} args | ||
* @return {*} The result of calling the handler | ||
* @function | ||
* @name callOnlyFirst | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.callOnlyFirst = function () { | ||
return callHandlers(arguments, true); | ||
}; | ||
/** | ||
* Checks if a signal has a handler | ||
* | ||
* @param {String} signal | ||
* @return {Boolean} | ||
* @function | ||
* @name hasHandler | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.hasHandler = function (signal) { | ||
var i = registeredPlugins.length; | ||
signal = formatSignalName(signal); | ||
/** | ||
* Checks if a signal has a handler | ||
* | ||
* @param {string} signal | ||
* @return {boolean} | ||
* @function | ||
* @name hasHandler | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.hasHandler = function (signal) { | ||
var i = registeredPlugins.length; | ||
signal = formatSignalName(signal); | ||
while (i--) { | ||
if (signal in registeredPlugins[i]) { | ||
return true; | ||
} | ||
while (i--) { | ||
if (signal in registeredPlugins[i]) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
return false; | ||
}; | ||
/** | ||
* Checks if the plugin exists in plugins | ||
* | ||
* @param {String} plugin | ||
* @return {Boolean} | ||
* @function | ||
* @name exists | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.exists = function (plugin) { | ||
if (plugin in plugins) { | ||
plugin = plugins[plugin]; | ||
/** | ||
* Checks if the plugin exists in plugins | ||
* | ||
* @param {string} plugin | ||
* @return {boolean} | ||
* @function | ||
* @name exists | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.exists = function (plugin) { | ||
if (plugin in plugins) { | ||
plugin = plugins[plugin]; | ||
return typeof plugin === 'function' && | ||
typeof plugin.prototype === 'object'; | ||
} | ||
return typeof plugin === 'function' && | ||
typeof plugin.prototype === 'object'; | ||
} | ||
return false; | ||
}; | ||
return false; | ||
}; | ||
/** | ||
* Checks if the passed plugin is currently registered. | ||
* | ||
* @param {String} plugin | ||
* @return {Boolean} | ||
* @function | ||
* @name isRegistered | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.isRegistered = function (plugin) { | ||
if (base.exists(plugin)) { | ||
var idx = registeredPlugins.length; | ||
/** | ||
* Checks if the passed plugin is currently registered. | ||
* | ||
* @param {string} plugin | ||
* @return {boolean} | ||
* @function | ||
* @name isRegistered | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.isRegistered = function (plugin) { | ||
if (base.exists(plugin)) { | ||
var idx = registeredPlugins.length; | ||
while (idx--) { | ||
if (registeredPlugins[idx] instanceof plugins[plugin]) { | ||
return true; | ||
} | ||
while (idx--) { | ||
if (registeredPlugins[idx] instanceof plugins[plugin]) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}; | ||
/** | ||
* Registers a plugin to receive signals | ||
* | ||
* @param {string} plugin | ||
* @return {boolean} | ||
* @function | ||
* @name register | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.register = function (plugin) { | ||
if (!base.exists(plugin) || base.isRegistered(plugin)) { | ||
return false; | ||
}; | ||
} | ||
/** | ||
* Registers a plugin to receive signals | ||
* | ||
* @param {String} plugin | ||
* @return {Boolean} | ||
* @function | ||
* @name register | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.register = function (plugin) { | ||
if (!base.exists(plugin) || base.isRegistered(plugin)) { | ||
return false; | ||
} | ||
plugin = new plugins[plugin](); | ||
registeredPlugins.push(plugin); | ||
plugin = new plugins[plugin](); | ||
registeredPlugins.push(plugin); | ||
if ('init' in plugin) { | ||
plugin.init.call(thisObj); | ||
} | ||
if ('init' in plugin) { | ||
plugin.init.call(thisObj); | ||
} | ||
return true; | ||
}; | ||
return true; | ||
}; | ||
/** | ||
* Deregisters a plugin. | ||
* | ||
* @param {string} plugin | ||
* @return {boolean} | ||
* @function | ||
* @name deregister | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.deregister = function (plugin) { | ||
var removedPlugin, | ||
pluginIdx = registeredPlugins.length, | ||
removed = false; | ||
/** | ||
* Deregisters a plugin. | ||
* | ||
* @param {String} plugin | ||
* @return {Boolean} | ||
* @function | ||
* @name deregister | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.deregister = function (plugin) { | ||
var removedPlugin, | ||
pluginIdx = registeredPlugins.length, | ||
removed = false; | ||
if (!base.isRegistered(plugin)) { | ||
return removed; | ||
} | ||
if (!base.isRegistered(plugin)) { | ||
return removed; | ||
} | ||
while (pluginIdx--) { | ||
if (registeredPlugins[pluginIdx] instanceof plugins[plugin]) { | ||
removedPlugin = registeredPlugins.splice(pluginIdx, 1)[0]; | ||
removed = true; | ||
while (pluginIdx--) { | ||
if (registeredPlugins[pluginIdx] instanceof plugins[plugin]) { | ||
removedPlugin = registeredPlugins.splice(pluginIdx, 1)[0]; | ||
removed = true; | ||
if ('destroy' in removedPlugin) { | ||
removedPlugin.destroy.call(thisObj); | ||
} | ||
if ('destroy' in removedPlugin) { | ||
removedPlugin.destroy.call(thisObj); | ||
} | ||
} | ||
} | ||
return removed; | ||
}; | ||
return removed; | ||
}; | ||
/** | ||
* Clears all plugins and removes the owner reference. | ||
* | ||
* Calling any functions on this object after calling | ||
* destroy will cause a JS error. | ||
* | ||
* @name destroy | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.destroy = function () { | ||
var i = registeredPlugins.length; | ||
/** | ||
* Clears all plugins and removes the owner reference. | ||
* | ||
* Calling any functions on this object after calling | ||
* destroy will cause a JS error. | ||
* | ||
* @name destroy | ||
* @memberOf PluginManager.prototype | ||
*/ | ||
base.destroy = function () { | ||
var i = registeredPlugins.length; | ||
while (i--) { | ||
if ('destroy' in registeredPlugins[i]) { | ||
registeredPlugins[i].destroy.call(thisObj); | ||
} | ||
while (i--) { | ||
if ('destroy' in registeredPlugins[i]) { | ||
registeredPlugins[i].destroy.call(thisObj); | ||
} | ||
} | ||
registeredPlugins = []; | ||
thisObj = null; | ||
}; | ||
registeredPlugins = []; | ||
thisObj = null; | ||
}; | ||
}; | ||
PluginManager.plugins = plugins; | ||
return PluginManager; | ||
}); | ||
PluginManager.plugins = plugins; |
@@ -1,884 +0,773 @@ | ||
define(function (require) { | ||
'use strict'; | ||
import * as dom from './dom.js'; | ||
import * as escape from './escape.js'; | ||
import { ie as IE_VER } from './browser.js'; | ||
var $ = require('jquery'); | ||
var dom = require('./dom'); | ||
var escape = require('./escape'); | ||
var browser = require('./browser'); | ||
// In IE < 11 a BR at the end of a block level element | ||
// causes a line break. In all other browsers it's collapsed. | ||
var IE_BR_FIX = IE_VER && IE_VER < 11; | ||
var IE_VER = browser.ie; | ||
// In IE < 11 a BR at the end of a block level element | ||
// causes a line break. In all other browsers it's collapsed. | ||
var IE_BR_FIX = IE_VER && IE_VER < 11; | ||
/** | ||
* Gets the text, start/end node and offset for | ||
* length chars left or right of the passed node | ||
* at the specified offset. | ||
* | ||
* @param {Node} node | ||
* @param {number} offset | ||
* @param {boolean} isLeft | ||
* @param {number} length | ||
* @return {Object} | ||
* @private | ||
*/ | ||
var outerText = function (range, isLeft, length) { | ||
var nodeValue, remaining, start, end, node, | ||
text = '', | ||
next = range.startContainer, | ||
offset = range.startOffset; | ||
// Handle cases where node is a paragraph and offset | ||
// refers to the index of a text node. | ||
// 3 = text node | ||
if (next && next.nodeType !== 3) { | ||
next = next.childNodes[offset]; | ||
offset = 0; | ||
} | ||
var _nodeToHtml = function (node) { | ||
return $('<p>', node.ownerDocument).append(node).html(); | ||
}; | ||
start = end = offset; | ||
/** | ||
* Gets the text, start/end node and offset for | ||
* length chars left or right of the passed node | ||
* at the specified offset. | ||
* | ||
* @param {Node} node | ||
* @param {Number} offset | ||
* @param {Boolean} isLeft | ||
* @param {Number} length | ||
* @return {Object} | ||
* @private | ||
*/ | ||
var outerText = function (range, isLeft, length) { | ||
var nodeValue, remaining, start, end, node, | ||
text = '', | ||
next = range.startContainer, | ||
offset = range.startOffset; | ||
while (length > text.length && next && next.nodeType === 3) { | ||
nodeValue = next.nodeValue; | ||
remaining = length - text.length; | ||
// Handle cases where node is a paragraph and offset | ||
// refers to the index of a text node. | ||
// 3 = text node | ||
if (next && next.nodeType !== 3) { | ||
next = next.childNodes[offset]; | ||
offset = 0; | ||
// If not the first node, start and end should be at their | ||
// max values as will be updated when getting the text | ||
if (node) { | ||
end = nodeValue.length; | ||
start = 0; | ||
} | ||
start = end = offset; | ||
node = next; | ||
while (length > text.length && next && next.nodeType === 3) { | ||
nodeValue = next.nodeValue; | ||
remaining = length - text.length; | ||
if (isLeft) { | ||
start = Math.max(end - remaining, 0); | ||
offset = start; | ||
// If not the first node, start and end should be at their | ||
// max values as will be updated when getting the text | ||
if (node) { | ||
end = nodeValue.length; | ||
start = 0; | ||
} | ||
text = nodeValue.substr(start, end - start) + text; | ||
next = node.previousSibling; | ||
} else { | ||
end = Math.min(remaining, nodeValue.length); | ||
offset = start + end; | ||
node = next; | ||
if (isLeft) { | ||
start = Math.max(end - remaining, 0); | ||
offset = start; | ||
text = nodeValue.substr(start, end - start) + text; | ||
next = node.previousSibling; | ||
} else { | ||
end = Math.min(remaining, nodeValue.length); | ||
offset = start + end; | ||
text += nodeValue.substr(start, end); | ||
next = node.nextSibling; | ||
} | ||
text += nodeValue.substr(start, end); | ||
next = node.nextSibling; | ||
} | ||
} | ||
return { | ||
node: node || next, | ||
offset: offset, | ||
text: text | ||
}; | ||
return { | ||
node: node || next, | ||
offset: offset, | ||
text: text | ||
}; | ||
}; | ||
var RangeHelper = function (w, d) { | ||
var _createMarker, _isOwner, _prepareInput, | ||
doc = d || w.contentDocument || w.document, | ||
win = w, | ||
isW3C = !!w.getSelection, | ||
startMarker = 'sceditor-start-marker', | ||
endMarker = 'sceditor-end-marker', | ||
CHARACTER = 'character', // Used to improve minification | ||
base = this; | ||
/** | ||
* Range helper | ||
* | ||
* @class RangeHelper | ||
* @name RangeHelper | ||
*/ | ||
export default function RangeHelper(win, d) { | ||
var _createMarker, _prepareInput, | ||
doc = d || win.contentDocument || win.document, | ||
startMarker = 'sceditor-start-marker', | ||
endMarker = 'sceditor-end-marker', | ||
base = this; | ||
/** | ||
* <p>Inserts HTML into the current range replacing any selected | ||
* text.</p> | ||
* | ||
* <p>If endHTML is specified the selected contents will be put between | ||
* html and endHTML. If there is nothing selected html and endHTML are | ||
* just concatenate together.</p> | ||
* | ||
* @param {string} html | ||
* @param {string} endHTML | ||
* @return False on fail | ||
* @function | ||
* @name insertHTML | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertHTML = function (html, endHTML) { | ||
var node, div, | ||
range = base.selectedRange(); | ||
/** | ||
* Inserts HTML into the current range replacing any selected | ||
* text. | ||
* | ||
* If endHTML is specified the selected contents will be put between | ||
* html and endHTML. If there is nothing selected html and endHTML are | ||
* just concatenate together. | ||
* | ||
* @param {string} html | ||
* @param {string} [endHTML] | ||
* @return False on fail | ||
* @function | ||
* @name insertHTML | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertHTML = function (html, endHTML) { | ||
var node, div, | ||
range = base.selectedRange(); | ||
if (!range) { | ||
return false; | ||
} | ||
if (!range) { | ||
return false; | ||
} | ||
if (isW3C) { | ||
if (endHTML) { | ||
html += base.selectedHtml() + endHTML; | ||
} | ||
if (endHTML) { | ||
html += base.selectedHtml() + endHTML; | ||
} | ||
div = doc.createElement('p'); | ||
node = doc.createDocumentFragment(); | ||
div.innerHTML = html; | ||
div = dom.createElement('p', {}, doc); | ||
node = doc.createDocumentFragment(); | ||
div.innerHTML = html; | ||
while (div.firstChild) { | ||
node.appendChild(div.firstChild); | ||
} | ||
while (div.firstChild) { | ||
dom.appendChild(node, div.firstChild); | ||
} | ||
base.insertNode(node); | ||
} else { | ||
range.pasteHTML(_prepareInput(html, endHTML, true)); | ||
base.restoreRange(); | ||
} | ||
}; | ||
base.insertNode(node); | ||
}; | ||
/** | ||
* Prepares HTML to be inserted by adding a zero width space | ||
* if the last child is empty and adding the range start/end | ||
* markers to the last child. | ||
* | ||
* @param {Node|string} node | ||
* @param {Node|string} endNode | ||
* @param {boolean} returnHtml | ||
* @return {Node|string} | ||
* @private | ||
*/ | ||
_prepareInput = function (node, endNode, returnHtml) { | ||
var lastChild, $lastChild, | ||
div = doc.createElement('div'), | ||
$div = $(div); | ||
/** | ||
* Prepares HTML to be inserted by adding a zero width space | ||
* if the last child is empty and adding the range start/end | ||
* markers to the last child. | ||
* | ||
* @param {Node|string} node | ||
* @param {Node|string} [endNode] | ||
* @param {boolean} [returnHtml] | ||
* @return {Node|string} | ||
* @private | ||
*/ | ||
_prepareInput = function (node, endNode, returnHtml) { | ||
var lastChild, | ||
frag = doc.createDocumentFragment(); | ||
if (typeof node === 'string') { | ||
if (endNode) { | ||
node += base.selectedHtml() + endNode; | ||
} | ||
$div.html(node); | ||
} else { | ||
$div.append(node); | ||
if (endNode) { | ||
$div | ||
.append(base.selectedRange().extractContents()) | ||
.append(endNode); | ||
} | ||
if (typeof node === 'string') { | ||
if (endNode) { | ||
node += base.selectedHtml() + endNode; | ||
} | ||
if (!(lastChild = div.lastChild)) { | ||
return; | ||
} | ||
frag = dom.parseHTML(node); | ||
} else { | ||
dom.appendChild(frag, node); | ||
while (!dom.isInline(lastChild.lastChild, true)) { | ||
lastChild = lastChild.lastChild; | ||
if (endNode) { | ||
dom.appendChild(frag, base.selectedRange().extractContents()); | ||
dom.appendChild(frag, endNode); | ||
} | ||
} | ||
if (dom.canHaveChildren(lastChild)) { | ||
$lastChild = $(lastChild); | ||
if (!(lastChild = frag.lastChild)) { | ||
return; | ||
} | ||
// IE <= 8 and Webkit won't allow the cursor to be placed | ||
// inside an empty tag, so add a zero width space to it. | ||
if (!lastChild.lastChild) { | ||
$lastChild.append('\u200B'); | ||
} | ||
} | ||
while (!dom.isInline(lastChild.lastChild, true)) { | ||
lastChild = lastChild.lastChild; | ||
} | ||
// Needed so IE <= 8 can place the cursor after emoticons and images | ||
if (IE_VER && IE_VER < 9 && $(lastChild).is('img')) { | ||
$div.append('\u200B'); | ||
if (dom.canHaveChildren(lastChild)) { | ||
// IE <= 8 and Webkit won't allow the cursor to be placed | ||
// inside an empty tag, so add a zero width space to it. | ||
if (!lastChild.lastChild) { | ||
dom.appendChild(lastChild, document.createTextNode('\u200B')); | ||
} | ||
} else { | ||
lastChild = frag; | ||
} | ||
base.removeMarkers(); | ||
base.removeMarkers(); | ||
// Append marks to last child so when restored cursor will be in | ||
// the right place | ||
($lastChild || $div) | ||
.append(_createMarker(startMarker)) | ||
.append(_createMarker(endMarker)); | ||
// Append marks to last child so when restored cursor will be in | ||
// the right place | ||
dom.appendChild(lastChild, _createMarker(startMarker)); | ||
dom.appendChild(lastChild, _createMarker(endMarker)); | ||
if (returnHtml) { | ||
return $div.html(); | ||
} | ||
if (returnHtml) { | ||
var div = dom.createElement('div'); | ||
dom.appendChild(div, frag); | ||
return $(doc.createDocumentFragment()).append($div.contents())[0]; | ||
}; | ||
return div.innerHTML; | ||
} | ||
/** | ||
* <p>The same as insertHTML except with DOM nodes instead</p> | ||
* | ||
* <p><strong>Warning:</strong> the nodes must belong to the | ||
* document they are being inserted into. Some browsers | ||
* will throw exceptions if they don't.</p> | ||
* | ||
* @param {Node} node | ||
* @param {Node} endNode | ||
* @return False on fail | ||
* @function | ||
* @name insertNode | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertNode = function (node, endNode) { | ||
if (isW3C) { | ||
var input = _prepareInput(node, endNode), | ||
range = base.selectedRange(), | ||
parent = range.commonAncestorContainer; | ||
return frag; | ||
}; | ||
if (!input) { | ||
return false; | ||
} | ||
/** | ||
* The same as insertHTML except with DOM nodes instead | ||
* | ||
* <strong>Warning:</strong> the nodes must belong to the | ||
* document they are being inserted into. Some browsers | ||
* will throw exceptions if they don't. | ||
* | ||
* Returns boolean false on fail | ||
* | ||
* @param {Node} node | ||
* @param {Node} endNode | ||
* @return {false|undefined} | ||
* @function | ||
* @name insertNode | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertNode = function (node, endNode) { | ||
var input = _prepareInput(node, endNode), | ||
range = base.selectedRange(), | ||
parent = range.commonAncestorContainer; | ||
range.deleteContents(); | ||
if (!input) { | ||
return false; | ||
} | ||
// FF allows <br /> to be selected but inserting a node | ||
// into <br /> will cause it not to be displayed so must | ||
// insert before the <br /> in FF. | ||
// 3 = TextNode | ||
if (parent && parent.nodeType !== 3 && | ||
!dom.canHaveChildren(parent)) { | ||
parent.parentNode.insertBefore(input, parent); | ||
} else { | ||
range.insertNode(input); | ||
} | ||
range.deleteContents(); | ||
base.restoreRange(); | ||
} else { | ||
base.insertHTML( | ||
_nodeToHtml(node), | ||
endNode ? _nodeToHtml(endNode) : null | ||
); | ||
} | ||
}; | ||
// FF allows <br /> to be selected but inserting a node | ||
// into <br /> will cause it not to be displayed so must | ||
// insert before the <br /> in FF. | ||
// 3 = TextNode | ||
if (parent && parent.nodeType !== 3 && !dom.canHaveChildren(parent)) { | ||
dom.insertBefore(input, parent); | ||
} else { | ||
range.insertNode(input); | ||
} | ||
/** | ||
* <p>Clones the selected Range</p> | ||
* | ||
* <p>IE <= 8 will return a TextRange, all other browsers | ||
* will return a Range object.</p> | ||
* | ||
* @return {Range|TextRange} | ||
* @function | ||
* @name cloneSelected | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.cloneSelected = function () { | ||
var range = base.selectedRange(); | ||
base.restoreRange(); | ||
}; | ||
if (range) { | ||
return isW3C ? range.cloneRange() : range.duplicate(); | ||
} | ||
}; | ||
/** | ||
* <p>Clones the selected Range</p> | ||
* | ||
* <p>IE <= 8 will return a TextRange, all other browsers | ||
* will return a Range object.</p> | ||
* | ||
* @return {Range} | ||
* @function | ||
* @name cloneSelected | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.cloneSelected = function () { | ||
var range = base.selectedRange(); | ||
/** | ||
* <p>Gets the selected Range</p> | ||
* | ||
* <p>IE <= 8 will return a TextRange, all other browsers | ||
* will return a Range object.</p> | ||
* | ||
* @return {Range|TextRange} | ||
* @function | ||
* @name selectedRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectedRange = function () { | ||
var range, firstChild, | ||
sel = isW3C ? win.getSelection() : doc.selection; | ||
if (range) { | ||
return range.cloneRange(); | ||
} | ||
}; | ||
if (!sel) { | ||
return; | ||
} | ||
/** | ||
* <p>Gets the selected Range</p> | ||
* | ||
* <p>IE <= 8 will return a TextRange, all other browsers | ||
* will return a Range object.</p> | ||
* | ||
* @return {Range} | ||
* @function | ||
* @name selectedRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectedRange = function () { | ||
var range, firstChild, | ||
sel = win.getSelection(); | ||
// When creating a new range, set the start to the first child | ||
// element of the body element to avoid errors in FF. | ||
if (sel.getRangeAt && sel.rangeCount <= 0) { | ||
firstChild = doc.body; | ||
while (firstChild.firstChild) { | ||
firstChild = firstChild.firstChild; | ||
} | ||
if (!sel) { | ||
return; | ||
} | ||
range = doc.createRange(); | ||
// Must be setStartBefore otherwise it can cause infinite | ||
// loops with lists in WebKit. See issue 442 | ||
range.setStartBefore(firstChild); | ||
sel.addRange(range); | ||
// When creating a new range, set the start to the first child | ||
// element of the body element to avoid errors in FF. | ||
if (sel.getRangeAt && sel.rangeCount <= 0) { | ||
firstChild = doc.body; | ||
while (firstChild.firstChild) { | ||
firstChild = firstChild.firstChild; | ||
} | ||
if (isW3C && sel.rangeCount > 0) { | ||
range = sel.getRangeAt(0); | ||
} | ||
range = doc.createRange(); | ||
// Must be setStartBefore otherwise it can cause infinite | ||
// loops with lists in WebKit. See issue 442 | ||
range.setStartBefore(firstChild); | ||
if (!isW3C && sel.type !== 'Control') { | ||
range = sel.createRange(); | ||
} | ||
sel.addRange(range); | ||
} | ||
// IE fix to make sure only return selections that | ||
// are part of the WYSIWYG iframe | ||
return _isOwner(range) ? range : null; | ||
}; | ||
if (sel.rangeCount > 0) { | ||
range = sel.getRangeAt(0); | ||
} | ||
/** | ||
* Checks if an IE TextRange range belongs to | ||
* this document or not. | ||
* | ||
* Returns true if the range isn't an IE range or | ||
* if the range is null. | ||
* | ||
* @private | ||
*/ | ||
_isOwner = function (range) { | ||
var parent; | ||
return range; | ||
}; | ||
if (range && !isW3C) { | ||
parent = range.parentElement(); | ||
} | ||
/** | ||
* Gets if there is currently a selection | ||
* | ||
* @return {boolean} | ||
* @function | ||
* @name hasSelection | ||
* @since 1.4.4 | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.hasSelection = function () { | ||
var sel = win.getSelection(); | ||
// IE fix to make sure only return selections | ||
// that are part of the WYSIWYG iframe | ||
return parent ? | ||
parent.ownerDocument === doc : | ||
true; | ||
}; | ||
return sel && sel.rangeCount > 0; | ||
}; | ||
/** | ||
* Gets if there is currently a selection | ||
* | ||
* @return {boolean} | ||
* @function | ||
* @name hasSelection | ||
* @since 1.4.4 | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.hasSelection = function () { | ||
var sel = isW3C ? win.getSelection() : doc.selection; | ||
/** | ||
* Gets the currently selected HTML | ||
* | ||
* @return {string} | ||
* @function | ||
* @name selectedHtml | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectedHtml = function () { | ||
var div, | ||
range = base.selectedRange(); | ||
if (isW3C || !sel) { | ||
return sel && sel.rangeCount > 0; | ||
} | ||
if (range) { | ||
div = dom.createElement('p', {}, doc); | ||
dom.appendChild(div, range.cloneContents()); | ||
return sel.type !== 'None' && _isOwner(sel.createRange()); | ||
}; | ||
return div.innerHTML; | ||
} | ||
/** | ||
* Gets the currently selected HTML | ||
* | ||
* @return {string} | ||
* @function | ||
* @name selectedHtml | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectedHtml = function () { | ||
var div, | ||
range = base.selectedRange(); | ||
return ''; | ||
}; | ||
if (range) { | ||
/** | ||
* Gets the parent node of the selected contents in the range | ||
* | ||
* @return {HTMLElement} | ||
* @function | ||
* @name parentNode | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.parentNode = function () { | ||
var range = base.selectedRange(); | ||
// IE9+ and all other browsers | ||
if (isW3C) { | ||
div = doc.createElement('p'); | ||
div.appendChild(range.cloneContents()); | ||
if (range) { | ||
return range.commonAncestorContainer; | ||
} | ||
}; | ||
return div.innerHTML; | ||
// IE < 9 | ||
} else if (range.text !== '' && range.htmlText) { | ||
return range.htmlText; | ||
} | ||
/** | ||
* Gets the first block level parent of the selected | ||
* contents of the range. | ||
* | ||
* @return {HTMLElement} | ||
* @function | ||
* @name getFirstBlockParent | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
/** | ||
* Gets the first block level parent of the selected | ||
* contents of the range. | ||
* | ||
* @param {Node} [n] The element to get the first block level parent from | ||
* @return {HTMLElement} | ||
* @function | ||
* @name getFirstBlockParent^2 | ||
* @since 1.4.1 | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getFirstBlockParent = function (node) { | ||
var func = function (elm) { | ||
if (!dom.isInline(elm, true)) { | ||
return elm; | ||
} | ||
return ''; | ||
}; | ||
elm = elm ? elm.parentNode : null; | ||
/** | ||
* Gets the parent node of the selected contents in the range | ||
* | ||
* @return {HTMLElement} | ||
* @function | ||
* @name parentNode | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.parentNode = function () { | ||
var range = base.selectedRange(); | ||
if (range) { | ||
return range.parentElement ? | ||
range.parentElement() : | ||
range.commonAncestorContainer; | ||
} | ||
return elm ? func(elm) : elm; | ||
}; | ||
/** | ||
* Gets the first block level parent of the selected | ||
* contents of the range. | ||
* | ||
* @return {HTMLElement} | ||
* @function | ||
* @name getFirstBlockParent | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
/** | ||
* Gets the first block level parent of the selected | ||
* contents of the range. | ||
* | ||
* @param {Node} n The element to get the first block level parent from | ||
* @return {HTMLElement} | ||
* @function | ||
* @name getFirstBlockParent^2 | ||
* @since 1.4.1 | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getFirstBlockParent = function (n) { | ||
var func = function (node) { | ||
if (!dom.isInline(node, true)) { | ||
return node; | ||
} | ||
return func(node || base.parentNode()); | ||
}; | ||
node = node ? node.parentNode : null; | ||
/** | ||
* Inserts a node at either the start or end of the current selection | ||
* | ||
* @param {Bool} start | ||
* @param {Node} node | ||
* @function | ||
* @name insertNodeAt | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertNodeAt = function (start, node) { | ||
var currentRange = base.selectedRange(), | ||
range = base.cloneSelected(); | ||
return node ? func(node) : node; | ||
}; | ||
if (!range) { | ||
return false; | ||
} | ||
return func(n || base.parentNode()); | ||
}; | ||
range.collapse(start); | ||
range.insertNode(node); | ||
/** | ||
* Inserts a node at either the start or end of the current selection | ||
* | ||
* @param {Bool} start | ||
* @param {Node} node | ||
* @function | ||
* @name insertNodeAt | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.insertNodeAt = function (start, node) { | ||
var currentRange = base.selectedRange(), | ||
range = base.cloneSelected(); | ||
// Reselect the current range. | ||
// Fixes issue with Chrome losing the selection. Issue#82 | ||
base.selectRange(currentRange); | ||
}; | ||
if (!range) { | ||
return false; | ||
} | ||
/** | ||
* Creates a marker node | ||
* | ||
* @param {string} id | ||
* @return {HTMLSpanElement} | ||
* @private | ||
*/ | ||
_createMarker = function (id) { | ||
base.removeMarker(id); | ||
range.collapse(start); | ||
var marker = dom.createElement('span', { | ||
id: id, | ||
className: 'sceditor-selection sceditor-ignore', | ||
style: 'display:none;line-height:0' | ||
}, doc); | ||
if (isW3C) { | ||
range.insertNode(node); | ||
} else { | ||
range.pasteHTML(_nodeToHtml(node)); | ||
} | ||
marker.innerHTML = ' '; | ||
// Reselect the current range. | ||
// Fixes issue with Chrome losing the selection. Issue#82 | ||
base.selectRange(currentRange); | ||
}; | ||
return marker; | ||
}; | ||
/** | ||
* Creates a marker node | ||
* | ||
* @param {string} id | ||
* @return {Node} | ||
* @private | ||
*/ | ||
_createMarker = function (id) { | ||
base.removeMarker(id); | ||
/** | ||
* Inserts start/end markers for the current selection | ||
* which can be used by restoreRange to re-select the | ||
* range. | ||
* | ||
* @memberOf RangeHelper.prototype | ||
* @function | ||
* @name insertMarkers | ||
*/ | ||
base.insertMarkers = function () { | ||
var currentRange = base.selectedRange(); | ||
var startNode = _createMarker(startMarker); | ||
var marker = doc.createElement('span'); | ||
marker.id = id; | ||
marker.style.lineHeight = '0'; | ||
marker.style.display = 'none'; | ||
marker.className = 'sceditor-selection sceditor-ignore'; | ||
marker.innerHTML = ' '; | ||
base.removeMarkers(); | ||
base.insertNodeAt(true, startNode); | ||
return marker; | ||
}; | ||
/** | ||
* Inserts start/end markers for the current selection | ||
* which can be used by restoreRange to re-select the | ||
* range. | ||
* | ||
* @memberOf RangeHelper.prototype | ||
* @function | ||
* @name insertMarkers | ||
*/ | ||
base.insertMarkers = function () { | ||
base.insertNodeAt(true, _createMarker(startMarker)); | ||
// Fixes issue with end marker sometimes being placed before | ||
// the start marker when the range is collapsed. | ||
if (currentRange && currentRange.collapsed) { | ||
startNode.parentNode.insertBefore( | ||
_createMarker(endMarker), startNode.nextSibling); | ||
} else { | ||
base.insertNodeAt(false, _createMarker(endMarker)); | ||
}; | ||
} | ||
}; | ||
/** | ||
* Gets the marker with the specified ID | ||
* | ||
* @param {string} id | ||
* @return {Node} | ||
* @function | ||
* @name getMarker | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getMarker = function (id) { | ||
return doc.getElementById(id); | ||
}; | ||
/** | ||
* Gets the marker with the specified ID | ||
* | ||
* @param {string} id | ||
* @return {Node} | ||
* @function | ||
* @name getMarker | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getMarker = function (id) { | ||
return doc.getElementById(id); | ||
}; | ||
/** | ||
* Removes the marker with the specified ID | ||
* | ||
* @param {string} id | ||
* @function | ||
* @name removeMarker | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.removeMarker = function (id) { | ||
var marker = base.getMarker(id); | ||
/** | ||
* Removes the marker with the specified ID | ||
* | ||
* @param {string} id | ||
* @function | ||
* @name removeMarker | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.removeMarker = function (id) { | ||
var marker = base.getMarker(id); | ||
if (marker) { | ||
marker.parentNode.removeChild(marker); | ||
} | ||
}; | ||
if (marker) { | ||
dom.remove(marker); | ||
} | ||
}; | ||
/** | ||
* Removes the start/end markers | ||
* | ||
* @function | ||
* @name removeMarkers | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.removeMarkers = function () { | ||
base.removeMarker(startMarker); | ||
base.removeMarker(endMarker); | ||
}; | ||
/** | ||
* Removes the start/end markers | ||
* | ||
* @function | ||
* @name removeMarkers | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.removeMarkers = function () { | ||
base.removeMarker(startMarker); | ||
base.removeMarker(endMarker); | ||
}; | ||
/** | ||
* Saves the current range location. Alias of insertMarkers() | ||
* | ||
* @function | ||
* @name saveRage | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.saveRange = function () { | ||
base.insertMarkers(); | ||
}; | ||
/** | ||
* Saves the current range location. Alias of insertMarkers() | ||
* | ||
* @function | ||
* @name saveRage | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.saveRange = function () { | ||
base.insertMarkers(); | ||
}; | ||
/** | ||
* Select the specified range | ||
* | ||
* @param {Range|TextRange} range | ||
* @function | ||
* @name selectRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectRange = function (range) { | ||
if (isW3C) { | ||
var lastChild; | ||
var sel = win.getSelection(); | ||
var container = range.endContainer; | ||
/** | ||
* Select the specified range | ||
* | ||
* @param {Range} range | ||
* @function | ||
* @name selectRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectRange = function (range) { | ||
var lastChild; | ||
var sel = win.getSelection(); | ||
var container = range.endContainer; | ||
// Check if cursor is set after a BR when the BR is the only | ||
// child of the parent. In Firefox this causes a line break | ||
// to occur when something is typed. See issue #321 | ||
if (!IE_BR_FIX && range.collapsed && container && | ||
!dom.isInline(container, true)) { | ||
// Check if cursor is set after a BR when the BR is the only | ||
// child of the parent. In Firefox this causes a line break | ||
// to occur when something is typed. See issue #321 | ||
if (!IE_BR_FIX && range.collapsed && container && | ||
!dom.isInline(container, true)) { | ||
lastChild = container.lastChild; | ||
while (lastChild && $(lastChild).is('.sceditor-ignore')) { | ||
lastChild = lastChild.previousSibling; | ||
} | ||
lastChild = container.lastChild; | ||
while (lastChild && dom.is(lastChild, '.sceditor-ignore')) { | ||
lastChild = lastChild.previousSibling; | ||
} | ||
if ($(lastChild).is('br')) { | ||
var rng = doc.createRange(); | ||
rng.setEndAfter(lastChild); | ||
rng.collapse(false); | ||
if (dom.is(lastChild, 'br')) { | ||
var rng = doc.createRange(); | ||
rng.setEndAfter(lastChild); | ||
rng.collapse(false); | ||
if (base.compare(range, rng)) { | ||
range.setStartBefore(lastChild); | ||
range.collapse(true); | ||
} | ||
} | ||
if (base.compare(range, rng)) { | ||
range.setStartBefore(lastChild); | ||
range.collapse(true); | ||
} | ||
if (sel) { | ||
base.clear(); | ||
sel.addRange(range); | ||
} | ||
} else { | ||
range.select(); | ||
} | ||
}; | ||
} | ||
/** | ||
* Restores the last range saved by saveRange() or insertMarkers() | ||
* | ||
* @function | ||
* @name restoreRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.restoreRange = function () { | ||
var marker, isCollapsed, previousSibling, | ||
range = base.selectedRange(), | ||
start = base.getMarker(startMarker), | ||
end = base.getMarker(endMarker); | ||
if (sel) { | ||
base.clear(); | ||
sel.addRange(range); | ||
} | ||
}; | ||
if (!start || !end || !range) { | ||
return false; | ||
} | ||
/** | ||
* Restores the last range saved by saveRange() or insertMarkers() | ||
* | ||
* @function | ||
* @name restoreRange | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.restoreRange = function () { | ||
var isCollapsed, | ||
range = base.selectedRange(), | ||
start = base.getMarker(startMarker), | ||
end = base.getMarker(endMarker); | ||
isCollapsed = start.nextSibling === end; | ||
if (!start || !end || !range) { | ||
return false; | ||
} | ||
if (!isW3C) { | ||
range = doc.body.createTextRange(); | ||
marker = doc.body.createTextRange(); | ||
isCollapsed = start.nextSibling === end; | ||
// IE < 9 cannot set focus after a BR so need to insert | ||
// a dummy char after it to allow the cursor to be placed | ||
previousSibling = start.previousSibling; | ||
if (start.nextSibling === end && (!previousSibling || | ||
!dom.isInline(previousSibling, true) || | ||
$(previousSibling).is('br'))) { | ||
$(start).before('\u200B'); | ||
} | ||
range = doc.createRange(); | ||
range.setStartBefore(start); | ||
range.setEndAfter(end); | ||
marker.moveToElementText(start); | ||
range.setEndPoint('StartToStart', marker); | ||
range.moveStart(CHARACTER, 0); | ||
if (isCollapsed) { | ||
range.collapse(true); | ||
} | ||
marker.moveToElementText(end); | ||
range.setEndPoint('EndToStart', marker); | ||
range.moveEnd(CHARACTER, 0); | ||
} else { | ||
range = doc.createRange(); | ||
base.selectRange(range); | ||
base.removeMarkers(); | ||
}; | ||
range.setStartBefore(start); | ||
range.setEndAfter(end); | ||
} | ||
/** | ||
* Selects the text left and right of the current selection | ||
* | ||
* @param {number} left | ||
* @param {number} right | ||
* @since 1.4.3 | ||
* @function | ||
* @name selectOuterText | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectOuterText = function (left, right) { | ||
var start, end, | ||
range = base.cloneSelected(); | ||
if (isCollapsed) { | ||
range.collapse(true); | ||
} | ||
if (!range) { | ||
return false; | ||
} | ||
base.selectRange(range); | ||
base.removeMarkers(); | ||
}; | ||
range.collapse(false); | ||
/** | ||
* Selects the text left and right of the current selection | ||
* | ||
* @param {int} left | ||
* @param {int} right | ||
* @since 1.4.3 | ||
* @function | ||
* @name selectOuterText | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.selectOuterText = function (left, right) { | ||
var start, end, | ||
range = base.cloneSelected(); | ||
start = outerText(range, true, left); | ||
end = outerText(range, false, right); | ||
if (!range) { | ||
return false; | ||
} | ||
range.setStart(start.node, start.offset); | ||
range.setEnd(end.node, end.offset); | ||
range.collapse(false); | ||
base.selectRange(range); | ||
}; | ||
if (!isW3C) { | ||
range.moveStart(CHARACTER, 0 - left); | ||
range.moveEnd(CHARACTER, right); | ||
} else { | ||
start = outerText(range, true, left); | ||
end = outerText(range, false, right); | ||
/** | ||
* Gets the text left or right of the current selection | ||
* | ||
* @param {boolean} before | ||
* @param {number} length | ||
* @return {string} | ||
* @since 1.4.3 | ||
* @function | ||
* @name selectOuterText | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getOuterText = function (before, length) { | ||
var range = base.cloneSelected(); | ||
range.setStart(start.node, start.offset); | ||
range.setEnd(end.node, end.offset); | ||
} | ||
if (!range) { | ||
return ''; | ||
} | ||
base.selectRange(range); | ||
}; | ||
range.collapse(!before); | ||
/** | ||
* Gets the text left or right of the current selection | ||
* | ||
* @param {boolean} before | ||
* @param {number} length | ||
* @since 1.4.3 | ||
* @function | ||
* @name selectOuterText | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.getOuterText = function (before, length) { | ||
var range = base.cloneSelected(); | ||
return outerText(range, before, length).text; | ||
}; | ||
if (!range) { | ||
return ''; | ||
} | ||
/** | ||
* Replaces keywords with values based on the current caret position | ||
* | ||
* @param {Array} keywords | ||
* @param {boolean} includeAfter If to include the text after the | ||
* current caret position or just | ||
* text before | ||
* @param {boolean} keywordsSorted If the keywords array is pre | ||
* sorted shortest to longest | ||
* @param {number} longestKeyword Length of the longest keyword | ||
* @param {boolean} requireWhitespace If the key must be surrounded | ||
* by whitespace | ||
* @param {string} keypressChar If this is being called from | ||
* a keypress event, this should be | ||
* set to the pressed character | ||
* @return {boolean} | ||
* @function | ||
* @name replaceKeyword | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
// eslint-disable-next-line max-params | ||
base.replaceKeyword = function ( | ||
keywords, | ||
includeAfter, | ||
keywordsSorted, | ||
longestKeyword, | ||
requireWhitespace, | ||
keypressChar | ||
) { | ||
if (!keywordsSorted) { | ||
keywords.sort(function (a, b) { | ||
return a[0].length - b[0].length; | ||
}); | ||
} | ||
range.collapse(!before); | ||
var outerText, match, matchPos, startIndex, | ||
leftLen, charsLeft, keyword, keywordLen, | ||
whitespaceRegex = '(^|[\\s\xA0\u2002\u2003\u2009])', | ||
keywordIdx = keywords.length, | ||
whitespaceLen = requireWhitespace ? 1 : 0, | ||
maxKeyLen = longestKeyword || | ||
keywords[keywordIdx - 1][0].length; | ||
if (!isW3C) { | ||
if (before) { | ||
range.moveStart(CHARACTER, 0 - length); | ||
} else { | ||
range.moveEnd(CHARACTER, length); | ||
} | ||
if (requireWhitespace) { | ||
maxKeyLen++; | ||
} | ||
return range.text; | ||
} | ||
keypressChar = keypressChar || ''; | ||
outerText = base.getOuterText(true, maxKeyLen); | ||
leftLen = outerText.length; | ||
outerText += keypressChar; | ||
return outerText(range, before, length).text; | ||
}; | ||
if (includeAfter) { | ||
outerText += base.getOuterText(false, maxKeyLen); | ||
} | ||
/** | ||
* Replaces keywords with values based on the current caret position | ||
* | ||
* @param {Array} keywords | ||
* @param {boolean} includeAfter If to include the text after the | ||
* current caret position or just | ||
* text before | ||
* @param {boolean} keywordsSorted If the keywords array is pre | ||
* sorted shortest to longest | ||
* @param {number} longestKeyword Length of the longest keyword | ||
* @param {boolean} requireWhitespace If the key must be surrounded | ||
* by whitespace | ||
* @param {string} keypressChar If this is being called from | ||
* a keypress event, this should be | ||
* set to the pressed character | ||
* @return {boolean} | ||
* @function | ||
* @name replaceKeyword | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
/*jshint maxparams: false*/ | ||
base.replaceKeyword = function ( | ||
keywords, | ||
includeAfter, | ||
keywordsSorted, | ||
longestKeyword, | ||
requireWhitespace, | ||
keypressChar | ||
) { | ||
if (!keywordsSorted) { | ||
keywords.sort(function (a, b) { | ||
return a[0].length - b[0].length; | ||
}); | ||
} | ||
while (keywordIdx--) { | ||
keyword = keywords[keywordIdx][0]; | ||
keywordLen = keyword.length; | ||
startIndex = Math.max(0, leftLen - keywordLen - whitespaceLen); | ||
matchPos = -1; | ||
var outerText, matchPos, startIndex, leftLen, | ||
charsLeft, keyword, keywordLen, | ||
whitespaceRegex = '[\\s\xA0\u2002\u2003\u2009]', | ||
keywordIdx = keywords.length, | ||
whitespaceLen = requireWhitespace ? 1 : 0, | ||
maxKeyLen = longestKeyword || | ||
keywords[keywordIdx - 1][0].length; | ||
if (requireWhitespace) { | ||
match = outerText | ||
.substr(startIndex) | ||
.match(new RegExp(whitespaceRegex + | ||
escape.regex(keyword) + whitespaceRegex)); | ||
if (requireWhitespace) { | ||
// requireWhitespace doesn't work with textRanges as they | ||
// select text on the other side of elements causing | ||
// space-img-key to match when it shouldn't. | ||
if (!isW3C) { | ||
return false; | ||
if (match) { | ||
// Add the length of the text that was removed by | ||
// substr() and also add 1 for the whitespace | ||
matchPos = match.index + startIndex + match[1].length; | ||
} | ||
maxKeyLen++; | ||
} else { | ||
matchPos = outerText.indexOf(keyword, startIndex); | ||
} | ||
keypressChar = keypressChar || ''; | ||
outerText = base.getOuterText(true, maxKeyLen); | ||
leftLen = outerText.length; | ||
outerText += keypressChar; | ||
if (matchPos > -1) { | ||
// Make sure the match is between before and | ||
// after, not just entirely in one side or the other | ||
if (matchPos <= leftLen && | ||
matchPos + keywordLen + whitespaceLen >= leftLen) { | ||
charsLeft = leftLen - matchPos; | ||
if (includeAfter) { | ||
outerText += base.getOuterText(false, maxKeyLen); | ||
} | ||
// If the keypress char is white space then it should | ||
// not be replaced, only chars that are part of the | ||
// key should be replaced. | ||
base.selectOuterText( | ||
charsLeft, | ||
keywordLen - charsLeft - | ||
(/^\S/.test(keypressChar) ? 1 : 0) | ||
); | ||
while (keywordIdx--) { | ||
keyword = keywords[keywordIdx][0]; | ||
keywordLen = keyword.length; | ||
startIndex = Math.max(0, leftLen - keywordLen - whitespaceLen); | ||
if (requireWhitespace) { | ||
matchPos = outerText | ||
.substr(startIndex) | ||
.search(new RegExp( | ||
'(?:' + whitespaceRegex + ')' + | ||
escape.regex(keyword) + | ||
'(?=' + whitespaceRegex + ')' | ||
)); | ||
} else { | ||
matchPos = outerText.indexOf(keyword, startIndex); | ||
base.insertHTML(keywords[keywordIdx][1]); | ||
return true; | ||
} | ||
if (matchPos > -1) { | ||
// Add the length of the text that was removed by substr() | ||
// when matching and also add 1 for the whitespace | ||
if (requireWhitespace) { | ||
matchPos += startIndex + 1; | ||
} | ||
// Make sure the match is between before and | ||
// after, not just entirely in one side or the other | ||
if (matchPos <= leftLen && | ||
matchPos + keywordLen + whitespaceLen >= leftLen) { | ||
charsLeft = leftLen - matchPos; | ||
// If the keypress char is white space then it should | ||
// not be replaced, only chars that are part of the | ||
// key should be replaced. | ||
base.selectOuterText( | ||
charsLeft, | ||
keywordLen - charsLeft - | ||
(/^\S/.test(keypressChar) ? 1 : 0) | ||
); | ||
base.insertHTML(keywords[keywordIdx][1]); | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
}; | ||
return false; | ||
}; | ||
/** | ||
* Compares two ranges. | ||
* | ||
* If rangeB is undefined it will be set to | ||
* the current selected range | ||
* | ||
* @param {Range|TextRange} rangeA | ||
* @param {Range|TextRange} rangeB | ||
* @return {boolean} | ||
*/ | ||
base.compare = function (rangeA, rangeB) { | ||
var END_TO_END = isW3C ? Range.END_TO_END : 'EndToEnd', | ||
START_TO_START = isW3C ? Range.START_TO_START : 'StartToStart', | ||
comparePoints = isW3C ? | ||
'compareBoundaryPoints' : | ||
'compareEndPoints'; | ||
/** | ||
* Compares two ranges. | ||
* | ||
* If rangeB is undefined it will be set to | ||
* the current selected range | ||
* | ||
* @param {Range} rngA | ||
* @param {Range} [rngB] | ||
* @return {boolean} | ||
* @function | ||
* @name compare | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.compare = function (rngA, rngB) { | ||
if (!rngB) { | ||
rngB = base.selectedRange(); | ||
} | ||
if (!rangeB) { | ||
rangeB = base.selectedRange(); | ||
} | ||
if (!rngA || !rngB) { | ||
return !rngA && !rngB; | ||
} | ||
if (!rangeA || !rangeB) { | ||
return !rangeA && !rangeB; | ||
} | ||
return rngA.compareBoundaryPoints(Range.END_TO_END, rngB) === 0 && | ||
rngA.compareBoundaryPoints(Range.START_TO_START, rngB) === 0; | ||
}; | ||
return _isOwner(rangeA) && _isOwner(rangeB) && | ||
rangeA[comparePoints](END_TO_END, rangeB) === 0 && | ||
rangeA[comparePoints](START_TO_START, rangeB) === 0; | ||
}; | ||
/** | ||
* Removes any current selection | ||
* | ||
* @since 1.4.6 | ||
* @function | ||
* @name clear | ||
* @memberOf RangeHelper.prototype | ||
*/ | ||
base.clear = function () { | ||
var sel = win.getSelection(); | ||
/** | ||
* Removes any current selection | ||
* | ||
* @since 1.4.6 | ||
*/ | ||
base.clear = function () { | ||
var sel = isW3C ? win.getSelection() : doc.selection; | ||
if (sel) { | ||
if (sel.removeAllRanges) { | ||
sel.removeAllRanges(); | ||
} else if (sel.empty) { | ||
sel.empty(); | ||
} | ||
if (sel) { | ||
if (sel.removeAllRanges) { | ||
sel.removeAllRanges(); | ||
} else if (sel.empty) { | ||
sel.empty(); | ||
} | ||
}; | ||
} | ||
}; | ||
return RangeHelper; | ||
}); | ||
}; |
@@ -1,119 +0,119 @@ | ||
define(function () { | ||
'use strict'; | ||
import * as dom from './dom'; | ||
import * as escape from './escape'; | ||
/** | ||
* HTML templates used by the editor and default commands | ||
* @type {Object} | ||
* @private | ||
*/ | ||
var _templates = { | ||
html: | ||
'<!DOCTYPE html>' + | ||
'<html{attrs}>' + | ||
'<head>' + | ||
// TODO: move these styles into the CSS file | ||
'<style>.ie * {min-height: auto !important} ' + | ||
'.ie table td {height:15px} ' + | ||
// Target Edge (fixes edge issues) | ||
'@supports (-ms-ime-align:auto) { ' + | ||
'* { min-height: auto !important; } ' + | ||
'}' + | ||
'</style>' + | ||
'<meta http-equiv="Content-Type" ' + | ||
'content="text/html;charset={charset}" />' + | ||
'<link rel="stylesheet" type="text/css" href="{style}" />' + | ||
'</head>' + | ||
'<body contenteditable="true" {spellcheck}><p></p></body>' + | ||
'</html>', | ||
toolbarButton: '<a class="sceditor-button sceditor-button-{name}" ' + | ||
'data-sceditor-command="{name}" unselectable="on">' + | ||
'<div unselectable="on">{dispName}</div></a>', | ||
/** | ||
* HTML templates used by the editor and default commands | ||
* @type {Object} | ||
* @private | ||
*/ | ||
var _templates = { | ||
html: | ||
'<!DOCTYPE html>' + | ||
'<html{attrs}>' + | ||
'<head>' + | ||
'<style>.ie * {min-height: auto !important} ' + | ||
'.ie table td {height:15px} ' + | ||
// Target Edge (fixes edge issues) | ||
'@supports (-ms-ime-align:auto) { ' + | ||
'* { min-height: auto !important; } ' + | ||
'}' + | ||
'</style>' + | ||
'<meta http-equiv="Content-Type" ' + | ||
'content="text/html;charset={charset}" />' + | ||
'<link rel="stylesheet" type="text/css" href="{style}" />' + | ||
'</head>' + | ||
'<body contenteditable="true" {spellcheck}><p></p></body>' + | ||
'</html>', | ||
emoticon: '<img src="{url}" data-sceditor-emoticon="{key}" ' + | ||
'alt="{key}" title="{tooltip}" />', | ||
toolbarButton: '<a class="sceditor-button sceditor-button-{name}" ' + | ||
'data-sceditor-command="{name}" unselectable="on">' + | ||
'<div unselectable="on">{dispName}</div></a>', | ||
fontOpt: '<a class="sceditor-font-option" href="#" ' + | ||
'data-font="{font}"><font face="{font}">{font}</font></a>', | ||
emoticon: '<img src="{url}" data-sceditor-emoticon="{key}" ' + | ||
'alt="{key}" title="{tooltip}" />', | ||
sizeOpt: '<a class="sceditor-fontsize-option" data-size="{size}" ' + | ||
'href="#"><font size="{size}">{size}</font></a>', | ||
fontOpt: '<a class="sceditor-font-option" href="#" ' + | ||
'data-font="{font}"><font face="{font}">{font}</font></a>', | ||
pastetext: | ||
'<div><label for="txt">{label}</label> ' + | ||
'<textarea cols="20" rows="7" id="txt"></textarea></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
sizeOpt: '<a class="sceditor-fontsize-option" data-size="{size}" ' + | ||
'href="#"><font size="{size}">{size}</font></a>', | ||
table: | ||
'<div><label for="rows">{rows}</label><input type="text" ' + | ||
'id="rows" value="2" /></div>' + | ||
'<div><label for="cols">{cols}</label><input type="text" ' + | ||
'id="cols" value="2" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}"' + | ||
' /></div>', | ||
image: | ||
'<div><label for="link">{url}</label> ' + | ||
'<input type="text" id="image" placeholder="http://" /></div>' + | ||
'<div><label for="width">{width}</label> ' + | ||
'<input type="text" id="width" size="2" /></div>' + | ||
'<div><label for="height">{height}</label> ' + | ||
'<input type="text" id="height" size="2" /></div>' + | ||
pastetext: | ||
'<div><label for="txt">{label}</label> ' + | ||
'<textarea cols="20" rows="7" id="txt"></textarea></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
'</div>', | ||
email: | ||
'<div><label for="email">{label}</label> ' + | ||
'<input type="text" id="email" /></div>' + | ||
'<div><label for="des">{desc}</label> ' + | ||
'<input type="text" id="des" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
table: | ||
'<div><label for="rows">{rows}</label><input type="text" ' + | ||
'id="rows" value="2" /></div>' + | ||
'<div><label for="cols">{cols}</label><input type="text" ' + | ||
'id="cols" value="2" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}"' + | ||
' /></div>', | ||
link: | ||
'<div><label for="link">{url}</label> ' + | ||
'<input type="text" id="link" placeholder="http://" /></div>' + | ||
'<div><label for="des">{desc}</label> ' + | ||
'<input type="text" id="des" /></div>' + | ||
'<div><input type="button" class="button" value="{ins}" /></div>', | ||
image: | ||
'<div><label for="link">{url}</label> ' + | ||
'<input type="text" id="image" placeholder="https://" /></div>' + | ||
'<div><label for="width">{width}</label> ' + | ||
'<input type="text" id="width" size="2" /></div>' + | ||
'<div><label for="height">{height}</label> ' + | ||
'<input type="text" id="height" size="2" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
youtubeMenu: | ||
'<div><label for="link">{label}</label> ' + | ||
'<input type="text" id="link" placeholder="https://" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
email: | ||
'<div><label for="email">{label}</label> ' + | ||
'<input type="text" id="email" /></div>' + | ||
'<div><label for="des">{desc}</label> ' + | ||
'<input type="text" id="des" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
youtube: | ||
'<iframe width="560" height="315" ' + | ||
'src="https://www.youtube.com/embed/{id}?wmode=opaque" ' + | ||
'data-youtube-id="{id}" frameborder="0" allowfullscreen></iframe>' | ||
}; | ||
link: | ||
'<div><label for="link">{url}</label> ' + | ||
'<input type="text" id="link" placeholder="https://" /></div>' + | ||
'<div><label for="des">{desc}</label> ' + | ||
'<input type="text" id="des" /></div>' + | ||
'<div><input type="button" class="button" value="{ins}" /></div>', | ||
/** | ||
* <p>Replaces any params in a template with the passed params.</p> | ||
* | ||
* <p>If createHtml is passed it will use jQuery to create the HTML. The | ||
* same as doing: $(editor.tmpl("html", {params...}));</p> | ||
* | ||
* @param {string} name | ||
* @param {Object} params | ||
* @param {Boolean} createHtml | ||
* @private | ||
*/ | ||
return function (name, params, createHtml) { | ||
var template = _templates[name]; | ||
youtubeMenu: | ||
'<div><label for="link">{label}</label> ' + | ||
'<input type="text" id="link" placeholder="https://" /></div>' + | ||
'<div><input type="button" class="button" value="{insert}" />' + | ||
'</div>', | ||
$.each(params, function (name, val) { | ||
template = template.replace( | ||
new RegExp('\\{' + name + '\\}', 'g'), val | ||
); | ||
}); | ||
youtube: | ||
'<iframe width="560" height="315" frameborder="0" allowfullscreen' + | ||
'src="https://www.youtube.com/embed/{id}?wmode=opaque&start={time}" ' + | ||
'data-youtube-id="{id}"></iframe>' | ||
}; | ||
if (createHtml) { | ||
template = $(template); | ||
} | ||
/** | ||
* Replaces any params in a template with the passed params. | ||
* | ||
* If createHtml is passed it will return a DocumentFragment | ||
* containing the parsed template. | ||
* | ||
* @param {string} name | ||
* @param {Object} [params] | ||
* @param {boolean} [createHtml] | ||
* @returns {string|DocumentFragment} | ||
* @private | ||
*/ | ||
export default function (name, params, createHtml) { | ||
var template = _templates[name]; | ||
return template; | ||
}; | ||
}); | ||
Object.keys(params).forEach(function (name) { | ||
template = template.replace( | ||
new RegExp(escape.regex('{' + name + '}'), 'g'), params[name] | ||
); | ||
}); | ||
if (createHtml) { | ||
template = dom.parseHTML(template); | ||
} | ||
return template; | ||
}; |
@@ -12,8 +12,7 @@ /** | ||
* @author Sam Clarke | ||
* @requires jQuery | ||
*/ | ||
(function ($) { | ||
(function (sceditor) { | ||
'use strict'; | ||
$.sceditor.plugins.format = function () { | ||
sceditor.plugins.format = function () { | ||
var base = this; | ||
@@ -61,3 +60,3 @@ | ||
if (pOpts.excludeTags) { | ||
$.each(pOpts.excludeTags, function (idx, val) { | ||
pOpts.excludeTags.forEach(function (val) { | ||
delete tags[val]; | ||
@@ -76,3 +75,3 @@ }); | ||
if (opts.toolbar === $.sceditor.defaultOptions.toolbar) { | ||
if (opts.toolbar === sceditor.defaultOptions.toolbar) { | ||
opts.toolbar = opts.toolbar.replace(',color,', | ||
@@ -107,9 +106,9 @@ ',color,format,'); | ||
var editor = this, | ||
$content = $('<div />'); | ||
content = document.createElement('div'); | ||
$.each(tags, function (tag, val) { | ||
$( | ||
'<a class="sceditor-option" href="#">' + | ||
(val.name || val) + '</a>' | ||
).click(function () { | ||
sceditor.utils.each(tags, function (tag, val) { | ||
var link = document.createElement('a'); | ||
link.className = 'sceditor-option'; | ||
link.textContent = val.name || val; | ||
link.addEventListener('click', function (e) { | ||
editor.closeDropDown(true); | ||
@@ -123,10 +122,11 @@ | ||
return false; | ||
}) | ||
.appendTo($content); | ||
e.preventDefault(); | ||
}); | ||
content.appendChild(link); | ||
}); | ||
editor.createDropDown(caller, 'format', $content); | ||
editor.createDropDown(caller, 'format', content); | ||
}; | ||
}; | ||
})(jQuery); | ||
})(sceditor); |
@@ -1,5 +0,5 @@ | ||
(function ($) { | ||
(function (sceditor) { | ||
'use strict'; | ||
$.sceditor.plugins.undo = function () { | ||
sceditor.plugins.undo = function () { | ||
var base = this; | ||
@@ -41,3 +41,3 @@ var editor; | ||
/** | ||
* Caluclates the number of characters that have changed | ||
* Calculates the number of characters that have changed | ||
* between two strings. | ||
@@ -150,7 +150,7 @@ * | ||
* the rangeHelper range markers inserted, or it will be the raw value | ||
* of the source editor (BBCode or HTML depening on plugins). | ||
* of the source editor (BBCode or HTML depending on plugins). | ||
* @return {void} | ||
*/ | ||
base.signalValuechangedEvent = function (e) { | ||
var rawValue = e.rawValue; | ||
var rawValue = e.detail.rawValue; | ||
@@ -189,2 +189,2 @@ if (undoLimit > 0 && undoStates.length > undoLimit) { | ||
}; | ||
}(jQuery)); | ||
}(sceditor)); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12913
128
862315
174
1