From f26acaeb99cb6a5221da835de558e50ad93a3a7a Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Thu, 25 May 2017 01:13:15 +0000 Subject: [PATCH] TinyMCE: update to 4.6.2. Changelog: https://www.tinymce.com/docs/changelog/#version462-may232017. Fixes #40859 #40756. git-svn-id: https://develop.svn.wordpress.org/trunk@40834 602fd350-edb4-49c9-b593-d223f7449a82 --- .../js/tinymce/plugins/paste/plugin.js | 2 +- .../js/tinymce/plugins/paste/plugin.min.js | 2 +- .../js/tinymce/themes/modern/theme.js | 40 +- .../js/tinymce/themes/modern/theme.min.js | 2 +- src/wp-includes/js/tinymce/tinymce.js | 5783 +++++++++-------- src/wp-includes/js/tinymce/tinymce.min.js | 28 +- src/wp-includes/version.php | 2 +- 7 files changed, 3270 insertions(+), 2589 deletions(-) diff --git a/src/wp-includes/js/tinymce/plugins/paste/plugin.js b/src/wp-includes/js/tinymce/plugins/paste/plugin.js index a8296e5dfa..cb191b69c0 100644 --- a/src/wp-includes/js/tinymce/plugins/paste/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/paste/plugin.js @@ -517,7 +517,7 @@ define( var getData = function (editor) { return { - html: editor.selection.getContent(), + html: editor.selection.getContent({ contextual: true }), text: editor.selection.getContent({ format: 'text' }) }; }; diff --git a/src/wp-includes/js/tinymce/plugins/paste/plugin.min.js b/src/wp-includes/js/tinymce/plugins/paste/plugin.min.js index 6d9ec7a6f7..5bbb85d7c0 100644 --- a/src/wp-includes/js/tinymce/plugins/paste/plugin.min.js +++ b/src/wp-includes/js/tinymce/plugins/paste/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i",c=function(a){return b+a},d=function(a){return a.replace(b,"")},e=function(a){return a.indexOf(b)!==-1};return{mark:c,unmark:d,isMarked:e,internalHtmlMime:function(){return a}}}),g("g",["6"],function(a){return a("tinymce.html.DomParser")}),g("h",["6"],function(a){return a("tinymce.html.Schema")}),g("d",["a","g","h"],function(a,b,c){function d(b,c){return a.each(c,function(a){b=a.constructor==RegExp?b.replace(a,""):b.replace(a[0],a[1])}),b}function e(e){function f(a){var b=a.name,c=a;if("br"===b)return void(i+="\n");if(j[b]&&(i+=" "),k[b])return void(i+=" ");if(3==a.type&&(i+=a.value),!a.shortEnded&&(a=a.firstChild))do f(a);while(a=a.next);l[b]&&c.next&&(i+="\n","p"==b&&(i+="\n"))}var g=new c,h=new b({},g),i="",j=g.getShortEndedElements(),k=a.makeMap("script noscript style textarea video audio iframe object"," "),l=g.getBlockElements();return e=d(e,[//g]),f(h.parse(e)),i}function f(a){function b(a,b,c){return b||c?"\xa0":" "}return a=d(a,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/gi,/|/g,[/( ?)\u00a0<\/span>( ?)/g,b],/
/g,/
$/i])}function g(a){var b=0;return function(){return a+b++}}var h=function(){return navigator.userAgent.indexOf(" Edge/")!==-1};return{filter:d,innerText:e,trimHtml:f,createIdGenerator:g,isMsEdge:h}}),g("3",["8","c","d"],function(a,b,c){var d=function(){},e=function(b){return a.iOS===!1&&void 0!==b&&"function"==typeof b.setData&&c.isMsEdge()!==!0},f=function(a,c,d){if(!e(a))return!1;try{return a.clearData(),a.setData("text/html",c),a.setData("text/plain",d),a.setData(b.internalHtmlMime(),c),!0}catch(a){return!1}},g=function(a,b,c,d){f(a.clipboardData,b.html,b.text)?(a.preventDefault(),d()):c(b.html,d)},h=function(a){return function(c,d){var e=b.mark(c),f=a.dom.create("div",{contenteditable:"false"}),g=a.dom.create("div",{contenteditable:"true"},e);a.dom.setStyles(f,{position:"fixed",left:"-3000px",width:"1000px",overflow:"hidden"}),f.appendChild(g),a.dom.add(a.getBody(),f);var h=a.selection.getRng();g.focus();var i=a.dom.createRng();i.selectNodeContents(g),a.selection.setRng(i),setTimeout(function(){f.parentNode.removeChild(f),a.selection.setRng(h),d()},0)}},i=function(a){return{html:a.selection.getContent(),text:a.selection.getContent({format:"text"})}},j=function(a){return function(b){a.selection.isCollapsed()===!1&&g(b,i(a),h(a),function(){a.execCommand("Delete")})}},k=function(a){return function(b){a.selection.isCollapsed()===!1&&g(b,i(a),h(a),d)}},l=function(a){a.on("cut",j(a)),a.on("copy",k(a))};return{register:l}}),g("k",["6"],function(a){return a("tinymce.html.Entities")}),g("e",["k"],function(a){var b=function(a){return!/<(?:(?!\/?(?:div|p|br))[^>]*|(?:div|p|br)\s+\w[^>]+)>/.test(a)},c=function(a){return a.replace(/\r?\n/g,"
")},d=function(b,c){var d,e=[],f="<"+b;if("object"==typeof c){for(d in c)c.hasOwnProperty(d)&&e.push(d+'="'+a.encodeAllRaw(c[d])+'"');e.length&&(f+=" "+e.join(" "))}return f+">"},e=function(a,b,c){var e,f,g,h=a.split(/\r?\n/),i=0,j=h.length,k=[],l=[],m=d(b,c),n="";if(1===h.length)return a;for(;i")),k=[]),f&&i++;return 1===l.length?l[0]:m+l.join(n+m)+n},f=function(a,b,d){return b?e(a,b,d):c(a)};return{isPlainText:b,convert:f,toBRs:c,toBlockElements:e}}),g("f",["a"],function(a){var b=function(a){return/^https?:\/\/[\w\?\-\/+=.&%@~#]+$/i.test(a)},c=function(a){return b(a)&&/.(gif|jpe?g|png)$/.test(a)},d=function(a,b,c){return a.undoManager.extra(function(){c(a,b)},function(){a.insertContent('')}),!0},e=function(a,b,c){return a.undoManager.extra(function(){c(a,b)},function(){a.execCommand("mceInsertLink",!1,b)}),!0},f=function(a,c,d){return!(a.selection.isCollapsed()!==!1||!b(c))&&e(a,c,d)},g=function(a,b,e){return!!c(b)&&d(a,b,e)},h=function(a,b){return a.insertContent(b,{merge:a.settings.paste_merge_formats!==!1,paste:!0}),!0},i=function(b,c){a.each([f,g,h],function(a){return a(b,c,h)!==!0})},j=function(a,b){a.settings.smart_paste===!1?h(a,b):i(a,b)};return{isImageUrl:c,isAbsoluteUrl:b,insertContent:j}}),g("2",["7","8","9","a","b","3","c","e","f","d"],function(a,b,c,d,e,f,g,h,i,j){return function(f){function k(a,b){var c,d,e=f.dom;if(d=b||g.isMarked(a),a=g.unmark(a),c=f.fire("BeforePastePreProcess",{content:a,internal:d}),c=f.fire("PastePreProcess",c),a=c.content,!c.isDefaultPrevented()){if(f.hasEventListeners("PastePostProcess")&&!c.isDefaultPrevented()){var h=e.add(f.getBody(),"div",{style:"display:none"},a);c=f.fire("PastePostProcess",{node:h,internal:d}),e.remove(h),a=c.node.innerHTML}c.isDefaultPrevented()||i.insertContent(f,a)}}function l(a){a=f.dom.encode(a).replace(/\r\n/g,"\n"),a=h.convert(a,f.settings.forced_root_block,f.settings.forced_root_block_attrs),k(a,!1)}function m(){function a(a){var b,c,e,f=a.startContainer;if(b=a.getClientRects(),b.length)return b[0];if(a.collapsed&&1==f.nodeType){for(e=f.childNodes[C.startOffset];e&&3==e.nodeType&&!e.data.length;)e=e.nextSibling;if(e)return"BR"==e.tagName&&(c=d.doc.createTextNode("\ufeff"),e.parentNode.insertBefore(c,e),a=d.createRng(),a.setStartBefore(c),a.setEndAfter(c),b=a.getClientRects(),d.remove(c)),b.length?b[0]:void 0}}var c,d=f.dom,e=f.getBody(),g=f.dom.getViewPort(f.getWin()),h=g.y,i=20;if(C=f.selection.getRng(),f.inline&&(c=f.selection.getScrollContainer(),c&&c.scrollTop>0&&(h=c.scrollTop)),C.getClientRects){var j=a(C);if(j)i=h+(j.top-d.getPos(e).y);else{i=h;var k=C.startContainer;k&&(3==k.nodeType&&k.parentNode!=e&&(k=k.parentNode),1==k.nodeType&&(i=d.getPos(k,c||e).y))}}B=d.add(f.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"all",style:"position: absolute; top: "+i+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},H),(b.ie||b.gecko)&&d.setStyle(B,"left","rtl"==d.getStyle(e,"direction",!0)?65535:-65535),d.bind(B,"beforedeactivate focusin focusout",function(a){a.stopPropagation()}),B.focus(),f.selection.select(B,!0)}function n(){if(B){for(var a;a=f.dom.get("mcepastebin");)f.dom.remove(a),f.dom.unbind(a);C&&f.selection.setRng(C)}B=C=null}function o(){var a,b,c,d,e="";for(a=f.dom.select("div[id=mcepastebin]"),b=0;b0&&c.indexOf(I)==-1&&(b["text/plain"]=c)}if(a.types)for(var d=0;d',!1)}else k('',!1)}function v(a,b){function c(c){var d,e,f,g=!1;if(c)for(d=0;d0}function z(a){return e.metaKeyPressed(a)&&86==a.keyCode||a.shiftKey&&45==a.keyCode}function A(){function a(a,b,c,d){var e,g;return y(a,"text/html")?e=a["text/html"]:(e=o(),e==H&&(c=!0)),e=j.trimHtml(e),B&&B.firstChild&&"mcepastebin"===B.firstChild.id&&(c=!0),n(),g=d===!1&&h.isPlainText(e),e.length&&!g||(c=!0),c&&(e=y(a,"text/plain")&&g?a["text/plain"]:j.innerText(e)),e==H?void(b||f.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.")):void(c?l(e):k(e,d))}function d(a){var b=a["text/plain"];return!!b&&0===b.indexOf("file://")}f.on("keydown",function(a){function c(a){z(a)&&!a.isDefaultPrevented()&&n()}if(z(a)&&!a.isDefaultPrevented()){if(D=a.shiftKey&&86==a.keyCode,D&&b.webkit&&navigator.userAgent.indexOf("Version/")!=-1)return;if(a.stopImmediatePropagation(),F=(new Date).getTime(),b.ie&&D)return a.preventDefault(),void f.fire("paste",{ieFake:!0});n(),m(),f.once("keyup",c),f.once("paste",function(){f.off("keyup",c)})}});var e=function(){return C||f.selection.getRng()};f.on("paste",function(d){var h=(new Date).getTime(),i=q(d),j=(new Date).getTime()-h,k=(new Date).getTime()-F-j<1e3,l="text"==E.pasteFormat||D,p=y(i,g.internalHtmlMime());return D=!1,d.isDefaultPrevented()||w(d)?void n():!r(i)&&v(d,e())?void n():(k||d.preventDefault(),!b.ie||k&&!d.ieFake||y(i,"text/html")||(m(),f.dom.bind(B,"paste",function(a){a.stopPropagation()}),f.getDoc().execCommand("Paste",!1,null),i["text/html"]=o()),void(y(i,"text/html")?(d.preventDefault(),a(i,k,l,p)):c.setEditorTimeout(f,function(){a(i,k,l,p)},0)))}),f.on("dragstart dragend",function(a){G="dragstart"==a.type}),f.on("drop",function(a){var b,e;if(e=x(a),!a.isDefaultPrevented()&&!G){b=p(a.dataTransfer);var h=y(b,g.internalHtmlMime());if((r(b)&&!d(b)||!v(a,e))&&e&&f.settings.paste_filter_drop!==!1){var i=b["mce-internal"]||b["text/html"]||b["text/plain"];i&&(a.preventDefault(),c.setEditorTimeout(f,function(){f.undoManager.transact(function(){b["mce-internal"]&&f.execCommand("Delete"),f.selection.setRng(e),i=j.trimHtml(i),b["text/html"]?k(i,h):l(i)})}))}}}),f.on("dragover dragend",function(a){f.settings.paste_data_images&&a.preventDefault()})}var B,C,D,E=this,F=0,G=!1,H="%MCEPASTEBIN%",I="data:text/mce-internal,",J=j.createIdGenerator("mceclip");E.pasteHtml=k,E.pasteText=l,E.pasteImageData=v,f.on("preInit",function(){A(),f.parser.addNodeFilter("img",function(a,c,d){function e(a){return a.data&&a.data.paste===!0}function g(a){a.attr("data-mce-object")||k===b.transparentSrc||a.remove()}function h(a){return 0===a.indexOf("webkit-fake-url")}function i(a){return 0===a.indexOf("data:")}if(!f.settings.paste_data_images&&e(d))for(var j=a.length;j--;){var k=a[j].attributes.map.src;k&&(h(k)?g(a[j]):!f.settings.allow_html_data_urls&&i(k)&&g(a[j]))}})})}}),g("i",["6"],function(a){return a("tinymce.html.Serializer")}),g("j",["6"],function(a){return a("tinymce.html.Node")}),g("5",["a","g","h","i","j","d"],function(a,b,c,d,e,f){function g(a){return/1&&g.attr("start",""+f),a.wrap(g)),a.name="li",h>k&&j&&j.lastChild.append(g),k=h,d(a),c(a,/^\u00a0+/),c(a,/^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/),c(a,/^\u00a0+/)}for(var g,j,k=1,l=[],m=a.firstChild;"undefined"!=typeof m&&null!==m;)if(l.push(m),m=m.walk(),null!==m)for(;"undefined"!=typeof m&&m.parent!==a;)m=m.walk();for(var n=0;n]+id="?docs-internal-[^>]*>/gi,""),q=q.replace(/
/gi,""),o=k.paste_retain_style_properties,o&&(p=a.makeMap(o.split(/[, ]/))),k.paste_enable_default_filters!==!1&&g(l.content)){l.wordContent=!0,q=f.filter(q,[//gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(a,b){return b.length>0?b.replace(/./," ").slice(Math.floor(b.length/2)).split("").join("\xa0"):""}]]);var r=k.paste_word_valid_elements;r||(r="-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody");var s=new c({valid_elements:r,valid_children:"-li[p]"});a.each(s.elements,function(a){a.attributes["class"]||(a.attributes["class"]={},a.attributesOrder.push("class")),a.attributes.style||(a.attributes.style={},a.attributesOrder.push("style"))});var t=new b({},s);t.addAttributeFilter("style",function(a){for(var b,c=a.length;c--;)b=a[c],b.attr("style",n(b,b.attr("style"))),"span"==b.name&&b.parent&&!b.attributes.length&&b.unwrap()}),t.addAttributeFilter("class",function(a){for(var b,c,d=a.length;d--;)b=a[d],c=b.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(c)&&b.remove(),b.attr("class",null)}),t.addNodeFilter("del",function(a){for(var b=a.length;b--;)a[b].remove()}),t.addNodeFilter("a",function(a){for(var b,c,d,e=a.length;e--;)if(b=a[e],c=b.attr("href"),d=b.attr("name"),c&&c.indexOf("#_msocom_")!=-1)b.remove();else if(c&&0===c.indexOf("file://")&&(c=c.split("#")[1],c&&(c="#"+c)),c||d){if(d&&!/^_?(?:toc|edn|ftn)/i.test(d)){b.unwrap();continue}b.attr({href:c,name:d})}else b.unwrap()});var u=t.parse(q);k.paste_convert_word_fake_lists!==!1&&m(u),l.content=new d({validate:k.validate},s).serialize(u)}})}return j.isWordContent=g,j}),g("4",["8","a","5","d"],function(a,b,c,d){"use strict";return function(e){function f(a){e.on("BeforePastePreProcess",function(b){b.content=a(b.content)})}function g(a){e.on("PastePostProcess",function(b){a(b.node)})}function h(a){if(!c.isWordContent(a))return a;var f=[];b.each(e.schema.getBlockElements(),function(a,b){f.push(b)});var g=new RegExp("(?:
 [\\s\\r\\n]+|
)*(<\\/?("+f.join("|")+")[^>]*>)(?:
 [\\s\\r\\n]+|
)*","g");return a=d.filter(a,[[g,"$1"]]),a=d.filter(a,[[/

/g,"

"],[/
/g," "],[/

/g,"
"]])}function i(a){if(c.isWordContent(a))return a;var b=e.settings.paste_webkit_styles;if(e.settings.paste_remove_styles_if_webkit===!1||"all"==b)return a;if(b&&(b=b.split(/[, ]/)),b){var d=e.dom,f=e.selection.getNode();a=a.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(a,c,e,g){var h=d.parseStyle(d.decode(e),"span"),i={};if("none"===b)return c+g;for(var j=0;j]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return a=a.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(a,b,c,d){return b+' style="'+c+'"'+d})}function j(a){e.$("a",a).find("font,u").each(function(a,b){e.dom.remove(b,!0)})}a.webkit&&f(i),a.ie&&(f(h),g(j))}}),g("0",["1","2","3","4","5"],function(a,b,c,d,e){var f;return a.add("paste",function(g){function h(){return f||g.settings.paste_plaintext_inform===!1}function i(){if("text"==k.pasteFormat)k.pasteFormat="html",g.fire("PastePlainTextToggle",{state:!1});else if(k.pasteFormat="text",g.fire("PastePlainTextToggle",{state:!0}),!h()){var a=g.translate("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.");g.notificationManager.open({text:a,type:"info"}),f=!0}g.focus()}function j(){var a=this;a.active("text"===k.pasteFormat),g.on("PastePlainTextToggle",function(b){a.active(b.state)})}var k,l=this,m=g.settings;return/(^|[ ,])powerpaste([, ]|$)/.test(m.plugins)&&a.get("powerpaste")?void("undefined"!=typeof console&&console.log&&console.log("PowerPaste is incompatible with Paste plugin! Remove 'paste' from the 'plugins' option.")):(l.clipboard=k=new b(g),l.quirks=new d(g),l.wordFilter=new e(g),g.settings.paste_as_text&&(l.clipboard.pasteFormat="text"),m.paste_preprocess&&g.on("PastePreProcess",function(a){m.paste_preprocess.call(l,l,a)}),m.paste_postprocess&&g.on("PastePostProcess",function(a){m.paste_postprocess.call(l,l,a)}),g.addCommand("mceInsertClipboardContent",function(a,b){b.content&&l.clipboard.pasteHtml(b.content,b.internal),b.text&&l.clipboard.pasteText(b.text)}),g.settings.paste_block_drop&&g.on("dragend dragover draggesture dragdrop drop drag",function(a){a.preventDefault(),a.stopPropagation()}),g.settings.paste_data_images||g.on("drop",function(a){var b=a.dataTransfer;b&&b.files&&b.files.length>0&&a.preventDefault()}),g.addCommand("mceTogglePlainTextPaste",i),g.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:i,onPostRender:j}),g.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:k.pasteFormat,onclick:i,onPostRender:j}),void c.register(g))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i",c=function(a){return b+a},d=function(a){return a.replace(b,"")},e=function(a){return a.indexOf(b)!==-1};return{mark:c,unmark:d,isMarked:e,internalHtmlMime:function(){return a}}}),g("g",["6"],function(a){return a("tinymce.html.DomParser")}),g("h",["6"],function(a){return a("tinymce.html.Schema")}),g("d",["a","g","h"],function(a,b,c){function d(b,c){return a.each(c,function(a){b=a.constructor==RegExp?b.replace(a,""):b.replace(a[0],a[1])}),b}function e(e){function f(a){var b=a.name,c=a;if("br"===b)return void(i+="\n");if(j[b]&&(i+=" "),k[b])return void(i+=" ");if(3==a.type&&(i+=a.value),!a.shortEnded&&(a=a.firstChild))do f(a);while(a=a.next);l[b]&&c.next&&(i+="\n","p"==b&&(i+="\n"))}var g=new c,h=new b({},g),i="",j=g.getShortEndedElements(),k=a.makeMap("script noscript style textarea video audio iframe object"," "),l=g.getBlockElements();return e=d(e,[//g]),f(h.parse(e)),i}function f(a){function b(a,b,c){return b||c?"\xa0":" "}return a=d(a,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/gi,/|/g,[/( ?)\u00a0<\/span>( ?)/g,b],/
/g,/
$/i])}function g(a){var b=0;return function(){return a+b++}}var h=function(){return navigator.userAgent.indexOf(" Edge/")!==-1};return{filter:d,innerText:e,trimHtml:f,createIdGenerator:g,isMsEdge:h}}),g("3",["8","c","d"],function(a,b,c){var d=function(){},e=function(b){return a.iOS===!1&&void 0!==b&&"function"==typeof b.setData&&c.isMsEdge()!==!0},f=function(a,c,d){if(!e(a))return!1;try{return a.clearData(),a.setData("text/html",c),a.setData("text/plain",d),a.setData(b.internalHtmlMime(),c),!0}catch(a){return!1}},g=function(a,b,c,d){f(a.clipboardData,b.html,b.text)?(a.preventDefault(),d()):c(b.html,d)},h=function(a){return function(c,d){var e=b.mark(c),f=a.dom.create("div",{contenteditable:"false"}),g=a.dom.create("div",{contenteditable:"true"},e);a.dom.setStyles(f,{position:"fixed",left:"-3000px",width:"1000px",overflow:"hidden"}),f.appendChild(g),a.dom.add(a.getBody(),f);var h=a.selection.getRng();g.focus();var i=a.dom.createRng();i.selectNodeContents(g),a.selection.setRng(i),setTimeout(function(){f.parentNode.removeChild(f),a.selection.setRng(h),d()},0)}},i=function(a){return{html:a.selection.getContent({contextual:!0}),text:a.selection.getContent({format:"text"})}},j=function(a){return function(b){a.selection.isCollapsed()===!1&&g(b,i(a),h(a),function(){a.execCommand("Delete")})}},k=function(a){return function(b){a.selection.isCollapsed()===!1&&g(b,i(a),h(a),d)}},l=function(a){a.on("cut",j(a)),a.on("copy",k(a))};return{register:l}}),g("k",["6"],function(a){return a("tinymce.html.Entities")}),g("e",["k"],function(a){var b=function(a){return!/<(?:(?!\/?(?:div|p|br))[^>]*|(?:div|p|br)\s+\w[^>]+)>/.test(a)},c=function(a){return a.replace(/\r?\n/g,"
")},d=function(b,c){var d,e=[],f="<"+b;if("object"==typeof c){for(d in c)c.hasOwnProperty(d)&&e.push(d+'="'+a.encodeAllRaw(c[d])+'"');e.length&&(f+=" "+e.join(" "))}return f+">"},e=function(a,b,c){var e,f,g,h=a.split(/\r?\n/),i=0,j=h.length,k=[],l=[],m=d(b,c),n="";if(1===h.length)return a;for(;i")),k=[]),f&&i++;return 1===l.length?l[0]:m+l.join(n+m)+n},f=function(a,b,d){return b?e(a,b,d):c(a)};return{isPlainText:b,convert:f,toBRs:c,toBlockElements:e}}),g("f",["a"],function(a){var b=function(a){return/^https?:\/\/[\w\?\-\/+=.&%@~#]+$/i.test(a)},c=function(a){return b(a)&&/.(gif|jpe?g|png)$/.test(a)},d=function(a,b,c){return a.undoManager.extra(function(){c(a,b)},function(){a.insertContent('')}),!0},e=function(a,b,c){return a.undoManager.extra(function(){c(a,b)},function(){a.execCommand("mceInsertLink",!1,b)}),!0},f=function(a,c,d){return!(a.selection.isCollapsed()!==!1||!b(c))&&e(a,c,d)},g=function(a,b,e){return!!c(b)&&d(a,b,e)},h=function(a,b){return a.insertContent(b,{merge:a.settings.paste_merge_formats!==!1,paste:!0}),!0},i=function(b,c){a.each([f,g,h],function(a){return a(b,c,h)!==!0})},j=function(a,b){a.settings.smart_paste===!1?h(a,b):i(a,b)};return{isImageUrl:c,isAbsoluteUrl:b,insertContent:j}}),g("2",["7","8","9","a","b","3","c","e","f","d"],function(a,b,c,d,e,f,g,h,i,j){return function(f){function k(a,b){var c,d,e=f.dom;if(d=b||g.isMarked(a),a=g.unmark(a),c=f.fire("BeforePastePreProcess",{content:a,internal:d}),c=f.fire("PastePreProcess",c),a=c.content,!c.isDefaultPrevented()){if(f.hasEventListeners("PastePostProcess")&&!c.isDefaultPrevented()){var h=e.add(f.getBody(),"div",{style:"display:none"},a);c=f.fire("PastePostProcess",{node:h,internal:d}),e.remove(h),a=c.node.innerHTML}c.isDefaultPrevented()||i.insertContent(f,a)}}function l(a){a=f.dom.encode(a).replace(/\r\n/g,"\n"),a=h.convert(a,f.settings.forced_root_block,f.settings.forced_root_block_attrs),k(a,!1)}function m(){function a(a){var b,c,e,f=a.startContainer;if(b=a.getClientRects(),b.length)return b[0];if(a.collapsed&&1==f.nodeType){for(e=f.childNodes[C.startOffset];e&&3==e.nodeType&&!e.data.length;)e=e.nextSibling;if(e)return"BR"==e.tagName&&(c=d.doc.createTextNode("\ufeff"),e.parentNode.insertBefore(c,e),a=d.createRng(),a.setStartBefore(c),a.setEndAfter(c),b=a.getClientRects(),d.remove(c)),b.length?b[0]:void 0}}var c,d=f.dom,e=f.getBody(),g=f.dom.getViewPort(f.getWin()),h=g.y,i=20;if(C=f.selection.getRng(),f.inline&&(c=f.selection.getScrollContainer(),c&&c.scrollTop>0&&(h=c.scrollTop)),C.getClientRects){var j=a(C);if(j)i=h+(j.top-d.getPos(e).y);else{i=h;var k=C.startContainer;k&&(3==k.nodeType&&k.parentNode!=e&&(k=k.parentNode),1==k.nodeType&&(i=d.getPos(k,c||e).y))}}B=d.add(f.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"all",style:"position: absolute; top: "+i+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},H),(b.ie||b.gecko)&&d.setStyle(B,"left","rtl"==d.getStyle(e,"direction",!0)?65535:-65535),d.bind(B,"beforedeactivate focusin focusout",function(a){a.stopPropagation()}),B.focus(),f.selection.select(B,!0)}function n(){if(B){for(var a;a=f.dom.get("mcepastebin");)f.dom.remove(a),f.dom.unbind(a);C&&f.selection.setRng(C)}B=C=null}function o(){var a,b,c,d,e="";for(a=f.dom.select("div[id=mcepastebin]"),b=0;b0&&c.indexOf(I)==-1&&(b["text/plain"]=c)}if(a.types)for(var d=0;d',!1)}else k('',!1)}function v(a,b){function c(c){var d,e,f,g=!1;if(c)for(d=0;d0}function z(a){return e.metaKeyPressed(a)&&86==a.keyCode||a.shiftKey&&45==a.keyCode}function A(){function a(a,b,c,d){var e,g;return y(a,"text/html")?e=a["text/html"]:(e=o(),e==H&&(c=!0)),e=j.trimHtml(e),B&&B.firstChild&&"mcepastebin"===B.firstChild.id&&(c=!0),n(),g=d===!1&&h.isPlainText(e),e.length&&!g||(c=!0),c&&(e=y(a,"text/plain")&&g?a["text/plain"]:j.innerText(e)),e==H?void(b||f.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.")):void(c?l(e):k(e,d))}function d(a){var b=a["text/plain"];return!!b&&0===b.indexOf("file://")}f.on("keydown",function(a){function c(a){z(a)&&!a.isDefaultPrevented()&&n()}if(z(a)&&!a.isDefaultPrevented()){if(D=a.shiftKey&&86==a.keyCode,D&&b.webkit&&navigator.userAgent.indexOf("Version/")!=-1)return;if(a.stopImmediatePropagation(),F=(new Date).getTime(),b.ie&&D)return a.preventDefault(),void f.fire("paste",{ieFake:!0});n(),m(),f.once("keyup",c),f.once("paste",function(){f.off("keyup",c)})}});var e=function(){return C||f.selection.getRng()};f.on("paste",function(d){var h=(new Date).getTime(),i=q(d),j=(new Date).getTime()-h,k=(new Date).getTime()-F-j<1e3,l="text"==E.pasteFormat||D,p=y(i,g.internalHtmlMime());return D=!1,d.isDefaultPrevented()||w(d)?void n():!r(i)&&v(d,e())?void n():(k||d.preventDefault(),!b.ie||k&&!d.ieFake||y(i,"text/html")||(m(),f.dom.bind(B,"paste",function(a){a.stopPropagation()}),f.getDoc().execCommand("Paste",!1,null),i["text/html"]=o()),void(y(i,"text/html")?(d.preventDefault(),a(i,k,l,p)):c.setEditorTimeout(f,function(){a(i,k,l,p)},0)))}),f.on("dragstart dragend",function(a){G="dragstart"==a.type}),f.on("drop",function(a){var b,e;if(e=x(a),!a.isDefaultPrevented()&&!G){b=p(a.dataTransfer);var h=y(b,g.internalHtmlMime());if((r(b)&&!d(b)||!v(a,e))&&e&&f.settings.paste_filter_drop!==!1){var i=b["mce-internal"]||b["text/html"]||b["text/plain"];i&&(a.preventDefault(),c.setEditorTimeout(f,function(){f.undoManager.transact(function(){b["mce-internal"]&&f.execCommand("Delete"),f.selection.setRng(e),i=j.trimHtml(i),b["text/html"]?k(i,h):l(i)})}))}}}),f.on("dragover dragend",function(a){f.settings.paste_data_images&&a.preventDefault()})}var B,C,D,E=this,F=0,G=!1,H="%MCEPASTEBIN%",I="data:text/mce-internal,",J=j.createIdGenerator("mceclip");E.pasteHtml=k,E.pasteText=l,E.pasteImageData=v,f.on("preInit",function(){A(),f.parser.addNodeFilter("img",function(a,c,d){function e(a){return a.data&&a.data.paste===!0}function g(a){a.attr("data-mce-object")||k===b.transparentSrc||a.remove()}function h(a){return 0===a.indexOf("webkit-fake-url")}function i(a){return 0===a.indexOf("data:")}if(!f.settings.paste_data_images&&e(d))for(var j=a.length;j--;){var k=a[j].attributes.map.src;k&&(h(k)?g(a[j]):!f.settings.allow_html_data_urls&&i(k)&&g(a[j]))}})})}}),g("i",["6"],function(a){return a("tinymce.html.Serializer")}),g("j",["6"],function(a){return a("tinymce.html.Node")}),g("5",["a","g","h","i","j","d"],function(a,b,c,d,e,f){function g(a){return/1&&g.attr("start",""+f),a.wrap(g)),a.name="li",h>k&&j&&j.lastChild.append(g),k=h,d(a),c(a,/^\u00a0+/),c(a,/^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/),c(a,/^\u00a0+/)}for(var g,j,k=1,l=[],m=a.firstChild;"undefined"!=typeof m&&null!==m;)if(l.push(m),m=m.walk(),null!==m)for(;"undefined"!=typeof m&&m.parent!==a;)m=m.walk();for(var n=0;n]+id="?docs-internal-[^>]*>/gi,""),q=q.replace(/
/gi,""),o=k.paste_retain_style_properties,o&&(p=a.makeMap(o.split(/[, ]/))),k.paste_enable_default_filters!==!1&&g(l.content)){l.wordContent=!0,q=f.filter(q,[//gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(a,b){return b.length>0?b.replace(/./," ").slice(Math.floor(b.length/2)).split("").join("\xa0"):""}]]);var r=k.paste_word_valid_elements;r||(r="-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody");var s=new c({valid_elements:r,valid_children:"-li[p]"});a.each(s.elements,function(a){a.attributes["class"]||(a.attributes["class"]={},a.attributesOrder.push("class")),a.attributes.style||(a.attributes.style={},a.attributesOrder.push("style"))});var t=new b({},s);t.addAttributeFilter("style",function(a){for(var b,c=a.length;c--;)b=a[c],b.attr("style",n(b,b.attr("style"))),"span"==b.name&&b.parent&&!b.attributes.length&&b.unwrap()}),t.addAttributeFilter("class",function(a){for(var b,c,d=a.length;d--;)b=a[d],c=b.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(c)&&b.remove(),b.attr("class",null)}),t.addNodeFilter("del",function(a){for(var b=a.length;b--;)a[b].remove()}),t.addNodeFilter("a",function(a){for(var b,c,d,e=a.length;e--;)if(b=a[e],c=b.attr("href"),d=b.attr("name"),c&&c.indexOf("#_msocom_")!=-1)b.remove();else if(c&&0===c.indexOf("file://")&&(c=c.split("#")[1],c&&(c="#"+c)),c||d){if(d&&!/^_?(?:toc|edn|ftn)/i.test(d)){b.unwrap();continue}b.attr({href:c,name:d})}else b.unwrap()});var u=t.parse(q);k.paste_convert_word_fake_lists!==!1&&m(u),l.content=new d({validate:k.validate},s).serialize(u)}})}return j.isWordContent=g,j}),g("4",["8","a","5","d"],function(a,b,c,d){"use strict";return function(e){function f(a){e.on("BeforePastePreProcess",function(b){b.content=a(b.content)})}function g(a){e.on("PastePostProcess",function(b){a(b.node)})}function h(a){if(!c.isWordContent(a))return a;var f=[];b.each(e.schema.getBlockElements(),function(a,b){f.push(b)});var g=new RegExp("(?:
 [\\s\\r\\n]+|
)*(<\\/?("+f.join("|")+")[^>]*>)(?:
 [\\s\\r\\n]+|
)*","g");return a=d.filter(a,[[g,"$1"]]),a=d.filter(a,[[/

/g,"

"],[/
/g," "],[/

/g,"
"]])}function i(a){if(c.isWordContent(a))return a;var b=e.settings.paste_webkit_styles;if(e.settings.paste_remove_styles_if_webkit===!1||"all"==b)return a;if(b&&(b=b.split(/[, ]/)),b){var d=e.dom,f=e.selection.getNode();a=a.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(a,c,e,g){var h=d.parseStyle(d.decode(e),"span"),i={};if("none"===b)return c+g;for(var j=0;j]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return a=a.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(a,b,c,d){return b+' style="'+c+'"'+d})}function j(a){e.$("a",a).find("font,u").each(function(a,b){e.dom.remove(b,!0)})}a.webkit&&f(i),a.ie&&(f(h),g(j))}}),g("0",["1","2","3","4","5"],function(a,b,c,d,e){var f;return a.add("paste",function(g){function h(){return f||g.settings.paste_plaintext_inform===!1}function i(){if("text"==k.pasteFormat)k.pasteFormat="html",g.fire("PastePlainTextToggle",{state:!1});else if(k.pasteFormat="text",g.fire("PastePlainTextToggle",{state:!0}),!h()){var a=g.translate("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.");g.notificationManager.open({text:a,type:"info"}),f=!0}g.focus()}function j(){var a=this;a.active("text"===k.pasteFormat),g.on("PastePlainTextToggle",function(b){a.active(b.state)})}var k,l=this,m=g.settings;return/(^|[ ,])powerpaste([, ]|$)/.test(m.plugins)&&a.get("powerpaste")?void("undefined"!=typeof console&&console.log&&console.log("PowerPaste is incompatible with Paste plugin! Remove 'paste' from the 'plugins' option.")):(l.clipboard=k=new b(g),l.quirks=new d(g),l.wordFilter=new e(g),g.settings.paste_as_text&&(l.clipboard.pasteFormat="text"),m.paste_preprocess&&g.on("PastePreProcess",function(a){m.paste_preprocess.call(l,l,a)}),m.paste_postprocess&&g.on("PastePostProcess",function(a){m.paste_postprocess.call(l,l,a)}),g.addCommand("mceInsertClipboardContent",function(a,b){b.content&&l.clipboard.pasteHtml(b.content,b.internal),b.text&&l.clipboard.pasteText(b.text)}),g.settings.paste_block_drop&&g.on("dragend dragover draggesture dragdrop drop drag",function(a){a.preventDefault(),a.stopPropagation()}),g.settings.paste_data_images||g.on("drop",function(a){var b=a.dataTransfer;b&&b.files&&b.files.length>0&&a.preventDefault()}),g.addCommand("mceTogglePlainTextPaste",i),g.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:i,onPostRender:j}),g.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:k.pasteFormat,onclick:i,onPostRender:j}),void c.register(g))}),function(){}}),d("0")()}(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/themes/modern/theme.js b/src/wp-includes/js/tinymce/themes/modern/theme.js index 7bf2c3b165..dca03c85b6 100644 --- a/src/wp-includes/js/tinymce/themes/modern/theme.js +++ b/src/wp-includes/js/tinymce/themes/modern/theme.js @@ -283,17 +283,17 @@ define( function (DOMUtils) { var DOM = DOMUtils.DOM; - var reposition = function (editor, poweredByElm) { + var reposition = function (editor, poweredByElm, hasStatusbar) { return function () { var iframeWidth = editor.getContentAreaContainer().querySelector('iframe').offsetWidth; var scrollbarWidth = Math.max(iframeWidth - editor.getDoc().documentElement.offsetWidth, 0); - var statusbarElm = editor.getContainer().querySelector('.mce-statusbar'); - var statusbarHeight = statusbarElm ? statusbarElm.offsetHeight : 1; - DOM.setStyles(poweredByElm, { - right: scrollbarWidth + 'px', - bottom: statusbarHeight + 'px' - }); + DOM.setStyle(poweredByElm, 'right', scrollbarWidth + 'px'); + if (hasStatusbar) { + DOM.setStyle(poweredByElm, 'top', '-16px'); + } else { + DOM.setStyle(poweredByElm, 'bottom', '1px'); + } }; }; @@ -303,13 +303,33 @@ define( }; }; + var setupReposition = function (editor, poweredByElm, hasStatusbar) { + reposition(editor, poweredByElm, hasStatusbar)(); + editor.on('NodeChange ResizeEditor', reposition(editor, poweredByElm, hasStatusbar)); + }; + + var appendToStatusbar = function (editor, poweredByElm, statusbarElm) { + statusbarElm.appendChild(poweredByElm); + setupReposition(editor, poweredByElm, true); + }; + + var appendToContainer = function (editor, poweredByElm) { + editor.getContainer().appendChild(poweredByElm); + setupReposition(editor, poweredByElm, false); + }; + var setupEventListeners = function (editor) { editor.on('SkinLoaded', function () { var poweredByElm = DOM.create('div', { 'class': 'mce-branding-powered-by' }); - editor.getContainer().appendChild(poweredByElm); + var statusbarElm = editor.getContainer().querySelector('.mce-statusbar'); + + if (statusbarElm) { + appendToStatusbar(editor, poweredByElm, statusbarElm); + } else { + appendToContainer(editor, poweredByElm); + } + DOM.bind(poweredByElm, 'click', hide(poweredByElm)); - reposition(editor, poweredByElm)(); - editor.on('NodeChange ResizeEditor', reposition(editor, poweredByElm)); }); }; diff --git a/src/wp-includes/js/tinymce/themes/modern/theme.min.js b/src/wp-includes/js/tinymce/themes/modern/theme.min.js index 7dda013c16..524b421e86 100644 --- a/src/wp-includes/js/tinymce/themes/modern/theme.min.js +++ b/src/wp-includes/js/tinymce/themes/modern/theme.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i=0;c--)for(d=f.length-1;d>=0;d--)if(f[d].predicate(e[c]))return{toolbar:f[d],element:e[c]};return null};a.on("click keyup setContent ObjectResized",function(b){("setcontent"!==b.type||b.selection)&&c.setEditorTimeout(a,function(){var b;b=u(a.selection.getNode()),b?(t(),s(b)):t()})}),a.on("blur hide contextmenu",t),a.on("ObjectResizeStart",function(){var b=u(a.selection.getNode());b&&b.toolbar.panel&&b.toolbar.panel.hide()}),a.on("ResizeEditor ResizeWindow",q(!0)),a.on("nodeChange",q(!1)),a.on("remove",function(){b.each(n(),function(a){a.panel&&a.panel.remove()}),a.contextToolbars={}}),a.shortcuts.add("ctrl+shift+e > ctrl+shift+p","",function(){var b=u(a.selection.getNode());b&&b.toolbar.panel&&b.toolbar.panel.items()[0].focus()})};return{addContextualToolbars:m}}),g("h",["d"],function(a){var b={file:{title:"File",items:"newdocument"},edit:{title:"Edit",items:"undo redo | cut copy paste pastetext | selectall"},insert:{title:"Insert",items:"|"},view:{title:"View",items:"visualaid |"},format:{title:"Format",items:"bold italic underline strikethrough superscript subscript | formats | removeformat"},table:{title:"Table"},tools:{title:"Tools"}},c=function(a,b){var c;return"|"==b?{text:"|"}:c=a[b]},d=function(d,e,f){var g,h,i,j,k;if(k=a.makeMap((e.removed_menuitems||"").split(/[ ,]/)),e.menu?(h=e.menu[f],j=!0):h=b[f],h){g={text:h.title},i=[],a.each((h.items||"").split(/[ ,]/),function(a){var b=c(d,a);b&&!k[a]&&i.push(c(d,a))}),j||a.each(d,function(a){a.context==f&&("before"==a.separator&&i.push({text:"|"}),a.prependToContext?i.unshift(a):i.push(a),"after"==a.separator&&i.push({text:"|"}))});for(var l=0;l=11},k=function(a){return!(!j()||!a.sidebars)&&a.sidebars.length>0},l=function(b){var c=a.map(b.sidebars,function(a){var c=a.settings;return{type:"button",icon:c.icon,image:c.image,tooltip:c.tooltip,onclick:i(b,a.name,b.sidebars)}});return{type:"panel",name:"sidebar",layout:"stack",classes:"sidebar",items:[{type:"toolbar",layout:"stack",classes:"sidebar-toolbar",items:c}]}};return{hasSidebar:k,createSidebar:l}}),g("j",[],function(){var a=function(a){var b=function(){a._skinLoaded=!0,a.fire("SkinLoaded")};return function(){a.initialized?b():a.on("init",b)}};return{fireSkinLoaded:a}}),g("6",["b","c","d","e","f","g","h","9","i","j","k"],function(a,b,c,d,e,f,g,h,i,j,k){var l=a.DOM,m=function(a){return function(b){a.find("*").disabled("readonly"===b.mode)}},n=function(a){return{type:"panel",name:"iframe",layout:"stack",classes:"edit-area",border:a,html:""}},o=function(a){return{type:"panel",layout:"stack",classes:"edit-aria-container",border:"1 0 0 0",items:[n("0"),i.createSidebar(a)]}},p=function(a,c,p){var q,r,s,t=a.settings;return p.skinUiCss&&l.styleSheetLoader.load(p.skinUiCss,j.fireSkinLoaded(a)),q=c.panel=b.create({type:"panel",role:"application",classes:"tinymce",style:"visibility: hidden",layout:"stack",border:1,items:[t.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:g.createMenuButtons(a)},k.createToolbars(a,t.toolbar_items_size),i.hasSidebar(a)?o(a):n("1 0 0 0")]}),t.resize!==!1&&(r={type:"resizehandle",direction:t.resize,onResizeStart:function(){var b=a.getContentAreaContainer().firstChild;s={width:b.clientWidth,height:b.clientHeight}},onResize:function(b){"both"===t.resize?h.resizeTo(a,s.width+b.deltaX,s.height+b.deltaY):h.resizeTo(a,null,s.height+b.deltaY)}}),t.statusbar!==!1&&q.add({type:"panel",name:"statusbar",classes:"statusbar",layout:"flow",border:"1 0 0 0",ariaRoot:!0,items:[{type:"elementpath",editor:a},r]}),a.fire("BeforeRenderUI"),a.on("SwitchMode",m(q)),q.renderBefore(p.targetNode).reflow(),t.readonly&&a.setMode("readonly"),p.width&&l.setStyle(q.getEl(),"width",p.width),a.on("remove",function(){q.remove(),q=null}),d.addKeys(a,q),f.addContextualToolbars(a),e.setup(a),{iframeContainer:q.find("#iframe")[0].getEl(),editorContainer:q.getEl()}};return{render:p}}),g("l",["a"],function(a){return a("tinymce.ui.FloatPanel")}),g("7",["d","c","b","l","k","h","g","e","j"],function(a,b,c,d,e,f,g,h,i){var j=function(a,j,k){var l,m,n=a.settings,o=c.DOM;n.fixed_toolbar_container&&(m=o.select(n.fixed_toolbar_container)[0]);var p=function(){if(l&&l.moveRel&&l.visible()&&!l._fixed){var b=a.selection.getScrollContainer(),c=a.getBody(),d=0,e=0;if(b){var f=o.getPos(c),g=o.getPos(b);d=Math.max(0,g.x-f.x),e=Math.max(0,g.y-f.y)}l.fixed(!1).moveRel(c,a.rtl?["tr-br","br-tr"]:["tl-bl","bl-tl","tr-br"]).moveBy(d,e)}},q=function(){l&&(l.show(),p(),o.addClass(a.getBody(),"mce-edit-focus"))},r=function(){l&&(l.hide(),d.hideAll(),o.removeClass(a.getBody(),"mce-edit-focus"))},s=function(){return l?void(l.visible()||q()):(l=j.panel=b.create({type:m?"panel":"floatpanel",role:"application",classes:"tinymce tinymce-inline",layout:"flex",direction:"column",align:"stretch",autohide:!1,autofix:!0,fixed:!!m,border:1,items:[n.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:f.createMenuButtons(a)},e.createToolbars(a,n.toolbar_items_size)]}),a.fire("BeforeRenderUI"),l.renderTo(m||document.body).reflow(),h.addKeys(a,l),q(),g.addContextualToolbars(a),a.on("nodeChange",p),a.on("activate",q),a.on("deactivate",r),void a.nodeChanged())};return n.content_editable=!0,a.on("focus",function(){k.skinUiCss?o.styleSheetLoader.load(k.skinUiCss,s,s):s()}),a.on("blur hide",r),a.on("remove",function(){l&&(l.remove(),l=null)}),k.skinUiCss&&o.styleSheetLoader.load(k.skinUiCss,i.fireSkinLoaded(a)),{}};return{render:j}}),g("m",["a"],function(a){return a("tinymce.ui.Throbber")}),g("8",["m"],function(a){var b=function(b,c){var d;b.on("ProgressState",function(b){d=d||new a(c.panel.getEl("body")),b.state?d.show(b.time):d.hide()})};return{setup:b}}),g("0",["1","2","3","4","5","6","7","8","9"],function(a,b,c,d,e,f,g,h,i){var j=b.ThemeManager;e.appendTo(a.tinymce?a.tinymce:{});var k=function(a,b,d){var e=a.settings,i=e.skin!==!1&&(e.skin||"lightgray");if(i){var j=e.skin_url;j=j?a.documentBaseURI.toAbsolute(j):c.baseURL+"/skins/"+i,d.skinUiCss=j+"/skin.min.css",a.contentCSS.push(j+"/content"+(a.inline?".inline":"")+".min.css")}return h.setup(a,b),e.inline?g.render(a,b,d):f.render(a,b,d)};return j.add("modern",function(a){return{renderUI:function(b){return k(a,this,b)},resizeTo:function(b,c){return i.resizeTo(a,b,c)},resizeBy:function(b,c){return i.resizeBy(a,b,c)}}}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i=0;c--)for(d=f.length-1;d>=0;d--)if(f[d].predicate(e[c]))return{toolbar:f[d],element:e[c]};return null};a.on("click keyup setContent ObjectResized",function(b){("setcontent"!==b.type||b.selection)&&c.setEditorTimeout(a,function(){var b;b=u(a.selection.getNode()),b?(t(),s(b)):t()})}),a.on("blur hide contextmenu",t),a.on("ObjectResizeStart",function(){var b=u(a.selection.getNode());b&&b.toolbar.panel&&b.toolbar.panel.hide()}),a.on("ResizeEditor ResizeWindow",q(!0)),a.on("nodeChange",q(!1)),a.on("remove",function(){b.each(n(),function(a){a.panel&&a.panel.remove()}),a.contextToolbars={}}),a.shortcuts.add("ctrl+shift+e > ctrl+shift+p","",function(){var b=u(a.selection.getNode());b&&b.toolbar.panel&&b.toolbar.panel.items()[0].focus()})};return{addContextualToolbars:m}}),g("h",["d"],function(a){var b={file:{title:"File",items:"newdocument"},edit:{title:"Edit",items:"undo redo | cut copy paste pastetext | selectall"},insert:{title:"Insert",items:"|"},view:{title:"View",items:"visualaid |"},format:{title:"Format",items:"bold italic underline strikethrough superscript subscript | formats | removeformat"},table:{title:"Table"},tools:{title:"Tools"}},c=function(a,b){var c;return"|"==b?{text:"|"}:c=a[b]},d=function(d,e,f){var g,h,i,j,k;if(k=a.makeMap((e.removed_menuitems||"").split(/[ ,]/)),e.menu?(h=e.menu[f],j=!0):h=b[f],h){g={text:h.title},i=[],a.each((h.items||"").split(/[ ,]/),function(a){var b=c(d,a);b&&!k[a]&&i.push(c(d,a))}),j||a.each(d,function(a){a.context==f&&("before"==a.separator&&i.push({text:"|"}),a.prependToContext?i.unshift(a):i.push(a),"after"==a.separator&&i.push({text:"|"}))});for(var l=0;l=11},k=function(a){return!(!j()||!a.sidebars)&&a.sidebars.length>0},l=function(b){var c=a.map(b.sidebars,function(a){var c=a.settings;return{type:"button",icon:c.icon,image:c.image,tooltip:c.tooltip,onclick:i(b,a.name,b.sidebars)}});return{type:"panel",name:"sidebar",layout:"stack",classes:"sidebar",items:[{type:"toolbar",layout:"stack",classes:"sidebar-toolbar",items:c}]}};return{hasSidebar:k,createSidebar:l}}),g("j",[],function(){var a=function(a){var b=function(){a._skinLoaded=!0,a.fire("SkinLoaded")};return function(){a.initialized?b():a.on("init",b)}};return{fireSkinLoaded:a}}),g("6",["b","c","d","e","f","g","h","9","i","j","k"],function(a,b,c,d,e,f,g,h,i,j,k){var l=a.DOM,m=function(a){return function(b){a.find("*").disabled("readonly"===b.mode)}},n=function(a){return{type:"panel",name:"iframe",layout:"stack",classes:"edit-area",border:a,html:""}},o=function(a){return{type:"panel",layout:"stack",classes:"edit-aria-container",border:"1 0 0 0",items:[n("0"),i.createSidebar(a)]}},p=function(a,c,p){var q,r,s,t=a.settings;return p.skinUiCss&&l.styleSheetLoader.load(p.skinUiCss,j.fireSkinLoaded(a)),q=c.panel=b.create({type:"panel",role:"application",classes:"tinymce",style:"visibility: hidden",layout:"stack",border:1,items:[t.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:g.createMenuButtons(a)},k.createToolbars(a,t.toolbar_items_size),i.hasSidebar(a)?o(a):n("1 0 0 0")]}),t.resize!==!1&&(r={type:"resizehandle",direction:t.resize,onResizeStart:function(){var b=a.getContentAreaContainer().firstChild;s={width:b.clientWidth,height:b.clientHeight}},onResize:function(b){"both"===t.resize?h.resizeTo(a,s.width+b.deltaX,s.height+b.deltaY):h.resizeTo(a,null,s.height+b.deltaY)}}),t.statusbar!==!1&&q.add({type:"panel",name:"statusbar",classes:"statusbar",layout:"flow",border:"1 0 0 0",ariaRoot:!0,items:[{type:"elementpath",editor:a},r]}),a.fire("BeforeRenderUI"),a.on("SwitchMode",m(q)),q.renderBefore(p.targetNode).reflow(),t.readonly&&a.setMode("readonly"),p.width&&l.setStyle(q.getEl(),"width",p.width),a.on("remove",function(){q.remove(),q=null}),d.addKeys(a,q),f.addContextualToolbars(a),e.setup(a),{iframeContainer:q.find("#iframe")[0].getEl(),editorContainer:q.getEl()}};return{render:p}}),g("l",["a"],function(a){return a("tinymce.ui.FloatPanel")}),g("7",["d","c","b","l","k","h","g","e","j"],function(a,b,c,d,e,f,g,h,i){var j=function(a,j,k){var l,m,n=a.settings,o=c.DOM;n.fixed_toolbar_container&&(m=o.select(n.fixed_toolbar_container)[0]);var p=function(){if(l&&l.moveRel&&l.visible()&&!l._fixed){var b=a.selection.getScrollContainer(),c=a.getBody(),d=0,e=0;if(b){var f=o.getPos(c),g=o.getPos(b);d=Math.max(0,g.x-f.x),e=Math.max(0,g.y-f.y)}l.fixed(!1).moveRel(c,a.rtl?["tr-br","br-tr"]:["tl-bl","bl-tl","tr-br"]).moveBy(d,e)}},q=function(){l&&(l.show(),p(),o.addClass(a.getBody(),"mce-edit-focus"))},r=function(){l&&(l.hide(),d.hideAll(),o.removeClass(a.getBody(),"mce-edit-focus"))},s=function(){return l?void(l.visible()||q()):(l=j.panel=b.create({type:m?"panel":"floatpanel",role:"application",classes:"tinymce tinymce-inline",layout:"flex",direction:"column",align:"stretch",autohide:!1,autofix:!0,fixed:!!m,border:1,items:[n.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:f.createMenuButtons(a)},e.createToolbars(a,n.toolbar_items_size)]}),a.fire("BeforeRenderUI"),l.renderTo(m||document.body).reflow(),h.addKeys(a,l),q(),g.addContextualToolbars(a),a.on("nodeChange",p),a.on("activate",q),a.on("deactivate",r),void a.nodeChanged())};return n.content_editable=!0,a.on("focus",function(){k.skinUiCss?o.styleSheetLoader.load(k.skinUiCss,s,s):s()}),a.on("blur hide",r),a.on("remove",function(){l&&(l.remove(),l=null)}),k.skinUiCss&&o.styleSheetLoader.load(k.skinUiCss,i.fireSkinLoaded(a)),{}};return{render:j}}),g("m",["a"],function(a){return a("tinymce.ui.Throbber")}),g("8",["m"],function(a){var b=function(b,c){var d;b.on("ProgressState",function(b){d=d||new a(c.panel.getEl("body")),b.state?d.show(b.time):d.hide()})};return{setup:b}}),g("0",["1","2","3","4","5","6","7","8","9"],function(a,b,c,d,e,f,g,h,i){var j=b.ThemeManager;e.appendTo(a.tinymce?a.tinymce:{});var k=function(a,b,d){var e=a.settings,i=e.skin!==!1&&(e.skin||"lightgray");if(i){var j=e.skin_url;j=j?a.documentBaseURI.toAbsolute(j):c.baseURL+"/skins/"+i,d.skinUiCss=j+"/skin.min.css",a.contentCSS.push(j+"/content"+(a.inline?".inline":"")+".min.css")}return h.setup(a,b),e.inline?g.render(a,b,d):f.render(a,b,d)};return j.add("modern",function(a){return{renderUI:function(b){return k(a,this,b)},resizeTo:function(b,c){return i.resizeTo(a,b,c)},resizeBy:function(b,c){return i.resizeBy(a,b,c)}}}),function(){}}),d("0")()}(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/tinymce.js b/src/wp-includes/js/tinymce/tinymce.js index f6b441b027..5fd2701682 100644 --- a/src/wp-includes/js/tinymce/tinymce.js +++ b/src/wp-includes/js/tinymce/tinymce.js @@ -1,4 +1,4 @@ -// 4.6.1 (2017-05-10) +// 4.6.2 (2017-05-23) (function () { var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)} @@ -82,7 +82,7 @@ var defineGlobal = function (id, ref) { define(id, [], function () { return ref; }); }; /*jsc -["tinymce.core.api.Main","tinymce.core.api.Tinymce","tinymce.core.Register","tinymce.core.geom.Rect","tinymce.core.util.Promise","tinymce.core.util.Delay","tinymce.core.Env","tinymce.core.dom.EventUtils","tinymce.core.dom.Sizzle","tinymce.core.util.Tools","tinymce.core.dom.DomQuery","tinymce.core.html.Styles","tinymce.core.dom.TreeWalker","tinymce.core.html.Entities","tinymce.core.dom.DOMUtils","tinymce.core.dom.ScriptLoader","tinymce.core.AddOnManager","tinymce.core.dom.RangeUtils","tinymce.core.html.Node","tinymce.core.html.Schema","tinymce.core.html.SaxParser","tinymce.core.html.DomParser","tinymce.core.html.Writer","tinymce.core.html.Serializer","tinymce.core.dom.Serializer","tinymce.core.util.VK","tinymce.core.dom.ControlSelection","tinymce.core.dom.BookmarkManager","tinymce.core.dom.Selection","tinymce.core.Formatter","tinymce.core.UndoManager","tinymce.core.EditorCommands","tinymce.core.util.URI","tinymce.core.util.Class","tinymce.core.util.EventDispatcher","tinymce.core.util.Observable","tinymce.core.WindowManager","tinymce.core.NotificationManager","tinymce.core.EditorObservable","tinymce.core.Shortcuts","tinymce.core.Editor","tinymce.core.util.I18n","tinymce.core.FocusManager","tinymce.core.EditorManager","tinymce.core.util.XHR","tinymce.core.util.JSON","tinymce.core.util.JSONRequest","tinymce.core.util.JSONP","tinymce.core.util.LocalStorage","tinymce.core.api.Compat","tinymce.core.util.Color","tinymce.core.ui.Api","tinymce.core.util.Arr","tinymce.core.dom.Range","tinymce.core.dom.StyleSheetLoader","tinymce.core.dom.NodeType","tinymce.core.caret.CaretContainer","tinymce.core.text.Zwsp","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.dom.ElementUtils","tinymce.core.util.Fun","tinymce.core.fmt.Preview","tinymce.core.fmt.Hooks","tinymce.core.undo.Levels","tinymce.core.delete.DeleteCommands","tinymce.core.InsertContent","global!document","tinymce.core.ui.Window","tinymce.core.ui.MessageBox","tinymce.core.ui.Notification","tinymce.core.init.Render","tinymce.core.Mode","tinymce.core.ui.Sidebar","tinymce.core.util.Uuid","tinymce.core.ErrorReporter","tinymce.core.LegacyInput","tinymce.core.ui.Selector","tinymce.core.ui.Collection","tinymce.core.ui.ReflowQueue","tinymce.core.ui.Control","tinymce.core.ui.Factory","tinymce.core.ui.KeyboardNavigation","tinymce.core.ui.Container","tinymce.core.ui.DragHelper","tinymce.core.ui.Scrollable","tinymce.core.ui.Panel","tinymce.core.ui.Movable","tinymce.core.ui.Resizable","tinymce.core.ui.FloatPanel","tinymce.core.ui.Tooltip","tinymce.core.ui.Widget","tinymce.core.ui.Progress","tinymce.core.ui.Layout","tinymce.core.ui.AbsoluteLayout","tinymce.core.ui.Button","tinymce.core.ui.ButtonGroup","tinymce.core.ui.Checkbox","tinymce.core.ui.ComboBox","tinymce.core.ui.ColorBox","tinymce.core.ui.PanelButton","tinymce.core.ui.ColorButton","tinymce.core.ui.ColorPicker","tinymce.core.ui.Path","tinymce.core.ui.ElementPath","tinymce.core.ui.FormItem","tinymce.core.ui.Form","tinymce.core.ui.FieldSet","tinymce.core.ui.FilePicker","tinymce.core.ui.FitLayout","tinymce.core.ui.FlexLayout","tinymce.core.ui.FlowLayout","tinymce.core.ui.FormatControls","tinymce.core.ui.GridLayout","tinymce.core.ui.Iframe","tinymce.core.ui.InfoBox","tinymce.core.ui.Label","tinymce.core.ui.Toolbar","tinymce.core.ui.MenuBar","tinymce.core.ui.MenuButton","tinymce.core.ui.MenuItem","tinymce.core.ui.Throbber","tinymce.core.ui.Menu","tinymce.core.ui.ListBox","tinymce.core.ui.Radio","tinymce.core.ui.ResizeHandle","tinymce.core.ui.SelectBox","tinymce.core.ui.Slider","tinymce.core.ui.Spacer","tinymce.core.ui.SplitButton","tinymce.core.ui.StackLayout","tinymce.core.ui.TabPanel","tinymce.core.ui.TextBox","ephox.katamari.api.Arr","ephox.katamari.api.Fun","ephox.katamari.api.Future","ephox.katamari.api.Futures","ephox.katamari.api.Result","tinymce.core.caret.CaretCandidate","tinymce.core.geom.ClientRect","tinymce.core.text.ExtendingChar","tinymce.core.undo.Fragments","tinymce.core.delete.BlockBoundaryDelete","tinymce.core.delete.BlockRangeDelete","tinymce.core.delete.CefDelete","tinymce.core.delete.InlineBoundaryDelete","tinymce.core.caret.CaretWalker","tinymce.core.dom.RangeNormalizer","tinymce.core.InsertList","tinymce.core.data.ObservableObject","tinymce.core.ui.DomUtils","tinymce.core.ui.BoxUtils","tinymce.core.ui.ClassList","global!window","tinymce.core.init.Init","tinymce.core.PluginManager","tinymce.core.ThemeManager","tinymce.core.content.LinkTargets","tinymce.core.fmt.FontInfo","ephox.katamari.api.Option","global!Array","global!Error","global!String","ephox.katamari.api.LazyValue","ephox.katamari.async.Bounce","ephox.katamari.async.AsyncValues","tinymce.core.undo.Diff","tinymce.core.delete.BlockBoundary","tinymce.core.delete.MergeBlocks","ephox.katamari.api.Options","ephox.sugar.api.dom.Compare","ephox.sugar.api.node.Element","tinymce.core.delete.DeleteUtils","tinymce.core.caret.CaretUtils","tinymce.core.delete.CefDeleteAction","tinymce.core.delete.DeleteElement","tinymce.core.keyboard.BoundaryCaret","tinymce.core.keyboard.BoundaryLocation","tinymce.core.keyboard.BoundarySelection","tinymce.core.keyboard.InlineUtils","tinymce.core.caret.CaretFinder","tinymce.core.data.Binding","tinymce.core.init.InitContentBody","global!Object","global!setTimeout","ephox.katamari.api.Struct","ephox.sand.api.Node","ephox.sand.api.PlatformDetection","ephox.sugar.api.search.Selectors","global!console","ephox.sugar.api.node.Node","ephox.sugar.api.search.PredicateFind","ephox.sugar.api.search.Traverse","tinymce.core.dom.Empty","ephox.sugar.api.dom.Insert","ephox.sugar.api.dom.Remove","ephox.katamari.api.Adt","tinymce.core.text.Bidi","tinymce.core.caret.CaretContainerInline","tinymce.core.caret.CaretContainerRemove","tinymce.core.util.LazyEvaluator","ephox.katamari.api.Cell","tinymce.core.caret.CaretContainerInput","tinymce.core.EditorUpload","tinymce.core.ForceBlocks","tinymce.core.keyboard.KeyboardOverrides","tinymce.core.NodeChange","tinymce.core.SelectionOverrides","tinymce.core.util.Quirks","ephox.katamari.data.Immutable","ephox.katamari.data.MixedBag","ephox.sand.util.Global","ephox.katamari.api.Thunk","ephox.sand.core.PlatformDetection","global!navigator","ephox.sugar.api.node.NodeTypes","ephox.katamari.api.Type","ephox.sugar.api.node.Body","ephox.sugar.impl.ClosestOrAncestor","ephox.sugar.alien.Recurse","ephox.sugar.api.search.SelectorExists","ephox.sugar.api.dom.InsertAll","ephox.katamari.api.Obj","tinymce.core.file.Uploader","tinymce.core.file.ImageScanner","tinymce.core.file.BlobCache","tinymce.core.file.UploadStatus","tinymce.core.keyboard.ArrowKeys","tinymce.core.keyboard.DeleteBackspaceKeys","tinymce.core.keyboard.EnterKey","tinymce.core.keyboard.SpaceKey","tinymce.core.caret.FakeCaret","tinymce.core.caret.LineWalker","tinymce.core.caret.LineUtils","tinymce.core.DragDropOverrides","tinymce.core.dom.NodePath","ephox.katamari.util.BagUtils","ephox.katamari.api.Resolve","ephox.sand.core.Browser","ephox.sand.core.OperatingSystem","ephox.sand.detect.DeviceType","ephox.sand.detect.UaString","ephox.sand.info.PlatformInfo","ephox.sugar.api.search.SelectorFind","tinymce.core.file.Conversions","global!URL","tinymce.core.keyboard.MatchKeys","tinymce.core.keyboard.InsertSpace","tinymce.core.dom.Dimensions","tinymce.core.dom.MousePosition","ephox.katamari.api.Global","ephox.sand.detect.Version","ephox.katamari.api.Strings","ephox.katamari.api.Merger","global!Number","ephox.katamari.str.StrAppend","ephox.katamari.str.StringParts"] +["tinymce.core.api.Main","tinymce.core.api.Tinymce","tinymce.core.Register","tinymce.core.geom.Rect","tinymce.core.util.Promise","tinymce.core.util.Delay","tinymce.core.Env","tinymce.core.dom.EventUtils","tinymce.core.dom.Sizzle","tinymce.core.util.Tools","tinymce.core.dom.DomQuery","tinymce.core.html.Styles","tinymce.core.dom.TreeWalker","tinymce.core.html.Entities","tinymce.core.dom.DOMUtils","tinymce.core.dom.ScriptLoader","tinymce.core.AddOnManager","tinymce.core.dom.RangeUtils","tinymce.core.html.Node","tinymce.core.html.Schema","tinymce.core.html.SaxParser","tinymce.core.html.DomParser","tinymce.core.html.Writer","tinymce.core.html.Serializer","tinymce.core.dom.Serializer","tinymce.core.util.VK","tinymce.core.dom.ControlSelection","tinymce.core.dom.BookmarkManager","tinymce.core.dom.Selection","tinymce.core.Formatter","tinymce.core.UndoManager","tinymce.core.EditorCommands","tinymce.core.util.URI","tinymce.core.util.Class","tinymce.core.util.EventDispatcher","tinymce.core.util.Observable","tinymce.core.WindowManager","tinymce.core.NotificationManager","tinymce.core.EditorObservable","tinymce.core.Shortcuts","tinymce.core.Editor","tinymce.core.util.I18n","tinymce.core.FocusManager","tinymce.core.EditorManager","tinymce.core.util.XHR","tinymce.core.util.JSON","tinymce.core.util.JSONRequest","tinymce.core.util.JSONP","tinymce.core.util.LocalStorage","tinymce.core.api.Compat","tinymce.core.util.Color","tinymce.core.ui.Api","tinymce.core.util.Arr","tinymce.core.dom.Range","tinymce.core.dom.StyleSheetLoader","tinymce.core.dom.NodeType","tinymce.core.caret.CaretContainer","tinymce.core.text.Zwsp","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.selection.FragmentReader","tinymce.core.dom.ElementUtils","tinymce.core.util.Fun","tinymce.core.fmt.Preview","tinymce.core.fmt.Hooks","tinymce.core.undo.Levels","tinymce.core.delete.DeleteCommands","tinymce.core.InsertContent","global!document","tinymce.core.ui.Window","tinymce.core.ui.MessageBox","tinymce.core.ui.Notification","tinymce.core.init.Render","tinymce.core.Mode","tinymce.core.ui.Sidebar","tinymce.core.util.Uuid","tinymce.core.ErrorReporter","tinymce.core.LegacyInput","tinymce.core.ui.Selector","tinymce.core.ui.Collection","tinymce.core.ui.ReflowQueue","tinymce.core.ui.Control","tinymce.core.ui.Factory","tinymce.core.ui.KeyboardNavigation","tinymce.core.ui.Container","tinymce.core.ui.DragHelper","tinymce.core.ui.Scrollable","tinymce.core.ui.Panel","tinymce.core.ui.Movable","tinymce.core.ui.Resizable","tinymce.core.ui.FloatPanel","tinymce.core.ui.Tooltip","tinymce.core.ui.Widget","tinymce.core.ui.Progress","tinymce.core.ui.Layout","tinymce.core.ui.AbsoluteLayout","tinymce.core.ui.Button","tinymce.core.ui.ButtonGroup","tinymce.core.ui.Checkbox","tinymce.core.ui.ComboBox","tinymce.core.ui.ColorBox","tinymce.core.ui.PanelButton","tinymce.core.ui.ColorButton","tinymce.core.ui.ColorPicker","tinymce.core.ui.Path","tinymce.core.ui.ElementPath","tinymce.core.ui.FormItem","tinymce.core.ui.Form","tinymce.core.ui.FieldSet","tinymce.core.ui.FilePicker","tinymce.core.ui.FitLayout","tinymce.core.ui.FlexLayout","tinymce.core.ui.FlowLayout","tinymce.core.ui.FormatControls","tinymce.core.ui.GridLayout","tinymce.core.ui.Iframe","tinymce.core.ui.InfoBox","tinymce.core.ui.Label","tinymce.core.ui.Toolbar","tinymce.core.ui.MenuBar","tinymce.core.ui.MenuButton","tinymce.core.ui.MenuItem","tinymce.core.ui.Throbber","tinymce.core.ui.Menu","tinymce.core.ui.ListBox","tinymce.core.ui.Radio","tinymce.core.ui.ResizeHandle","tinymce.core.ui.SelectBox","tinymce.core.ui.Slider","tinymce.core.ui.Spacer","tinymce.core.ui.SplitButton","tinymce.core.ui.StackLayout","tinymce.core.ui.TabPanel","tinymce.core.ui.TextBox","ephox.katamari.api.Arr","ephox.katamari.api.Fun","ephox.katamari.api.Future","ephox.katamari.api.Futures","ephox.katamari.api.Result","tinymce.core.caret.CaretCandidate","tinymce.core.geom.ClientRect","tinymce.core.text.ExtendingChar","ephox.sugar.api.dom.Insert","ephox.sugar.api.dom.Replication","ephox.sugar.api.node.Element","ephox.sugar.api.node.Fragment","ephox.sugar.api.node.Node","tinymce.core.dom.ElementType","tinymce.core.dom.Parents","tinymce.core.selection.SelectionUtils","tinymce.core.undo.Fragments","tinymce.core.delete.BlockBoundaryDelete","tinymce.core.delete.BlockRangeDelete","tinymce.core.delete.CefDelete","tinymce.core.delete.InlineBoundaryDelete","tinymce.core.caret.CaretWalker","tinymce.core.dom.RangeNormalizer","tinymce.core.InsertList","tinymce.core.data.ObservableObject","tinymce.core.ui.DomUtils","tinymce.core.ui.BoxUtils","tinymce.core.ui.ClassList","global!window","tinymce.core.init.Init","tinymce.core.PluginManager","tinymce.core.ThemeManager","tinymce.core.content.LinkTargets","tinymce.core.fmt.FontInfo","ephox.katamari.api.Option","global!Array","global!Error","global!String","ephox.katamari.api.LazyValue","ephox.katamari.async.Bounce","ephox.katamari.async.AsyncValues","ephox.sugar.api.search.Traverse","ephox.sugar.api.properties.Attr","global!console","ephox.sugar.api.dom.InsertAll","ephox.sugar.api.dom.Remove","ephox.sugar.api.node.NodeTypes","ephox.sugar.api.dom.Compare","ephox.katamari.api.Options","tinymce.core.undo.Diff","tinymce.core.delete.BlockBoundary","tinymce.core.delete.MergeBlocks","tinymce.core.delete.DeleteUtils","tinymce.core.caret.CaretUtils","tinymce.core.delete.CefDeleteAction","tinymce.core.delete.DeleteElement","tinymce.core.keyboard.BoundaryCaret","tinymce.core.keyboard.BoundaryLocation","tinymce.core.keyboard.BoundarySelection","tinymce.core.keyboard.InlineUtils","tinymce.core.caret.CaretFinder","tinymce.core.data.Binding","tinymce.core.init.InitContentBody","global!Object","global!setTimeout","ephox.katamari.api.Type","ephox.katamari.api.Struct","ephox.sugar.alien.Recurse","ephox.sand.api.Node","ephox.sand.api.PlatformDetection","ephox.sugar.api.search.Selectors","ephox.katamari.api.Obj","ephox.sugar.api.search.PredicateFind","tinymce.core.dom.Empty","ephox.katamari.api.Adt","tinymce.core.text.Bidi","tinymce.core.caret.CaretContainerInline","tinymce.core.caret.CaretContainerRemove","tinymce.core.util.LazyEvaluator","ephox.katamari.api.Cell","tinymce.core.caret.CaretContainerInput","tinymce.core.EditorUpload","tinymce.core.ForceBlocks","tinymce.core.keyboard.KeyboardOverrides","tinymce.core.NodeChange","tinymce.core.SelectionOverrides","tinymce.core.util.Quirks","ephox.katamari.data.Immutable","ephox.katamari.data.MixedBag","ephox.sand.util.Global","ephox.katamari.api.Thunk","ephox.sand.core.PlatformDetection","global!navigator","ephox.sugar.api.node.Body","ephox.sugar.impl.ClosestOrAncestor","ephox.sugar.api.search.SelectorExists","tinymce.core.file.Uploader","tinymce.core.file.ImageScanner","tinymce.core.file.BlobCache","tinymce.core.file.UploadStatus","tinymce.core.keyboard.ArrowKeys","tinymce.core.keyboard.DeleteBackspaceKeys","tinymce.core.keyboard.EnterKey","tinymce.core.keyboard.SpaceKey","tinymce.core.caret.FakeCaret","tinymce.core.caret.LineUtils","tinymce.core.DragDropOverrides","tinymce.core.keyboard.CefUtils","tinymce.core.dom.NodePath","ephox.katamari.util.BagUtils","ephox.katamari.api.Resolve","ephox.sand.core.Browser","ephox.sand.core.OperatingSystem","ephox.sand.detect.DeviceType","ephox.sand.detect.UaString","ephox.sand.info.PlatformInfo","ephox.sugar.api.search.SelectorFind","tinymce.core.file.Conversions","global!URL","tinymce.core.keyboard.CefNavigation","tinymce.core.keyboard.MatchKeys","tinymce.core.keyboard.InsertSpace","tinymce.core.dom.Dimensions","tinymce.core.dom.MousePosition","ephox.katamari.api.Global","ephox.sand.detect.Version","ephox.katamari.api.Strings","tinymce.core.caret.LineWalker","ephox.katamari.api.Merger","global!Number","ephox.katamari.str.StrAppend","ephox.katamari.str.StringParts"] jsc*/ /** * Rect.js @@ -13750,7 +13750,7 @@ define( var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name; var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded; var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns; - var attributesRequired, attributesDefault, attributesForced; + var attributesRequired, attributesDefault, attributesForced, processHtml; var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0; var decode = Entities.decode, fixSelfClosing, filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster'); var scriptUriRegExp = /((java|vb)script|mhtml):/i, dataUriRegExp = /^data:/i; @@ -13868,8 +13868,9 @@ define( removeInternalElements = settings.remove_internals; fixSelfClosing = settings.fix_self_closing; specialElements = schema.getSpecialElements(); + processHtml = html + '>'; - while ((matches = tokenRegExp.exec(html + '>'))) { // Adds and extra '>' to keep regexps from doing catastrofic backtracking on malformed html + while ((matches = tokenRegExp.exec(processHtml))) { // Adds and extra '>' to keep regexps from doing catastrofic backtracking on malformed html // Text if (index < matches.index) { self.text(decode(html.substr(index, matches.index - index))); @@ -18676,6 +18677,2201 @@ define( } ); +define( + 'ephox.katamari.api.Type', + + [ + 'global!Array', + 'global!String' + ], + + function (Array, String) { + var typeOf = function(x) { + if (x === null) return 'null'; + var t = typeof x; + if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; + if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; + return t; + }; + + var isType = function (type) { + return function (value) { + return typeOf(value) === type; + }; + }; + + return { + isString: isType('string'), + isObject: isType('object'), + isArray: isType('array'), + isNull: isType('null'), + isBoolean: isType('boolean'), + isUndefined: isType('undefined'), + isFunction: isType('function'), + isNumber: isType('number') + }; + } +); + + +define( + 'ephox.katamari.data.Immutable', + + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'global!Array', + 'global!Error' + ], + + function (Arr, Fun, Array, Error) { + return function () { + var fields = arguments; + return function(/* values */) { + // Don't use array slice(arguments), makes the whole function unoptimisable on Chrome + var values = new Array(arguments.length); + for (var i = 0; i < values.length; i++) values[i] = arguments[i]; + + if (fields.length !== values.length) + throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); + + var struct = {}; + Arr.each(fields, function (name, i) { + struct[name] = Fun.constant(values[i]); + }); + return struct; + }; + }; + } +); + +define( + 'ephox.katamari.api.Obj', + + [ + 'ephox.katamari.api.Option', + 'global!Object' + ], + + function (Option, Object) { + // There are many variations of Object iteration that are faster than the 'for-in' style: + // http://jsperf.com/object-keys-iteration/107 + // + // Use the native keys if it is available (IE9+), otherwise fall back to manually filtering + var keys = (function () { + var fastKeys = Object.keys; + + // This technically means that 'each' and 'find' on IE8 iterate through the object twice. + // This code doesn't run on IE8 much, so it's an acceptable tradeoff. + // If it becomes a problem we can always duplicate the feature detection inside each and find as well. + var slowKeys = function (o) { + var r = []; + for (var i in o) { + if (o.hasOwnProperty(i)) { + r.push(i); + } + } + return r; + }; + + return fastKeys === undefined ? slowKeys : fastKeys; + })(); + + + var each = function (obj, f) { + var props = keys(obj); + for (var k = 0, len = props.length; k < len; k++) { + var i = props[k]; + var x = obj[i]; + f(x, i, obj); + } + }; + + /** objectMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> x)) -> JsObj(k, x) */ + var objectMap = function (obj, f) { + return tupleMap(obj, function (x, i, obj) { + return { + k: i, + v: f(x, i, obj) + }; + }); + }; + + /** tupleMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> { k: x, v: y })) -> JsObj(x, y) */ + var tupleMap = function (obj, f) { + var r = {}; + each(obj, function (x, i) { + var tuple = f(x, i, obj); + r[tuple.k] = tuple.v; + }); + return r; + }; + + /** bifilter :: (JsObj(k, v), (v, k -> Bool)) -> { t: JsObj(k, v), f: JsObj(k, v) } */ + var bifilter = function (obj, pred) { + var t = {}; + var f = {}; + each(obj, function(x, i) { + var branch = pred(x, i) ? t : f; + branch[i] = x; + }); + return { + t: t, + f: f + }; + }; + + /** mapToArray :: (JsObj(k, v), (v, k -> a)) -> [a] */ + var mapToArray = function (obj, f) { + var r = []; + each(obj, function(value, name) { + r.push(f(value, name)); + }); + return r; + }; + + /** find :: (JsObj(k, v), (v, k, JsObj(k, v) -> Bool)) -> Option v */ + var find = function (obj, pred) { + var props = keys(obj); + for (var k = 0, len = props.length; k < len; k++) { + var i = props[k]; + var x = obj[i]; + if (pred(x, i, obj)) { + return Option.some(x); + } + } + return Option.none(); + }; + + /** values :: JsObj(k, v) -> [v] */ + var values = function (obj) { + return mapToArray(obj, function (v) { + return v; + }); + }; + + var size = function (obj) { + return values(obj).length; + }; + + return { + bifilter: bifilter, + each: each, + map: objectMap, + mapToArray: mapToArray, + tupleMap: tupleMap, + find: find, + keys: keys, + values: values, + size: size + }; + } +); +define( + 'ephox.katamari.util.BagUtils', + + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Type', + 'global!Error' + ], + + function (Arr, Type, Error) { + var sort = function (arr) { + return arr.slice(0).sort(); + }; + + var reqMessage = function (required, keys) { + throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.'); + }; + + var unsuppMessage = function (unsupported) { + throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', ')); + }; + + var validateStrArr = function (label, array) { + if (!Type.isArray(array)) throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.'); + Arr.each(array, function (a) { + if (!Type.isString(a)) throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.'); + }); + }; + + var invalidTypeMessage = function (incorrect, type) { + throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.'); + }; + + var checkDupes = function (everything) { + var sorted = sort(everything); + var dupe = Arr.find(sorted, function (s, i) { + return i < sorted.length -1 && s === sorted[i + 1]; + }); + + dupe.each(function (d) { + throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].'); + }); + }; + + return { + sort: sort, + reqMessage: reqMessage, + unsuppMessage: unsuppMessage, + validateStrArr: validateStrArr, + invalidTypeMessage: invalidTypeMessage, + checkDupes: checkDupes + }; + } +); +define( + 'ephox.katamari.data.MixedBag', + + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.katamari.api.Obj', + 'ephox.katamari.api.Option', + 'ephox.katamari.util.BagUtils', + 'global!Error', + 'global!Object' + ], + + function (Arr, Fun, Obj, Option, BagUtils, Error, Object) { + + return function (required, optional) { + var everything = required.concat(optional); + if (everything.length === 0) throw new Error('You must specify at least one required or optional field.'); + + BagUtils.validateStrArr('required', required); + BagUtils.validateStrArr('optional', optional); + + BagUtils.checkDupes(everything); + + return function (obj) { + var keys = Obj.keys(obj); + + // Ensure all required keys are present. + var allReqd = Arr.forall(required, function (req) { + return Arr.contains(keys, req); + }); + + if (! allReqd) BagUtils.reqMessage(required, keys); + + var unsupported = Arr.filter(keys, function (key) { + return !Arr.contains(everything, key); + }); + + if (unsupported.length > 0) BagUtils.unsuppMessage(unsupported); + + var r = {}; + Arr.each(required, function (req) { + r[req] = Fun.constant(obj[req]); + }); + + Arr.each(optional, function (opt) { + r[opt] = Fun.constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]): Option.none()); + }); + + return r; + }; + }; + } +); +define( + 'ephox.katamari.api.Struct', + + [ + 'ephox.katamari.data.Immutable', + 'ephox.katamari.data.MixedBag' + ], + + function (Immutable, MixedBag) { + return { + immutable: Immutable, + immutableBag: MixedBag + }; + } +); + +define( + 'ephox.sugar.alien.Recurse', + + [ + + ], + + function () { + /** + * Applies f repeatedly until it completes (by returning Option.none()). + * + * Normally would just use recursion, but JavaScript lacks tail call optimisation. + * + * This is what recursion looks like when manually unravelled :) + */ + var toArray = function (target, f) { + var r = []; + + var recurse = function (e) { + r.push(e); + return f(e); + }; + + var cur = f(target); + do { + cur = cur.bind(recurse); + } while (cur.isSome()); + + return r; + }; + + return { + toArray: toArray + }; + } +); +define( + 'ephox.katamari.api.Global', + + [ + ], + + function () { + // Use window object as the global if it's available since CSP will block script evals + if (typeof window !== 'undefined') { + return window; + } else { + return Function('return this;')(); + } + } +); + + +define( + 'ephox.katamari.api.Resolve', + + [ + 'ephox.katamari.api.Global' + ], + + function (Global) { + /** path :: ([String], JsObj?) -> JsObj */ + var path = function (parts, scope) { + var o = scope !== undefined ? scope : Global; + for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) + o = o[parts[i]]; + return o; + }; + + /** resolve :: (String, JsObj?) -> JsObj */ + var resolve = function (p, scope) { + var parts = p.split('.'); + return path(parts, scope); + }; + + /** step :: (JsObj, String) -> JsObj */ + var step = function (o, part) { + if (o[part] === undefined || o[part] === null) + o[part] = {}; + return o[part]; + }; + + /** forge :: ([String], JsObj?) -> JsObj */ + var forge = function (parts, target) { + var o = target !== undefined ? target : Global; + for (var i = 0; i < parts.length; ++i) + o = step(o, parts[i]); + return o; + }; + + /** namespace :: (String, JsObj?) -> JsObj */ + var namespace = function (name, target) { + var parts = name.split('.'); + return forge(parts, target); + }; + + return { + path: path, + resolve: resolve, + forge: forge, + namespace: namespace + }; + } +); + + +define( + 'ephox.sand.util.Global', + + [ + 'ephox.katamari.api.Resolve' + ], + + function (Resolve) { + var unsafe = function (name, scope) { + return Resolve.resolve(name, scope); + }; + + var getOrDie = function (name, scope) { + var actual = unsafe(name, scope); + + if (actual === undefined) throw name + ' not available on this browser'; + return actual; + }; + + return { + getOrDie: getOrDie + }; + } +); +define( + 'ephox.sand.api.Node', + + [ + 'ephox.sand.util.Global' + ], + + function (Global) { + /* + * MDN says (yes) for IE, but it's undefined on IE8 + */ + var node = function () { + var f = Global.getOrDie('Node'); + return f; + }; + + /* + * Most of numerosity doesn't alter the methods on the object. + * We're making an exception for Node, because bitwise and is so easy to get wrong. + * + * Might be nice to ADT this at some point instead of having individual methods. + */ + + var compareDocumentPosition = function (a, b, match) { + // Returns: 0 if e1 and e2 are the same node, or a bitmask comparing the positions + // of nodes e1 and e2 in their documents. See the URL below for bitmask interpretation + // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition + return (a.compareDocumentPosition(b) & match) !== 0; + }; + + var documentPositionPreceding = function (a, b) { + return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); + }; + + var documentPositionContainedBy = function (a, b) { + return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); + }; + + return { + documentPositionPreceding: documentPositionPreceding, + documentPositionContainedBy: documentPositionContainedBy + }; + } +); +define( + 'ephox.katamari.api.Thunk', + + [ + ], + + function () { + + var cached = function (f) { + var called = false; + var r; + return function() { + if (!called) { + called = true; + r = f.apply(null, arguments); + } + return r; + }; + }; + + return { + cached: cached + }; + } +); + +defineGlobal("global!Number", Number); +define( + 'ephox.sand.detect.Version', + + [ + 'ephox.katamari.api.Arr', + 'global!Number', + 'global!String' + ], + + function (Arr, Number, String) { + var firstMatch = function (regexes, s) { + for (var i = 0; i < regexes.length; i++) { + var x = regexes[i]; + if (x.test(s)) return x; + } + return undefined; + }; + + var find = function (regexes, agent) { + var r = firstMatch(regexes, agent); + if (!r) return { major : 0, minor : 0 }; + var group = function(i) { + return Number(agent.replace(r, '$' + i)); + }; + return nu(group(1), group(2)); + }; + + var detect = function (versionRegexes, agent) { + var cleanedAgent = String(agent).toLowerCase(); + + if (versionRegexes.length === 0) return unknown(); + return find(versionRegexes, cleanedAgent); + }; + + var unknown = function () { + return nu(0, 0); + }; + + var nu = function (major, minor) { + return { major: major, minor: minor }; + }; + + return { + nu: nu, + detect: detect, + unknown: unknown + }; + } +); +define( + 'ephox.sand.core.Browser', + + [ + 'ephox.katamari.api.Fun', + 'ephox.sand.detect.Version' + ], + + function (Fun, Version) { + var edge = 'Edge'; + var chrome = 'Chrome'; + var ie = 'IE'; + var opera = 'Opera'; + var firefox = 'Firefox'; + var safari = 'Safari'; + + var isBrowser = function (name, current) { + return function () { + return current === name; + }; + }; + + var unknown = function () { + return nu({ + current: undefined, + version: Version.unknown() + }); + }; + + var nu = function (info) { + var current = info.current; + var version = info.version; + + return { + current: current, + version: version, + + // INVESTIGATE: Rename to Edge ? + isEdge: isBrowser(edge, current), + isChrome: isBrowser(chrome, current), + // NOTE: isIe just looks too weird + isIE: isBrowser(ie, current), + isOpera: isBrowser(opera, current), + isFirefox: isBrowser(firefox, current), + isSafari: isBrowser(safari, current) + }; + }; + + return { + unknown: unknown, + nu: nu, + edge: Fun.constant(edge), + chrome: Fun.constant(chrome), + ie: Fun.constant(ie), + opera: Fun.constant(opera), + firefox: Fun.constant(firefox), + safari: Fun.constant(safari) + }; + } +); +define( + 'ephox.sand.core.OperatingSystem', + + [ + 'ephox.katamari.api.Fun', + 'ephox.sand.detect.Version' + ], + + function (Fun, Version) { + var windows = 'Windows'; + var ios = 'iOS'; + var android = 'Android'; + var linux = 'Linux'; + var osx = 'OSX'; + var solaris = 'Solaris'; + var freebsd = 'FreeBSD'; + + // Though there is a bit of dupe with this and Browser, trying to + // reuse code makes it much harder to follow and change. + var isOS = function (name, current) { + return function () { + return current === name; + }; + }; + + var unknown = function () { + return nu({ + current: undefined, + version: Version.unknown() + }); + }; + + var nu = function (info) { + var current = info.current; + var version = info.version; + + return { + current: current, + version: version, + + isWindows: isOS(windows, current), + // TODO: Fix capitalisation + isiOS: isOS(ios, current), + isAndroid: isOS(android, current), + isOSX: isOS(osx, current), + isLinux: isOS(linux, current), + isSolaris: isOS(solaris, current), + isFreeBSD: isOS(freebsd, current) + }; + }; + + return { + unknown: unknown, + nu: nu, + + windows: Fun.constant(windows), + ios: Fun.constant(ios), + android: Fun.constant(android), + linux: Fun.constant(linux), + osx: Fun.constant(osx), + solaris: Fun.constant(solaris), + freebsd: Fun.constant(freebsd) + }; + } +); +define( + 'ephox.sand.detect.DeviceType', + + [ + 'ephox.katamari.api.Fun' + ], + + function (Fun) { + return function (os, browser, userAgent) { + var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; + var isiPhone = os.isiOS() && !isiPad; + var isAndroid3 = os.isAndroid() && os.version.major === 3; + var isAndroid4 = os.isAndroid() && os.version.major === 4; + var isTablet = isiPad || isAndroid3 || ( isAndroid4 && /mobile/i.test(userAgent) === true ); + var isTouch = os.isiOS() || os.isAndroid(); + var isPhone = isTouch && !isTablet; + + var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; + + return { + isiPad : Fun.constant(isiPad), + isiPhone: Fun.constant(isiPhone), + isTablet: Fun.constant(isTablet), + isPhone: Fun.constant(isPhone), + isTouch: Fun.constant(isTouch), + isAndroid: os.isAndroid, + isiOS: os.isiOS, + isWebView: Fun.constant(iOSwebview) + }; + }; + } +); +define( + 'ephox.sand.detect.UaString', + + [ + 'ephox.katamari.api.Arr', + 'ephox.sand.detect.Version', + 'global!String' + ], + + function (Arr, Version, String) { + var detect = function (candidates, userAgent) { + var agent = String(userAgent).toLowerCase(); + return Arr.find(candidates, function (candidate) { + return candidate.search(agent); + }); + }; + + // They (browser and os) are the same at the moment, but they might + // not stay that way. + var detectBrowser = function (browsers, userAgent) { + return detect(browsers, userAgent).map(function (browser) { + var version = Version.detect(browser.versionRegexes, userAgent); + return { + current: browser.name, + version: version + }; + }); + }; + + var detectOs = function (oses, userAgent) { + return detect(oses, userAgent).map(function (os) { + var version = Version.detect(os.versionRegexes, userAgent); + return { + current: os.name, + version: version + }; + }); + }; + + return { + detectBrowser: detectBrowser, + detectOs: detectOs + }; + } +); +define( + 'ephox.katamari.str.StrAppend', + + [ + + ], + + function () { + var addToStart = function (str, prefix) { + return prefix + str; + }; + + var addToEnd = function (str, suffix) { + return str + suffix; + }; + + var removeFromStart = function (str, numChars) { + return str.substring(numChars); + }; + + var removeFromEnd = function (str, numChars) { + return str.substring(0, str.length - numChars); + }; + + return { + addToStart: addToStart, + addToEnd: addToEnd, + removeFromStart: removeFromStart, + removeFromEnd: removeFromEnd + }; + } +); +define( + 'ephox.katamari.str.StringParts', + + [ + 'ephox.katamari.api.Option', + 'global!Error' + ], + + function (Option, Error) { + /** Return the first 'count' letters from 'str'. +- * e.g. first("abcde", 2) === "ab" +- */ + var first = function(str, count) { + return str.substr(0, count); + }; + + /** Return the last 'count' letters from 'str'. + * e.g. last("abcde", 2) === "de" + */ + var last = function(str, count) { + return str.substr(str.length - count, str.length); + }; + + var head = function(str) { + return str === '' ? Option.none() : Option.some(str.substr(0, 1)); + }; + + var tail = function(str) { + return str === '' ? Option.none() : Option.some(str.substring(1)); + }; + + return { + first: first, + last: last, + head: head, + tail: tail + }; + } +); +define( + 'ephox.katamari.api.Strings', + + [ + 'ephox.katamari.str.StrAppend', + 'ephox.katamari.str.StringParts', + 'global!Error' + ], + + function (StrAppend, StringParts, Error) { + var checkRange = function(str, substr, start) { + if (substr === '') return true; + if (str.length < substr.length) return false; + var x = str.substr(start, start + substr.length); + return x === substr; + }; + + /** Given a string and object, perform template-replacements on the string, as specified by the object. + * Any template fields of the form ${name} are replaced by the string or number specified as obj["name"] + * Based on Douglas Crockford's 'supplant' method for template-replace of strings. Uses different template format. + */ + var supplant = function(str, obj) { + var isStringOrNumber = function(a) { + var t = typeof a; + return t === 'string' || t === 'number'; + }; + + return str.replace(/\${([^{}]*)}/g, + function (a, b) { + var value = obj[b]; + return isStringOrNumber(value) ? value : a; + } + ); + }; + + var removeLeading = function (str, prefix) { + return startsWith(str, prefix) ? StrAppend.removeFromStart(str, prefix.length) : str; + }; + + var removeTrailing = function (str, prefix) { + return endsWith(str, prefix) ? StrAppend.removeFromEnd(str, prefix.length) : str; + }; + + var ensureLeading = function (str, prefix) { + return startsWith(str, prefix) ? str : StrAppend.addToStart(str, prefix); + }; + + var ensureTrailing = function (str, prefix) { + return endsWith(str, prefix) ? str : StrAppend.addToEnd(str, prefix); + }; + + var contains = function(str, substr) { + return str.indexOf(substr) !== -1; + }; + + var capitalize = function(str) { + return StringParts.head(str).bind(function (head) { + return StringParts.tail(str).map(function (tail) { + return head.toUpperCase() + tail; + }); + }).getOr(str); + }; + + /** Does 'str' start with 'prefix'? + * Note: all strings start with the empty string. + * More formally, for all strings x, startsWith(x, ""). + * This is so that for all strings x and y, startsWith(y + x, y) + */ + var startsWith = function(str, prefix) { + return checkRange(str, prefix, 0); + }; + + /** Does 'str' end with 'suffix'? + * Note: all strings end with the empty string. + * More formally, for all strings x, endsWith(x, ""). + * This is so that for all strings x and y, endsWith(x + y, y) + */ + var endsWith = function(str, suffix) { + return checkRange(str, suffix, str.length - suffix.length); + }; + + + /** removes all leading and trailing spaces */ + var trim = function(str) { + return str.replace(/^\s+|\s+$/g, ''); + }; + + var lTrim = function(str) { + return str.replace(/^\s+/g, ''); + }; + + var rTrim = function(str) { + return str.replace(/\s+$/g, ''); + }; + + return { + supplant: supplant, + startsWith: startsWith, + removeLeading: removeLeading, + removeTrailing: removeTrailing, + ensureLeading: ensureLeading, + ensureTrailing: ensureTrailing, + endsWith: endsWith, + contains: contains, + trim: trim, + lTrim: lTrim, + rTrim: rTrim, + capitalize: capitalize + }; + } +); + +define( + 'ephox.sand.info.PlatformInfo', + + [ + 'ephox.katamari.api.Fun', + 'ephox.katamari.api.Strings' + ], + + function (Fun, Strings) { + var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; + + var checkContains = function (target) { + return function (uastring) { + return Strings.contains(uastring, target); + }; + }; + + var browsers = [ + { + name : 'Edge', + versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], + search: function (uastring) { + var monstrosity = Strings.contains(uastring, 'edge/') && Strings.contains(uastring, 'chrome') && Strings.contains(uastring, 'safari') && Strings.contains(uastring, 'applewebkit'); + return monstrosity; + } + }, + { + name : 'Chrome', + versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex], + search : function (uastring) { + return Strings.contains(uastring, 'chrome') && !Strings.contains(uastring, 'chromeframe'); + } + }, + { + name : 'IE', + versionRegexes: [/.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/], + search: function (uastring) { + return Strings.contains(uastring, 'msie') || Strings.contains(uastring, 'trident'); + } + }, + // INVESTIGATE: Is this still the Opera user agent? + { + name : 'Opera', + versionRegexes: [normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/], + search : checkContains('opera') + }, + { + name : 'Firefox', + versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], + search : checkContains('firefox') + }, + { + name : 'Safari', + versionRegexes: [normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/], + search : function (uastring) { + return (Strings.contains(uastring, 'safari') || Strings.contains(uastring, 'mobile/')) && Strings.contains(uastring, 'applewebkit'); + } + } + ]; + + var oses = [ + { + name : 'Windows', + search : checkContains('win'), + versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] + }, + { + name : 'iOS', + search : function (uastring) { + return Strings.contains(uastring, 'iphone') || Strings.contains(uastring, 'ipad'); + }, + versionRegexes: [/.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/] + }, + { + name : 'Android', + search : checkContains('android'), + versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] + }, + { + name : 'OSX', + search : checkContains('os x'), + versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] + }, + { + name : 'Linux', + search : checkContains('linux'), + versionRegexes: [ ] + }, + { name : 'Solaris', + search : checkContains('sunos'), + versionRegexes: [ ] + }, + { + name : 'FreeBSD', + search : checkContains('freebsd'), + versionRegexes: [ ] + } + ]; + + return { + browsers: Fun.constant(browsers), + oses: Fun.constant(oses) + }; + } +); +define( + 'ephox.sand.core.PlatformDetection', + + [ + 'ephox.sand.core.Browser', + 'ephox.sand.core.OperatingSystem', + 'ephox.sand.detect.DeviceType', + 'ephox.sand.detect.UaString', + 'ephox.sand.info.PlatformInfo' + ], + + function (Browser, OperatingSystem, DeviceType, UaString, PlatformInfo) { + var detect = function (userAgent) { + var browsers = PlatformInfo.browsers(); + var oses = PlatformInfo.oses(); + + var browser = UaString.detectBrowser(browsers, userAgent).fold( + Browser.unknown, + Browser.nu + ); + var os = UaString.detectOs(oses, userAgent).fold( + OperatingSystem.unknown, + OperatingSystem.nu + ); + var deviceType = DeviceType(os, browser, userAgent); + + return { + browser: browser, + os: os, + deviceType: deviceType + }; + }; + + return { + detect: detect + }; + } +); +defineGlobal("global!navigator", navigator); +define( + 'ephox.sand.api.PlatformDetection', + + [ + 'ephox.katamari.api.Thunk', + 'ephox.sand.core.PlatformDetection', + 'global!navigator' + ], + + function (Thunk, PlatformDetection, navigator) { + var detect = Thunk.cached(function () { + var userAgent = navigator.userAgent; + return PlatformDetection.detect(userAgent); + }); + + return { + detect: detect + }; + } +); +define("global!console", [], function () { if (typeof console === "undefined") console = { log: function () {} }; return console; }); +defineGlobal("global!document", document); +define( + 'ephox.sugar.api.node.Element', + + [ + 'ephox.katamari.api.Fun', + 'global!Error', + 'global!console', + 'global!document' + ], + + function (Fun, Error, console, document) { + var fromHtml = function (html, scope) { + var doc = scope || document; + var div = doc.createElement('div'); + div.innerHTML = html; + if (!div.hasChildNodes() || div.childNodes.length > 1) { + console.error('HTML does not have a single root node', html); + throw 'HTML must have a single root node'; + } + return fromDom(div.childNodes[0]); + }; + + var fromTag = function (tag, scope) { + var doc = scope || document; + var node = doc.createElement(tag); + return fromDom(node); + }; + + var fromText = function (text, scope) { + var doc = scope || document; + var node = doc.createTextNode(text); + return fromDom(node); + }; + + var fromDom = function (node) { + if (node === null || node === undefined) throw new Error('Node cannot be null or undefined'); + return { + dom: Fun.constant(node) + }; + }; + + return { + fromHtml: fromHtml, + fromTag: fromTag, + fromText: fromText, + fromDom: fromDom + }; + } +); + +define( + 'ephox.sugar.api.node.NodeTypes', + + [ + + ], + + function () { + return { + ATTRIBUTE: 2, + CDATA_SECTION: 4, + COMMENT: 8, + DOCUMENT: 9, + DOCUMENT_TYPE: 10, + DOCUMENT_FRAGMENT: 11, + ELEMENT: 1, + TEXT: 3, + PROCESSING_INSTRUCTION: 7, + ENTITY_REFERENCE: 5, + ENTITY: 6, + NOTATION: 12 + }; + } +); +define( + 'ephox.sugar.api.search.Selectors', + + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Option', + 'ephox.sugar.api.node.Element', + 'ephox.sugar.api.node.NodeTypes', + 'global!Error', + 'global!document' + ], + + function (Arr, Option, Element, NodeTypes, Error, document) { + /* + * There's a lot of code here; the aim is to allow the browser to optimise constant comparisons, + * instead of doing object lookup feature detection on every call + */ + var STANDARD = 0; + var MSSTANDARD = 1; + var WEBKITSTANDARD = 2; + var FIREFOXSTANDARD = 3; + + var selectorType = (function () { + var test = document.createElement('span'); + // As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function. + // Still check for the others, but do it last. + return test.matches !== undefined ? STANDARD : + test.msMatchesSelector !== undefined ? MSSTANDARD : + test.webkitMatchesSelector !== undefined ? WEBKITSTANDARD : + test.mozMatchesSelector !== undefined ? FIREFOXSTANDARD : + -1; + })(); + + + var ELEMENT = NodeTypes.ELEMENT; + var DOCUMENT = NodeTypes.DOCUMENT; + + var is = function (element, selector) { + var elem = element.dom(); + if (elem.nodeType !== ELEMENT) return false; // documents have querySelector but not matches + + // As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function. + // Still check for the others, but do it last. + else if (selectorType === STANDARD) return elem.matches(selector); + else if (selectorType === MSSTANDARD) return elem.msMatchesSelector(selector); + else if (selectorType === WEBKITSTANDARD) return elem.webkitMatchesSelector(selector); + else if (selectorType === FIREFOXSTANDARD) return elem.mozMatchesSelector(selector); + else throw new Error('Browser lacks native selectors'); // unfortunately we can't throw this on startup :( + }; + + var bypassSelector = function (dom) { + // Only elements and documents support querySelector + return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT || + // IE fix for complex queries on empty nodes: http://jsfiddle.net/spyder/fv9ptr5L/ + dom.childElementCount === 0; + }; + + var all = function (selector, scope) { + var base = scope === undefined ? document : scope.dom(); + return bypassSelector(base) ? [] : Arr.map(base.querySelectorAll(selector), Element.fromDom); + }; + + var one = function (selector, scope) { + var base = scope === undefined ? document : scope.dom(); + return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); + }; + + return { + all: all, + is: is, + one: one + }; + } +); + +define( + 'ephox.sugar.api.dom.Compare', + + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.sand.api.Node', + 'ephox.sand.api.PlatformDetection', + 'ephox.sugar.api.search.Selectors' + ], + + function (Arr, Fun, Node, PlatformDetection, Selectors) { + + var eq = function (e1, e2) { + return e1.dom() === e2.dom(); + }; + + var isEqualNode = function (e1, e2) { + return e1.dom().isEqualNode(e2.dom()); + }; + + var member = function (element, elements) { + return Arr.exists(elements, Fun.curry(eq, element)); + }; + + // DOM contains() method returns true if e1===e2, we define our contains() to return false (a node does not contain itself). + var regularContains = function (e1, e2) { + var d1 = e1.dom(), d2 = e2.dom(); + return d1 === d2 ? false : d1.contains(d2); + }; + + var ieContains = function (e1, e2) { + // IE only implements the contains() method for Element nodes. + // It fails for Text nodes, so implement it using compareDocumentPosition() + // https://connect.microsoft.com/IE/feedback/details/780874/node-contains-is-incorrect + // Note that compareDocumentPosition returns CONTAINED_BY if 'e2 *is_contained_by* e1': + // Also, compareDocumentPosition defines a node containing itself as false. + return Node.documentPositionContainedBy(e1.dom(), e2.dom()); + }; + + var browser = PlatformDetection.detect().browser; + + // Returns: true if node e1 contains e2, otherwise false. + // (returns false if e1===e2: A node does not contain itself). + var contains = browser.isIE() ? ieContains : regularContains; + + return { + eq: eq, + isEqualNode: isEqualNode, + member: member, + contains: contains, + + // Only used by DomUniverse. Remove (or should Selectors.is move here?) + is: Selectors.is + }; + } +); + +define( + 'ephox.sugar.api.search.Traverse', + + [ + 'ephox.katamari.api.Type', + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.katamari.api.Option', + 'ephox.katamari.api.Struct', + 'ephox.sugar.alien.Recurse', + 'ephox.sugar.api.dom.Compare', + 'ephox.sugar.api.node.Element' + ], + + function (Type, Arr, Fun, Option, Struct, Recurse, Compare, Element) { + // The document associated with the current element + var owner = function (element) { + return Element.fromDom(element.dom().ownerDocument); + }; + + var documentElement = function (element) { + // TODO: Avoid unnecessary wrap/unwrap here + var doc = owner(element); + return Element.fromDom(doc.dom().documentElement); + }; + + // The window element associated with the element + var defaultView = function (element) { + var el = element.dom(); + var defaultView = el.ownerDocument.defaultView; + return Element.fromDom(defaultView); + }; + + var parent = function (element) { + var dom = element.dom(); + return Option.from(dom.parentNode).map(Element.fromDom); + }; + + var findIndex = function (element) { + return parent(element).bind(function (p) { + // TODO: Refactor out children so we can avoid the constant unwrapping + var kin = children(p); + return Arr.findIndex(kin, function (elem) { + return Compare.eq(element, elem); + }); + }); + }; + + var parents = function (element, isRoot) { + var stop = Type.isFunction(isRoot) ? isRoot : Fun.constant(false); + + // This is used a *lot* so it needs to be performant, not recursive + var dom = element.dom(); + var ret = []; + + while (dom.parentNode !== null && dom.parentNode !== undefined) { + var rawParent = dom.parentNode; + var parent = Element.fromDom(rawParent); + ret.push(parent); + + if (stop(parent) === true) break; + else dom = rawParent; + } + return ret; + }; + + var siblings = function (element) { + // TODO: Refactor out children so we can just not add self instead of filtering afterwards + var filterSelf = function (elements) { + return Arr.filter(elements, function (x) { + return !Compare.eq(element, x); + }); + }; + + return parent(element).map(children).map(filterSelf).getOr([]); + }; + + var offsetParent = function (element) { + var dom = element.dom(); + return Option.from(dom.offsetParent).map(Element.fromDom); + }; + + var prevSibling = function (element) { + var dom = element.dom(); + return Option.from(dom.previousSibling).map(Element.fromDom); + }; + + var nextSibling = function (element) { + var dom = element.dom(); + return Option.from(dom.nextSibling).map(Element.fromDom); + }; + + var prevSiblings = function (element) { + // This one needs to be reversed, so they're still in DOM order + return Arr.reverse(Recurse.toArray(element, prevSibling)); + }; + + var nextSiblings = function (element) { + return Recurse.toArray(element, nextSibling); + }; + + var children = function (element) { + var dom = element.dom(); + return Arr.map(dom.childNodes, Element.fromDom); + }; + + var child = function (element, index) { + var children = element.dom().childNodes; + return Option.from(children[index]).map(Element.fromDom); + }; + + var firstChild = function (element) { + return child(element, 0); + }; + + var lastChild = function (element) { + return child(element, element.dom().childNodes.length - 1); + }; + + var spot = Struct.immutable('element', 'offset'); + var leaf = function (element, offset) { + var cs = children(element); + return cs.length > 0 && offset < cs.length ? spot(cs[offset], 0) : spot(element, offset); + }; + + return { + owner: owner, + defaultView: defaultView, + documentElement: documentElement, + parent: parent, + findIndex: findIndex, + parents: parents, + siblings: siblings, + prevSibling: prevSibling, + offsetParent: offsetParent, + prevSiblings: prevSiblings, + nextSibling: nextSibling, + nextSiblings: nextSiblings, + children: children, + child: child, + firstChild: firstChild, + lastChild: lastChild, + leaf: leaf + }; + } +); + +define( + 'ephox.sugar.api.dom.Insert', + + [ + 'ephox.sugar.api.search.Traverse' + ], + + function (Traverse) { + var before = function (marker, element) { + var parent = Traverse.parent(marker); + parent.each(function (v) { + v.dom().insertBefore(element.dom(), marker.dom()); + }); + }; + + var after = function (marker, element) { + var sibling = Traverse.nextSibling(marker); + sibling.fold(function () { + var parent = Traverse.parent(marker); + parent.each(function (v) { + append(v, element); + }); + }, function (v) { + before(v, element); + }); + }; + + var prepend = function (parent, element) { + var firstChild = Traverse.firstChild(parent); + firstChild.fold(function () { + append(parent, element); + }, function (v) { + parent.dom().insertBefore(element.dom(), v.dom()); + }); + }; + + var append = function (parent, element) { + parent.dom().appendChild(element.dom()); + }; + + var appendAt = function (parent, element, index) { + Traverse.child(parent, index).fold(function () { + append(parent, element); + }, function (v) { + before(v, element); + }); + }; + + var wrap = function (element, wrapper) { + before(element, wrapper); + append(wrapper, element); + }; + + return { + before: before, + after: after, + prepend: prepend, + append: append, + appendAt: appendAt, + wrap: wrap + }; + } +); + +define( + 'ephox.sugar.api.node.Node', + + [ + 'ephox.sugar.api.node.NodeTypes' + ], + + function (NodeTypes) { + var name = function (element) { + var r = element.dom().nodeName; + return r.toLowerCase(); + }; + + var type = function (element) { + return element.dom().nodeType; + }; + + var value = function (element) { + return element.dom().nodeValue; + }; + + var isType = function (t) { + return function (element) { + return type(element) === t; + }; + }; + + var isComment = function (element) { + return type(element) === NodeTypes.COMMENT || name(element) === '#comment'; + }; + + var isElement = isType(NodeTypes.ELEMENT); + var isText = isType(NodeTypes.TEXT); + var isDocument = isType(NodeTypes.DOCUMENT); + + return { + name: name, + type: type, + value: value, + isElement: isElement, + isText: isText, + isDocument: isDocument, + isComment: isComment + }; + } +); + +define( + 'ephox.sugar.api.properties.Attr', + + [ + 'ephox.katamari.api.Type', + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Obj', + 'ephox.sugar.api.node.Node', + 'global!Error', + 'global!console' + ], + + /* + * Direct attribute manipulation has been around since IE8, but + * was apparently unstable until IE10. + */ + function (Type, Arr, Obj, Node, Error, console) { + var rawSet = function (dom, key, value) { + /* + * JQuery coerced everything to a string, and silently did nothing on text node/null/undefined. + * + * We fail on those invalid cases, only allowing numbers and booleans. + */ + if (Type.isString(value) || Type.isBoolean(value) || Type.isNumber(value)) { + dom.setAttribute(key, value + ''); + } else { + console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); + throw new Error('Attribute value was not simple'); + } + }; + + var set = function (element, key, value) { + rawSet(element.dom(), key, value); + }; + + var setAll = function (element, attrs) { + var dom = element.dom(); + Obj.each(attrs, function (v, k) { + rawSet(dom, k, v); + }); + }; + + var get = function (element, key) { + var v = element.dom().getAttribute(key); + + // undefined is the more appropriate value for JS, and this matches JQuery + return v === null ? undefined : v; + }; + + var has = function (element, key) { + var dom = element.dom(); + + // return false for non-element nodes, no point in throwing an error + return dom && dom.hasAttribute ? dom.hasAttribute(key) : false; + }; + + var remove = function (element, key) { + element.dom().removeAttribute(key); + }; + + var hasNone = function (element) { + var attrs = element.dom().attributes; + return attrs === undefined || attrs === null || attrs.length === 0; + }; + + var clone = function (element) { + return Arr.foldl(element.dom().attributes, function (acc, attr) { + acc[attr.name] = attr.value; + return acc; + }, {}); + }; + + var transferOne = function (source, destination, attr) { + // NOTE: We don't want to clobber any existing attributes + if (has(source, attr) && !has(destination, attr)) set(destination, attr, get(source, attr)); + }; + + // Transfer attributes(attrs) from source to destination, unless they are already present + var transfer = function (source, destination, attrs) { + if (!Node.isElement(source) || !Node.isElement(destination)) return; + Arr.each(attrs, function (attr) { + transferOne(source, destination, attr); + }); + }; + + return { + clone: clone, + set: set, + setAll: setAll, + get: get, + has: has, + remove: remove, + hasNone: hasNone, + transfer: transfer + }; + } +); + +define( + 'ephox.sugar.api.dom.InsertAll', + + [ + 'ephox.katamari.api.Arr', + 'ephox.sugar.api.dom.Insert' + ], + + function (Arr, Insert) { + var before = function (marker, elements) { + Arr.each(elements, function (x) { + Insert.before(marker, x); + }); + }; + + var after = function (marker, elements) { + Arr.each(elements, function (x, i) { + var e = i === 0 ? marker : elements[i - 1]; + Insert.after(e, x); + }); + }; + + var prepend = function (parent, elements) { + Arr.each(elements.slice().reverse(), function (x) { + Insert.prepend(parent, x); + }); + }; + + var append = function (parent, elements) { + Arr.each(elements, function (x) { + Insert.append(parent, x); + }); + }; + + return { + before: before, + after: after, + prepend: prepend, + append: append + }; + } +); + +define( + 'ephox.sugar.api.dom.Remove', + + [ + 'ephox.katamari.api.Arr', + 'ephox.sugar.api.dom.InsertAll', + 'ephox.sugar.api.search.Traverse' + ], + + function (Arr, InsertAll, Traverse) { + var empty = function (element) { + // shortcut "empty node" trick. Requires IE 9. + element.dom().textContent = ''; + + // If the contents was a single empty text node, the above doesn't remove it. But, it's still faster in general + // than removing every child node manually. + // The following is (probably) safe for performance as 99.9% of the time the trick works and + // Traverse.children will return an empty array. + Arr.each(Traverse.children(element), function (rogue) { + remove(rogue); + }); + }; + + var remove = function (element) { + var dom = element.dom(); + if (dom.parentNode !== null) + dom.parentNode.removeChild(dom); + }; + + var unwrap = function (wrapper) { + var children = Traverse.children(wrapper); + if (children.length > 0) + InsertAll.before(wrapper, children); + remove(wrapper); + }; + + return { + empty: empty, + remove: remove, + unwrap: unwrap + }; + } +); + +define( + 'ephox.sugar.api.dom.Replication', + + [ + 'ephox.sugar.api.properties.Attr', + 'ephox.sugar.api.node.Element', + 'ephox.sugar.api.dom.Insert', + 'ephox.sugar.api.dom.InsertAll', + 'ephox.sugar.api.dom.Remove', + 'ephox.sugar.api.search.Traverse' + ], + + function (Attr, Element, Insert, InsertAll, Remove, Traverse) { + var clone = function (original, deep) { + return Element.fromDom(original.dom().cloneNode(deep)); + }; + + /** Shallow clone - just the tag, no children */ + var shallow = function (original) { + return clone(original, false); + }; + + /** Deep clone - everything copied including children */ + var deep = function (original) { + return clone(original, true); + }; + + /** Shallow clone, with a new tag */ + var shallowAs = function (original, tag) { + var nu = Element.fromTag(tag); + + var attributes = Attr.clone(original); + Attr.setAll(nu, attributes); + + return nu; + }; + + /** Deep clone, with a new tag */ + var copy = function (original, tag) { + var nu = shallowAs(original, tag); + + // NOTE + // previously this used serialisation: + // nu.dom().innerHTML = original.dom().innerHTML; + // + // Clone should be equivalent (and faster), but if TD <-> TH toggle breaks, put it back. + + var cloneChildren = Traverse.children(deep(original)); + InsertAll.append(nu, cloneChildren); + + return nu; + }; + + /** Change the tag name, but keep all children */ + var mutate = function (original, tag) { + var nu = shallowAs(original, tag); + + Insert.before(original, nu); + var children = Traverse.children(original); + InsertAll.append(nu, children); + Remove.remove(original); + return nu; + }; + + return { + shallow: shallow, + shallowAs: shallowAs, + deep: deep, + copy: copy, + mutate: mutate + }; + } +); + +define( + 'ephox.sugar.api.node.Fragment', + + [ + 'ephox.katamari.api.Arr', + 'ephox.sugar.api.node.Element', + 'global!document' + ], + + function (Arr, Element, document) { + var fromElements = function (elements, scope) { + var doc = scope || document; + var fragment = doc.createDocumentFragment(); + Arr.each(elements, function (element) { + fragment.appendChild(element.dom()); + }); + return Element.fromDom(fragment); + }; + + return { + fromElements: fromElements + }; + } +); + +/** + * ElementType.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.dom.ElementType', + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.sugar.api.node.Node' + ], + function (Arr, Fun, Node) { + var blocks = [ + 'article', 'aside', 'details', 'div', 'dt', 'figcaption', 'footer', + 'form', 'fieldset', 'header', 'hgroup', 'html', 'main', 'nav', + 'section', 'summary', 'body', 'p', 'dl', 'multicol', 'dd', 'figure', + 'address', 'center', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'listing', 'xmp', 'pre', 'plaintext', 'menu', 'dir', 'ul', 'ol', 'li', 'hr', + 'table', 'tbody', 'thead', 'tfoot', 'th', 'tr', 'td', 'caption' + ]; + + var voids = [ + 'area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', + 'isindex', 'link', 'meta', 'param', 'embed', 'source', 'wbr', 'track' + ]; + + var tableCells = ['td', 'th']; + + var textBlocks = [ + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'address', 'pre', 'form', + 'blockquote', 'center', 'dir', 'fieldset', 'header', 'footer', 'article', + 'section', 'hgroup', 'aside', 'nav', 'figure' + ]; + + var headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + + var lazyLookup = function (items) { + var lookup; + return function (node) { + lookup = lookup ? lookup : Arr.mapToObject(items, Fun.constant(true)); + return lookup.hasOwnProperty(Node.name(node)); + }; + }; + + var isHeading = lazyLookup(headings); + + var isBlock = lazyLookup(blocks); + + var isInline = function (node) { + return Node.isElement(node) && !isBlock(node); + }; + + return { + isBlock: isBlock, + isInline: isInline, + isHeading: isHeading, + isTextBlock: lazyLookup(textBlocks), + isVoid: lazyLookup(voids), + isTableCell: lazyLookup(tableCells) + }; + } +); + +/** + * Parents.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.dom.Parents', + [ + 'ephox.katamari.api.Fun', + 'ephox.sugar.api.dom.Compare', + 'ephox.sugar.api.search.Traverse' + ], + function (Fun, Compare, Traverse) { + var dropLast = function (xs) { + return xs.slice(0, -1); + }; + + var parentsUntil = function (startNode, rootElm, predicate) { + if (Compare.contains(rootElm, startNode)) { + return dropLast(Traverse.parents(startNode, function (elm) { + return predicate(elm) || Compare.eq(elm, rootElm); + })); + } else { + return []; + } + }; + + var parents = function (startNode, rootElm) { + return parentsUntil(startNode, rootElm, Fun.constant(false)); + }; + + var parentsAndSelf = function (startNode, rootElm) { + return [startNode].concat(parents(startNode, rootElm)); + }; + + return { + parentsUntil: parentsUntil, + parents: parents, + parentsAndSelf: parentsAndSelf + }; + } +); + +define( + 'ephox.katamari.api.Options', + + [ + 'ephox.katamari.api.Option' + ], + + function (Option) { + /** cat :: [Option a] -> [a] */ + var cat = function (arr) { + var r = []; + var push = function (x) { + r.push(x); + }; + for (var i = 0; i < arr.length; i++) { + arr[i].each(push); + } + return r; + }; + + /** findMap :: ([a], (a, Int -> Option b)) -> Option b */ + var findMap = function (arr, f) { + for (var i = 0; i < arr.length; i++) { + var r = f(arr[i], i); + if (r.isSome()) { + return r; + } + } + return Option.none(); + }; + + /** + * if all elements in arr are 'some', their inner values are passed as arguments to f + * f must have arity arr.length + */ + var liftN = function(arr, f) { + var r = []; + for (var i = 0; i < arr.length; i++) { + var x = arr[i]; + if (x.isSome()) { + r.push(x.getOrDie()); + } else { + return Option.none(); + } + } + return Option.some(f.apply(null, r)); + }; + + return { + cat: cat, + findMap: findMap, + liftN: liftN + }; + } +); + +/** + * SelectionUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.selection.SelectionUtils', + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.katamari.api.Option', + 'ephox.katamari.api.Options', + 'ephox.sugar.api.dom.Compare', + 'ephox.sugar.api.node.Element', + 'ephox.sugar.api.node.Node', + 'ephox.sugar.api.search.Traverse', + 'tinymce.core.dom.NodeType' + ], + function (Arr, Fun, Option, Options, Compare, Element, Node, Traverse, NodeType) { + var getStartNode = function (rng) { + var sc = rng.startContainer, so = rng.startOffset; + if (NodeType.isText(sc)) { + return so === 0 ? Option.some(Element.fromDom(sc)) : Option.none(); + } else { + return Option.from(sc.childNodes[so]).map(Element.fromDom); + } + }; + + var getEndNode = function (rng) { + var ec = rng.endContainer, eo = rng.endOffset; + if (NodeType.isText(ec)) { + return eo === ec.data.length ? Option.some(Element.fromDom(ec)) : Option.none(); + } else { + return Option.from(ec.childNodes[eo - 1]).map(Element.fromDom); + } + }; + + var getFirstChildren = function (node) { + return Traverse.firstChild(node).fold( + Fun.constant([node]), + function (child) { + return [node].concat(getFirstChildren(child)); + } + ); + }; + + var getLastChildren = function (node) { + return Traverse.lastChild(node).fold( + Fun.constant([node]), + function (child) { + if (Node.name(child) === 'br') { + return Traverse.prevSibling(child).map(function (sibling) { + return [node].concat(getLastChildren(sibling)); + }).getOr([]); + } else { + return [node].concat(getLastChildren(child)); + } + } + ); + }; + + var hasAllContentsSelected = function (elm, rng) { + return Options.liftN([getStartNode(rng), getEndNode(rng)], function (startNode, endNode) { + var start = Arr.find(getFirstChildren(elm), Fun.curry(Compare.eq, startNode)); + var end = Arr.find(getLastChildren(elm), Fun.curry(Compare.eq, endNode)); + return start.isSome() && end.isSome(); + }).getOr(false); + }; + + return { + hasAllContentsSelected: hasAllContentsSelected + }; + } +); + +/** + * FragmentReader.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.selection.FragmentReader', + [ + 'ephox.katamari.api.Arr', + 'ephox.katamari.api.Fun', + 'ephox.sugar.api.dom.Insert', + 'ephox.sugar.api.dom.Replication', + 'ephox.sugar.api.node.Element', + 'ephox.sugar.api.node.Fragment', + 'ephox.sugar.api.node.Node', + 'tinymce.core.dom.ElementType', + 'tinymce.core.dom.Parents', + 'tinymce.core.selection.SelectionUtils' + ], + function (Arr, Fun, Insert, Replication, Element, Fragment, Node, ElementType, Parents, SelectionUtils) { + var findParentListContainer = function (parents) { + return Arr.find(parents, function (elm) { + return Node.name(elm) === 'ul' || Node.name(elm) === 'ol'; + }); + }; + + var getFullySelectedListWrappers = function (parents, rng) { + return Arr.find(parents, function (elm) { + return Node.name(elm) === 'li' && SelectionUtils.hasAllContentsSelected(elm, rng); + }).fold( + Fun.constant([]), + function (li) { + return findParentListContainer(parents).map(function (listCont) { + return [ + Element.fromTag('li'), + Element.fromTag(Node.name(listCont)) + ]; + }).getOr([]); + } + ); + }; + + var wrap = function (innerElm, elms) { + var wrapped = Arr.foldl(elms, function (acc, elm) { + Insert.append(elm, acc); + return elm; + }, innerElm); + return elms.length > 0 ? Fragment.fromElements([wrapped]) : wrapped; + }; + + var getWrapElements = function (rootNode, rng) { + var parents = Parents.parentsAndSelf(Element.fromDom(rng.commonAncestorContainer), Element.fromDom(rootNode)); + var wrapElements = Arr.filter(parents, function (elm) { + return ElementType.isInline(elm) || ElementType.isHeading(elm); + }); + var fullWrappers = getFullySelectedListWrappers(parents, rng); + return Arr.map(wrapElements.concat(fullWrappers), Replication.shallow); + }; + + var getFragmentFromRange = function (rootNode, rng) { + return wrap(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng)); + }; + + var read = function (rootNode, rng) { + return rng.collapsed ? Fragment.fromElements([]) : getFragmentFromRange(rootNode, rng); + }; + + return { + read: read + }; + } +); + /** * Selection.js * @@ -18707,10 +20903,11 @@ define( 'tinymce.core.dom.TreeWalker', 'tinymce.core.dom.TridentSelection', 'tinymce.core.Env', + 'tinymce.core.selection.FragmentReader', 'tinymce.core.text.Zwsp', 'tinymce.core.util.Tools' ], - function (CaretPosition, BookmarkManager, ControlSelection, NodeType, RangeUtils, ScrollIntoView, TreeWalker, TridentSelection, Env, Zwsp, Tools) { + function (CaretPosition, BookmarkManager, ControlSelection, NodeType, RangeUtils, ScrollIntoView, TreeWalker, TridentSelection, Env, FragmentReader, Zwsp, Tools) { var each = Tools.each, trim = Tools.trim; var isIE = Env.ie; @@ -18792,8 +20989,7 @@ define( } if (rng.cloneContents) { - fragment = rng.cloneContents(); - + fragment = args.contextual ? FragmentReader.read(self.editor.getBody(), rng).dom() : rng.cloneContents(); if (fragment) { tmpElm.appendChild(fragment); } @@ -19858,7 +22054,7 @@ define( function getRequiredParent(elm, candidate) { var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm; var elmRule = schema.getElementRule(name); - var parentsRequired = elmRule.parentsRequired; + var parentsRequired = elmRule && elmRule.parentsRequired; if (parentsRequired && parentsRequired.length) { return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0]; @@ -19869,7 +22065,7 @@ define( function wrapInHtml(elm, ancestry, siblings) { var parent, parentCandidate, parentRequired; - var ancestor = ancestry.length && ancestry[0]; + var ancestor = ancestry.length > 0 && ancestry[0]; var ancestorName = ancestor && ancestor.name; parentRequired = getRequiredParent(elm, ancestorName); @@ -20445,10 +22641,10 @@ define( { inline: 'strike', remove: 'all' } ], - forecolor: { inline: 'span', styles: { color: '%value' }, links: true, remove_similar: true }, - hilitecolor: { inline: 'span', styles: { backgroundColor: '%value' }, links: true, remove_similar: true }, - fontname: { inline: 'span', styles: { fontFamily: '%value' } }, - fontsize: { inline: 'span', styles: { fontSize: '%value' } }, + forecolor: { inline: 'span', styles: { color: '%value' }, links: true, remove_similar: true, clear_child_styles: true }, + hilitecolor: { inline: 'span', styles: { backgroundColor: '%value' }, links: true, remove_similar: true, clear_child_styles: true }, + fontname: { inline: 'span', styles: { fontFamily: '%value' }, clear_child_styles: true }, + fontsize: { inline: 'span', styles: { fontSize: '%value' }, clear_child_styles: true }, fontsize_class: { inline: 'span', attributes: { 'class': '%value' } }, blockquote: { block: 'blockquote', wrapper: 1, remove: 'all' }, subscript: { inline: 'sub' }, @@ -20491,6 +22687,16 @@ define( register(ed.settings.formats); } + var clearChildStyles = function (format, node) { + if (format.clear_child_styles) { + each(dom.select('*', node), function (node) { + each(format.styles, function (value, name) { + dom.setStyle(node, name, ''); + }); + }); + } + }; + function addKeyboardShortcuts() { // Add some inline shortcuts ed.addShortcut('meta+b', 'bold_desc', 'Bold'); @@ -20933,6 +23139,8 @@ define( removeFormat(format, vars, child, format.exact ? child : null); }); + + clearChildStyles(format, node); }); // Remove format if direct parent already has the same format @@ -23029,7 +25237,9 @@ define( }; var read = function (elm) { - return Arr.map(elm.childNodes, getOuterHtml); + return Arr.filter(Arr.map(elm.childNodes, getOuterHtml), function (item) { + return item.length > 0; + }); }; var write = function (fragments, elm) { @@ -23524,1390 +25734,6 @@ define( } ); -define( - 'ephox.katamari.api.Options', - - [ - 'ephox.katamari.api.Option' - ], - - function (Option) { - /** cat :: [Option a] -> [a] */ - var cat = function (arr) { - var r = []; - var push = function (x) { - r.push(x); - }; - for (var i = 0; i < arr.length; i++) { - arr[i].each(push); - } - return r; - }; - - /** findMap :: ([a], (a, Int -> Option b)) -> Option b */ - var findMap = function (arr, f) { - for (var i = 0; i < arr.length; i++) { - var r = f(arr[i], i); - if (r.isSome()) { - return r; - } - } - return Option.none(); - }; - - /** - * if all elements in arr are 'some', their inner values are passed as arguments to f - * f must have arity arr.length - */ - var liftN = function(arr, f) { - var r = []; - for (var i = 0; i < arr.length; i++) { - var x = arr[i]; - if (x.isSome()) { - r.push(x.getOrDie()); - } else { - return Option.none(); - } - } - return Option.some(f.apply(null, r)); - }; - - return { - cat: cat, - findMap: findMap, - liftN: liftN - }; - } -); - -define( - 'ephox.katamari.data.Immutable', - - [ - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Fun', - 'global!Array', - 'global!Error' - ], - - function (Arr, Fun, Array, Error) { - return function () { - var fields = arguments; - return function(/* values */) { - // Don't use array slice(arguments), makes the whole function unoptimisable on Chrome - var values = new Array(arguments.length); - for (var i = 0; i < values.length; i++) values[i] = arguments[i]; - - if (fields.length !== values.length) - throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); - - var struct = {}; - Arr.each(fields, function (name, i) { - struct[name] = Fun.constant(values[i]); - }); - return struct; - }; - }; - } -); - -define( - 'ephox.katamari.api.Obj', - - [ - 'ephox.katamari.api.Option', - 'global!Object' - ], - - function (Option, Object) { - // There are many variations of Object iteration that are faster than the 'for-in' style: - // http://jsperf.com/object-keys-iteration/107 - // - // Use the native keys if it is available (IE9+), otherwise fall back to manually filtering - var keys = (function () { - var fastKeys = Object.keys; - - // This technically means that 'each' and 'find' on IE8 iterate through the object twice. - // This code doesn't run on IE8 much, so it's an acceptable tradeoff. - // If it becomes a problem we can always duplicate the feature detection inside each and find as well. - var slowKeys = function (o) { - var r = []; - for (var i in o) { - if (o.hasOwnProperty(i)) { - r.push(i); - } - } - return r; - }; - - return fastKeys === undefined ? slowKeys : fastKeys; - })(); - - - var each = function (obj, f) { - var props = keys(obj); - for (var k = 0, len = props.length; k < len; k++) { - var i = props[k]; - var x = obj[i]; - f(x, i, obj); - } - }; - - /** objectMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> x)) -> JsObj(k, x) */ - var objectMap = function (obj, f) { - return tupleMap(obj, function (x, i, obj) { - return { - k: i, - v: f(x, i, obj) - }; - }); - }; - - /** tupleMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> { k: x, v: y })) -> JsObj(x, y) */ - var tupleMap = function (obj, f) { - var r = {}; - each(obj, function (x, i) { - var tuple = f(x, i, obj); - r[tuple.k] = tuple.v; - }); - return r; - }; - - /** bifilter :: (JsObj(k, v), (v, k -> Bool)) -> { t: JsObj(k, v), f: JsObj(k, v) } */ - var bifilter = function (obj, pred) { - var t = {}; - var f = {}; - each(obj, function(x, i) { - var branch = pred(x, i) ? t : f; - branch[i] = x; - }); - return { - t: t, - f: f - }; - }; - - /** mapToArray :: (JsObj(k, v), (v, k -> a)) -> [a] */ - var mapToArray = function (obj, f) { - var r = []; - each(obj, function(value, name) { - r.push(f(value, name)); - }); - return r; - }; - - /** find :: (JsObj(k, v), (v, k, JsObj(k, v) -> Bool)) -> Option v */ - var find = function (obj, pred) { - var props = keys(obj); - for (var k = 0, len = props.length; k < len; k++) { - var i = props[k]; - var x = obj[i]; - if (pred(x, i, obj)) { - return Option.some(x); - } - } - return Option.none(); - }; - - /** values :: JsObj(k, v) -> [v] */ - var values = function (obj) { - return mapToArray(obj, function (v) { - return v; - }); - }; - - var size = function (obj) { - return values(obj).length; - }; - - return { - bifilter: bifilter, - each: each, - map: objectMap, - mapToArray: mapToArray, - tupleMap: tupleMap, - find: find, - keys: keys, - values: values, - size: size - }; - } -); -define( - 'ephox.katamari.api.Type', - - [ - 'global!Array', - 'global!String' - ], - - function (Array, String) { - var typeOf = function(x) { - if (x === null) return 'null'; - var t = typeof x; - if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; - if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; - return t; - }; - - var isType = function (type) { - return function (value) { - return typeOf(value) === type; - }; - }; - - return { - isString: isType('string'), - isObject: isType('object'), - isArray: isType('array'), - isNull: isType('null'), - isBoolean: isType('boolean'), - isUndefined: isType('undefined'), - isFunction: isType('function'), - isNumber: isType('number') - }; - } -); - - -define( - 'ephox.katamari.util.BagUtils', - - [ - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Type', - 'global!Error' - ], - - function (Arr, Type, Error) { - var sort = function (arr) { - return arr.slice(0).sort(); - }; - - var reqMessage = function (required, keys) { - throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.'); - }; - - var unsuppMessage = function (unsupported) { - throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', ')); - }; - - var validateStrArr = function (label, array) { - if (!Type.isArray(array)) throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.'); - Arr.each(array, function (a) { - if (!Type.isString(a)) throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.'); - }); - }; - - var invalidTypeMessage = function (incorrect, type) { - throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.'); - }; - - var checkDupes = function (everything) { - var sorted = sort(everything); - var dupe = Arr.find(sorted, function (s, i) { - return i < sorted.length -1 && s === sorted[i + 1]; - }); - - dupe.each(function (d) { - throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].'); - }); - }; - - return { - sort: sort, - reqMessage: reqMessage, - unsuppMessage: unsuppMessage, - validateStrArr: validateStrArr, - invalidTypeMessage: invalidTypeMessage, - checkDupes: checkDupes - }; - } -); -define( - 'ephox.katamari.data.MixedBag', - - [ - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Fun', - 'ephox.katamari.api.Obj', - 'ephox.katamari.api.Option', - 'ephox.katamari.util.BagUtils', - 'global!Error', - 'global!Object' - ], - - function (Arr, Fun, Obj, Option, BagUtils, Error, Object) { - - return function (required, optional) { - var everything = required.concat(optional); - if (everything.length === 0) throw new Error('You must specify at least one required or optional field.'); - - BagUtils.validateStrArr('required', required); - BagUtils.validateStrArr('optional', optional); - - BagUtils.checkDupes(everything); - - return function (obj) { - var keys = Obj.keys(obj); - - // Ensure all required keys are present. - var allReqd = Arr.forall(required, function (req) { - return Arr.contains(keys, req); - }); - - if (! allReqd) BagUtils.reqMessage(required, keys); - - var unsupported = Arr.filter(keys, function (key) { - return !Arr.contains(everything, key); - }); - - if (unsupported.length > 0) BagUtils.unsuppMessage(unsupported); - - var r = {}; - Arr.each(required, function (req) { - r[req] = Fun.constant(obj[req]); - }); - - Arr.each(optional, function (opt) { - r[opt] = Fun.constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]): Option.none()); - }); - - return r; - }; - }; - } -); -define( - 'ephox.katamari.api.Struct', - - [ - 'ephox.katamari.data.Immutable', - 'ephox.katamari.data.MixedBag' - ], - - function (Immutable, MixedBag) { - return { - immutable: Immutable, - immutableBag: MixedBag - }; - } -); - -define( - 'ephox.katamari.api.Global', - - [ - ], - - function () { - return Function('return this;')(); - } -); - - -define( - 'ephox.katamari.api.Resolve', - - [ - 'ephox.katamari.api.Global' - ], - - function (Global) { - /** path :: ([String], JsObj?) -> JsObj */ - var path = function (parts, scope) { - var o = scope !== undefined ? scope : Global; - for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) - o = o[parts[i]]; - return o; - }; - - /** resolve :: (String, JsObj?) -> JsObj */ - var resolve = function (p, scope) { - var parts = p.split('.'); - return path(parts, scope); - }; - - /** step :: (JsObj, String) -> JsObj */ - var step = function (o, part) { - if (o[part] === undefined || o[part] === null) - o[part] = {}; - return o[part]; - }; - - /** forge :: ([String], JsObj?) -> JsObj */ - var forge = function (parts, target) { - var o = target !== undefined ? target : Global; - for (var i = 0; i < parts.length; ++i) - o = step(o, parts[i]); - return o; - }; - - /** namespace :: (String, JsObj?) -> JsObj */ - var namespace = function (name, target) { - var parts = name.split('.'); - return forge(parts, target); - }; - - return { - path: path, - resolve: resolve, - forge: forge, - namespace: namespace - }; - } -); - - -define( - 'ephox.sand.util.Global', - - [ - 'ephox.katamari.api.Resolve' - ], - - function (Resolve) { - var unsafe = function (name, scope) { - return Resolve.resolve(name, scope); - }; - - var getOrDie = function (name, scope) { - var actual = unsafe(name, scope); - - if (actual === undefined) throw name + ' not available on this browser'; - return actual; - }; - - return { - getOrDie: getOrDie - }; - } -); -define( - 'ephox.sand.api.Node', - - [ - 'ephox.sand.util.Global' - ], - - function (Global) { - /* - * MDN says (yes) for IE, but it's undefined on IE8 - */ - var node = function () { - var f = Global.getOrDie('Node'); - return f; - }; - - /* - * Most of numerosity doesn't alter the methods on the object. - * We're making an exception for Node, because bitwise and is so easy to get wrong. - * - * Might be nice to ADT this at some point instead of having individual methods. - */ - - var compareDocumentPosition = function (a, b, match) { - // Returns: 0 if e1 and e2 are the same node, or a bitmask comparing the positions - // of nodes e1 and e2 in their documents. See the URL below for bitmask interpretation - // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition - return (a.compareDocumentPosition(b) & match) !== 0; - }; - - var documentPositionPreceding = function (a, b) { - return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); - }; - - var documentPositionContainedBy = function (a, b) { - return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); - }; - - return { - documentPositionPreceding: documentPositionPreceding, - documentPositionContainedBy: documentPositionContainedBy - }; - } -); -define( - 'ephox.katamari.api.Thunk', - - [ - ], - - function () { - - var cached = function (f) { - var called = false; - var r; - return function() { - if (!called) { - called = true; - r = f.apply(null, arguments); - } - return r; - }; - }; - - return { - cached: cached - }; - } -); - -defineGlobal("global!Number", Number); -define( - 'ephox.sand.detect.Version', - - [ - 'ephox.katamari.api.Arr', - 'global!Number', - 'global!String' - ], - - function (Arr, Number, String) { - var firstMatch = function (regexes, s) { - for (var i = 0; i < regexes.length; i++) { - var x = regexes[i]; - if (x.test(s)) return x; - } - return undefined; - }; - - var find = function (regexes, agent) { - var r = firstMatch(regexes, agent); - if (!r) return { major : 0, minor : 0 }; - var group = function(i) { - return Number(agent.replace(r, '$' + i)); - }; - return nu(group(1), group(2)); - }; - - var detect = function (versionRegexes, agent) { - var cleanedAgent = String(agent).toLowerCase(); - - if (versionRegexes.length === 0) return unknown(); - return find(versionRegexes, cleanedAgent); - }; - - var unknown = function () { - return nu(0, 0); - }; - - var nu = function (major, minor) { - return { major: major, minor: minor }; - }; - - return { - nu: nu, - detect: detect, - unknown: unknown - }; - } -); -define( - 'ephox.sand.core.Browser', - - [ - 'ephox.katamari.api.Fun', - 'ephox.sand.detect.Version' - ], - - function (Fun, Version) { - var edge = 'Edge'; - var chrome = 'Chrome'; - var ie = 'IE'; - var opera = 'Opera'; - var firefox = 'Firefox'; - var safari = 'Safari'; - - var isBrowser = function (name, current) { - return function () { - return current === name; - }; - }; - - var unknown = function () { - return nu({ - current: undefined, - version: Version.unknown() - }); - }; - - var nu = function (info) { - var current = info.current; - var version = info.version; - - return { - current: current, - version: version, - - // INVESTIGATE: Rename to Edge ? - isEdge: isBrowser(edge, current), - isChrome: isBrowser(chrome, current), - // NOTE: isIe just looks too weird - isIE: isBrowser(ie, current), - isOpera: isBrowser(opera, current), - isFirefox: isBrowser(firefox, current), - isSafari: isBrowser(safari, current) - }; - }; - - return { - unknown: unknown, - nu: nu, - edge: Fun.constant(edge), - chrome: Fun.constant(chrome), - ie: Fun.constant(ie), - opera: Fun.constant(opera), - firefox: Fun.constant(firefox), - safari: Fun.constant(safari) - }; - } -); -define( - 'ephox.sand.core.OperatingSystem', - - [ - 'ephox.katamari.api.Fun', - 'ephox.sand.detect.Version' - ], - - function (Fun, Version) { - var windows = 'Windows'; - var ios = 'iOS'; - var android = 'Android'; - var linux = 'Linux'; - var osx = 'OSX'; - var solaris = 'Solaris'; - var freebsd = 'FreeBSD'; - - // Though there is a bit of dupe with this and Browser, trying to - // reuse code makes it much harder to follow and change. - var isOS = function (name, current) { - return function () { - return current === name; - }; - }; - - var unknown = function () { - return nu({ - current: undefined, - version: Version.unknown() - }); - }; - - var nu = function (info) { - var current = info.current; - var version = info.version; - - return { - current: current, - version: version, - - isWindows: isOS(windows, current), - // TODO: Fix capitalisation - isiOS: isOS(ios, current), - isAndroid: isOS(android, current), - isOSX: isOS(osx, current), - isLinux: isOS(linux, current), - isSolaris: isOS(solaris, current), - isFreeBSD: isOS(freebsd, current) - }; - }; - - return { - unknown: unknown, - nu: nu, - - windows: Fun.constant(windows), - ios: Fun.constant(ios), - android: Fun.constant(android), - linux: Fun.constant(linux), - osx: Fun.constant(osx), - solaris: Fun.constant(solaris), - freebsd: Fun.constant(freebsd) - }; - } -); -define( - 'ephox.sand.detect.DeviceType', - - [ - 'ephox.katamari.api.Fun' - ], - - function (Fun) { - return function (os, browser, userAgent) { - var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; - var isiPhone = os.isiOS() && !isiPad; - var isAndroid3 = os.isAndroid() && os.version.major === 3; - var isAndroid4 = os.isAndroid() && os.version.major === 4; - var isTablet = isiPad || isAndroid3 || ( isAndroid4 && /mobile/i.test(userAgent) === true ); - var isTouch = os.isiOS() || os.isAndroid(); - var isPhone = isTouch && !isTablet; - - var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; - - return { - isiPad : Fun.constant(isiPad), - isiPhone: Fun.constant(isiPhone), - isTablet: Fun.constant(isTablet), - isPhone: Fun.constant(isPhone), - isTouch: Fun.constant(isTouch), - isAndroid: os.isAndroid, - isiOS: os.isiOS, - isWebView: Fun.constant(iOSwebview) - }; - }; - } -); -define( - 'ephox.sand.detect.UaString', - - [ - 'ephox.katamari.api.Arr', - 'ephox.sand.detect.Version', - 'global!String' - ], - - function (Arr, Version, String) { - var detect = function (candidates, userAgent) { - var agent = String(userAgent).toLowerCase(); - return Arr.find(candidates, function (candidate) { - return candidate.search(agent); - }); - }; - - // They (browser and os) are the same at the moment, but they might - // not stay that way. - var detectBrowser = function (browsers, userAgent) { - return detect(browsers, userAgent).map(function (browser) { - var version = Version.detect(browser.versionRegexes, userAgent); - return { - current: browser.name, - version: version - }; - }); - }; - - var detectOs = function (oses, userAgent) { - return detect(oses, userAgent).map(function (os) { - var version = Version.detect(os.versionRegexes, userAgent); - return { - current: os.name, - version: version - }; - }); - }; - - return { - detectBrowser: detectBrowser, - detectOs: detectOs - }; - } -); -define( - 'ephox.katamari.str.StrAppend', - - [ - - ], - - function () { - var addToStart = function (str, prefix) { - return prefix + str; - }; - - var addToEnd = function (str, suffix) { - return str + suffix; - }; - - var removeFromStart = function (str, numChars) { - return str.substring(numChars); - }; - - var removeFromEnd = function (str, numChars) { - return str.substring(0, str.length - numChars); - }; - - return { - addToStart: addToStart, - addToEnd: addToEnd, - removeFromStart: removeFromStart, - removeFromEnd: removeFromEnd - }; - } -); -define( - 'ephox.katamari.str.StringParts', - - [ - 'ephox.katamari.api.Option', - 'global!Error' - ], - - function (Option, Error) { - /** Return the first 'count' letters from 'str'. -- * e.g. first("abcde", 2) === "ab" -- */ - var first = function(str, count) { - return str.substr(0, count); - }; - - /** Return the last 'count' letters from 'str'. - * e.g. last("abcde", 2) === "de" - */ - var last = function(str, count) { - return str.substr(str.length - count, str.length); - }; - - var head = function(str) { - return str === '' ? Option.none() : Option.some(str.substr(0, 1)); - }; - - var tail = function(str) { - return str === '' ? Option.none() : Option.some(str.substring(1)); - }; - - return { - first: first, - last: last, - head: head, - tail: tail - }; - } -); -define( - 'ephox.katamari.api.Strings', - - [ - 'ephox.katamari.str.StrAppend', - 'ephox.katamari.str.StringParts', - 'global!Error' - ], - - function (StrAppend, StringParts, Error) { - var checkRange = function(str, substr, start) { - if (substr === '') return true; - if (str.length < substr.length) return false; - var x = str.substr(start, start + substr.length); - return x === substr; - }; - - /** Given a string and object, perform template-replacements on the string, as specified by the object. - * Any template fields of the form ${name} are replaced by the string or number specified as obj["name"] - * Based on Douglas Crockford's 'supplant' method for template-replace of strings. Uses different template format. - */ - var supplant = function(str, obj) { - var isStringOrNumber = function(a) { - var t = typeof a; - return t === 'string' || t === 'number'; - }; - - return str.replace(/\${([^{}]*)}/g, - function (a, b) { - var value = obj[b]; - return isStringOrNumber(value) ? value : a; - } - ); - }; - - var removeLeading = function (str, prefix) { - return startsWith(str, prefix) ? StrAppend.removeFromStart(str, prefix.length) : str; - }; - - var removeTrailing = function (str, prefix) { - return endsWith(str, prefix) ? StrAppend.removeFromEnd(str, prefix.length) : str; - }; - - var ensureLeading = function (str, prefix) { - return startsWith(str, prefix) ? str : StrAppend.addToStart(str, prefix); - }; - - var ensureTrailing = function (str, prefix) { - return endsWith(str, prefix) ? str : StrAppend.addToEnd(str, prefix); - }; - - var contains = function(str, substr) { - return str.indexOf(substr) !== -1; - }; - - var capitalize = function(str) { - return StringParts.head(str).bind(function (head) { - return StringParts.tail(str).map(function (tail) { - return head.toUpperCase() + tail; - }); - }).getOr(str); - }; - - /** Does 'str' start with 'prefix'? - * Note: all strings start with the empty string. - * More formally, for all strings x, startsWith(x, ""). - * This is so that for all strings x and y, startsWith(y + x, y) - */ - var startsWith = function(str, prefix) { - return checkRange(str, prefix, 0); - }; - - /** Does 'str' end with 'suffix'? - * Note: all strings end with the empty string. - * More formally, for all strings x, endsWith(x, ""). - * This is so that for all strings x and y, endsWith(x + y, y) - */ - var endsWith = function(str, suffix) { - return checkRange(str, suffix, str.length - suffix.length); - }; - - - /** removes all leading and trailing spaces */ - var trim = function(str) { - return str.replace(/^\s+|\s+$/g, ''); - }; - - var lTrim = function(str) { - return str.replace(/^\s+/g, ''); - }; - - var rTrim = function(str) { - return str.replace(/\s+$/g, ''); - }; - - return { - supplant: supplant, - startsWith: startsWith, - removeLeading: removeLeading, - removeTrailing: removeTrailing, - ensureLeading: ensureLeading, - ensureTrailing: ensureTrailing, - endsWith: endsWith, - contains: contains, - trim: trim, - lTrim: lTrim, - rTrim: rTrim, - capitalize: capitalize - }; - } -); - -define( - 'ephox.sand.info.PlatformInfo', - - [ - 'ephox.katamari.api.Fun', - 'ephox.katamari.api.Strings' - ], - - function (Fun, Strings) { - var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; - - var checkContains = function (target) { - return function (uastring) { - return Strings.contains(uastring, target); - }; - }; - - var browsers = [ - { - name : 'Edge', - versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], - search: function (uastring) { - var monstrosity = Strings.contains(uastring, 'edge/') && Strings.contains(uastring, 'chrome') && Strings.contains(uastring, 'safari') && Strings.contains(uastring, 'applewebkit'); - return monstrosity; - } - }, - { - name : 'Chrome', - versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex], - search : function (uastring) { - return Strings.contains(uastring, 'chrome') && !Strings.contains(uastring, 'chromeframe'); - } - }, - { - name : 'IE', - versionRegexes: [/.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/], - search: function (uastring) { - return Strings.contains(uastring, 'msie') || Strings.contains(uastring, 'trident'); - } - }, - // INVESTIGATE: Is this still the Opera user agent? - { - name : 'Opera', - versionRegexes: [normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/], - search : checkContains('opera') - }, - { - name : 'Firefox', - versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], - search : checkContains('firefox') - }, - { - name : 'Safari', - versionRegexes: [normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/], - search : function (uastring) { - return (Strings.contains(uastring, 'safari') || Strings.contains(uastring, 'mobile/')) && Strings.contains(uastring, 'applewebkit'); - } - } - ]; - - var oses = [ - { - name : 'Windows', - search : checkContains('win'), - versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] - }, - { - name : 'iOS', - search : function (uastring) { - return Strings.contains(uastring, 'iphone') || Strings.contains(uastring, 'ipad'); - }, - versionRegexes: [/.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/] - }, - { - name : 'Android', - search : checkContains('android'), - versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] - }, - { - name : 'OSX', - search : checkContains('os x'), - versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] - }, - { - name : 'Linux', - search : checkContains('linux'), - versionRegexes: [ ] - }, - { name : 'Solaris', - search : checkContains('sunos'), - versionRegexes: [ ] - }, - { - name : 'FreeBSD', - search : checkContains('freebsd'), - versionRegexes: [ ] - } - ]; - - return { - browsers: Fun.constant(browsers), - oses: Fun.constant(oses) - }; - } -); -define( - 'ephox.sand.core.PlatformDetection', - - [ - 'ephox.sand.core.Browser', - 'ephox.sand.core.OperatingSystem', - 'ephox.sand.detect.DeviceType', - 'ephox.sand.detect.UaString', - 'ephox.sand.info.PlatformInfo' - ], - - function (Browser, OperatingSystem, DeviceType, UaString, PlatformInfo) { - var detect = function (userAgent) { - var browsers = PlatformInfo.browsers(); - var oses = PlatformInfo.oses(); - - var browser = UaString.detectBrowser(browsers, userAgent).fold( - Browser.unknown, - Browser.nu - ); - var os = UaString.detectOs(oses, userAgent).fold( - OperatingSystem.unknown, - OperatingSystem.nu - ); - var deviceType = DeviceType(os, browser, userAgent); - - return { - browser: browser, - os: os, - deviceType: deviceType - }; - }; - - return { - detect: detect - }; - } -); -defineGlobal("global!navigator", navigator); -define( - 'ephox.sand.api.PlatformDetection', - - [ - 'ephox.katamari.api.Thunk', - 'ephox.sand.core.PlatformDetection', - 'global!navigator' - ], - - function (Thunk, PlatformDetection, navigator) { - var detect = Thunk.cached(function () { - var userAgent = navigator.userAgent; - return PlatformDetection.detect(userAgent); - }); - - return { - detect: detect - }; - } -); -define("global!console", [], function () { if (typeof console === "undefined") console = { log: function () {} }; return console; }); -defineGlobal("global!document", document); -define( - 'ephox.sugar.api.node.Element', - - [ - 'ephox.katamari.api.Fun', - 'global!Error', - 'global!console', - 'global!document' - ], - - function (Fun, Error, console, document) { - var fromHtml = function (html, scope) { - var doc = scope || document; - var div = doc.createElement('div'); - div.innerHTML = html; - if (!div.hasChildNodes() || div.childNodes.length > 1) { - console.error('HTML does not have a single root node', html); - throw 'HTML must have a single root node'; - } - return fromDom(div.childNodes[0]); - }; - - var fromTag = function (tag, scope) { - var doc = scope || document; - var node = doc.createElement(tag); - return fromDom(node); - }; - - var fromText = function (text, scope) { - var doc = scope || document; - var node = doc.createTextNode(text); - return fromDom(node); - }; - - var fromDom = function (node) { - if (node === null || node === undefined) throw new Error('Node cannot be null or undefined'); - return { - dom: Fun.constant(node) - }; - }; - - return { - fromHtml: fromHtml, - fromTag: fromTag, - fromText: fromText, - fromDom: fromDom - }; - } -); - -define( - 'ephox.sugar.api.node.NodeTypes', - - [ - - ], - - function () { - return { - ATTRIBUTE: 2, - CDATA_SECTION: 4, - COMMENT: 8, - DOCUMENT: 9, - DOCUMENT_TYPE: 10, - DOCUMENT_FRAGMENT: 11, - ELEMENT: 1, - TEXT: 3, - PROCESSING_INSTRUCTION: 7, - ENTITY_REFERENCE: 5, - ENTITY: 6, - NOTATION: 12 - }; - } -); -define( - 'ephox.sugar.api.search.Selectors', - - [ - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Option', - 'ephox.sugar.api.node.Element', - 'ephox.sugar.api.node.NodeTypes', - 'global!Error', - 'global!document' - ], - - function (Arr, Option, Element, NodeTypes, Error, document) { - /* - * There's a lot of code here; the aim is to allow the browser to optimise constant comparisons, - * instead of doing object lookup feature detection on every call - */ - var STANDARD = 0; - var MSSTANDARD = 1; - var WEBKITSTANDARD = 2; - var FIREFOXSTANDARD = 3; - - var selectorType = (function () { - var test = document.createElement('span'); - // As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function. - // Still check for the others, but do it last. - return test.matches !== undefined ? STANDARD : - test.msMatchesSelector !== undefined ? MSSTANDARD : - test.webkitMatchesSelector !== undefined ? WEBKITSTANDARD : - test.mozMatchesSelector !== undefined ? FIREFOXSTANDARD : - -1; - })(); - - - var ELEMENT = NodeTypes.ELEMENT; - var DOCUMENT = NodeTypes.DOCUMENT; - - var is = function (element, selector) { - var elem = element.dom(); - if (elem.nodeType !== ELEMENT) return false; // documents have querySelector but not matches - - // As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function. - // Still check for the others, but do it last. - else if (selectorType === STANDARD) return elem.matches(selector); - else if (selectorType === MSSTANDARD) return elem.msMatchesSelector(selector); - else if (selectorType === WEBKITSTANDARD) return elem.webkitMatchesSelector(selector); - else if (selectorType === FIREFOXSTANDARD) return elem.mozMatchesSelector(selector); - else throw new Error('Browser lacks native selectors'); // unfortunately we can't throw this on startup :( - }; - - var bypassSelector = function (dom) { - // Only elements and documents support querySelector - return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT || - // IE fix for complex queries on empty nodes: http://jsfiddle.net/spyder/fv9ptr5L/ - dom.childElementCount === 0; - }; - - var all = function (selector, scope) { - var base = scope === undefined ? document : scope.dom(); - return bypassSelector(base) ? [] : Arr.map(base.querySelectorAll(selector), Element.fromDom); - }; - - var one = function (selector, scope) { - var base = scope === undefined ? document : scope.dom(); - return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); - }; - - return { - all: all, - is: is, - one: one - }; - } -); - -define( - 'ephox.sugar.api.dom.Compare', - - [ - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Fun', - 'ephox.sand.api.Node', - 'ephox.sand.api.PlatformDetection', - 'ephox.sugar.api.search.Selectors' - ], - - function (Arr, Fun, Node, PlatformDetection, Selectors) { - - var eq = function (e1, e2) { - return e1.dom() === e2.dom(); - }; - - var isEqualNode = function (e1, e2) { - return e1.dom().isEqualNode(e2.dom()); - }; - - var member = function (element, elements) { - return Arr.exists(elements, Fun.curry(eq, element)); - }; - - // DOM contains() method returns true if e1===e2, we define our contains() to return false (a node does not contain itself). - var regularContains = function (e1, e2) { - var d1 = e1.dom(), d2 = e2.dom(); - return d1 === d2 ? false : d1.contains(d2); - }; - - var ieContains = function (e1, e2) { - // IE only implements the contains() method for Element nodes. - // It fails for Text nodes, so implement it using compareDocumentPosition() - // https://connect.microsoft.com/IE/feedback/details/780874/node-contains-is-incorrect - // Note that compareDocumentPosition returns CONTAINED_BY if 'e2 *is_contained_by* e1': - // Also, compareDocumentPosition defines a node containing itself as false. - return Node.documentPositionContainedBy(e1.dom(), e2.dom()); - }; - - var browser = PlatformDetection.detect().browser; - - // Returns: true if node e1 contains e2, otherwise false. - // (returns false if e1===e2: A node does not contain itself). - var contains = browser.isIE() ? ieContains : regularContains; - - return { - eq: eq, - isEqualNode: isEqualNode, - member: member, - contains: contains, - - // Only used by DomUniverse. Remove (or should Selectors.is move here?) - is: Selectors.is - }; - } -); - -define( - 'ephox.sugar.api.node.Node', - - [ - 'ephox.sugar.api.node.NodeTypes' - ], - - function (NodeTypes) { - var name = function (element) { - var r = element.dom().nodeName; - return r.toLowerCase(); - }; - - var type = function (element) { - return element.dom().nodeType; - }; - - var value = function (element) { - return element.dom().nodeValue; - }; - - var isType = function (t) { - return function (element) { - return type(element) === t; - }; - }; - - var isComment = function (element) { - return type(element) === NodeTypes.COMMENT || name(element) === '#comment'; - }; - - var isElement = isType(NodeTypes.ELEMENT); - var isText = isType(NodeTypes.TEXT); - var isDocument = isType(NodeTypes.DOCUMENT); - - return { - name: name, - type: type, - value: value, - isElement: isElement, - isText: isText, - isDocument: isDocument, - isComment: isComment - }; - } -); - define( 'ephox.sugar.api.node.Body', @@ -25052,189 +25878,6 @@ define( } ); -define( - 'ephox.sugar.alien.Recurse', - - [ - - ], - - function () { - /** - * Applies f repeatedly until it completes (by returning Option.none()). - * - * Normally would just use recursion, but JavaScript lacks tail call optimisation. - * - * This is what recursion looks like when manually unravelled :) - */ - var toArray = function (target, f) { - var r = []; - - var recurse = function (e) { - r.push(e); - return f(e); - }; - - var cur = f(target); - do { - cur = cur.bind(recurse); - } while (cur.isSome()); - - return r; - }; - - return { - toArray: toArray - }; - } -); -define( - 'ephox.sugar.api.search.Traverse', - - [ - 'ephox.katamari.api.Type', - 'ephox.katamari.api.Arr', - 'ephox.katamari.api.Fun', - 'ephox.katamari.api.Option', - 'ephox.katamari.api.Struct', - 'ephox.sugar.alien.Recurse', - 'ephox.sugar.api.dom.Compare', - 'ephox.sugar.api.node.Element' - ], - - function (Type, Arr, Fun, Option, Struct, Recurse, Compare, Element) { - // The document associated with the current element - var owner = function (element) { - return Element.fromDom(element.dom().ownerDocument); - }; - - var documentElement = function (element) { - // TODO: Avoid unnecessary wrap/unwrap here - var doc = owner(element); - return Element.fromDom(doc.dom().documentElement); - }; - - // The window element associated with the element - var defaultView = function (element) { - var el = element.dom(); - var defaultView = el.ownerDocument.defaultView; - return Element.fromDom(defaultView); - }; - - var parent = function (element) { - var dom = element.dom(); - return Option.from(dom.parentNode).map(Element.fromDom); - }; - - var findIndex = function (element) { - return parent(element).bind(function (p) { - // TODO: Refactor out children so we can avoid the constant unwrapping - var kin = children(p); - return Arr.findIndex(kin, function (elem) { - return Compare.eq(element, elem); - }); - }); - }; - - var parents = function (element, isRoot) { - var stop = Type.isFunction(isRoot) ? isRoot : Fun.constant(false); - - // This is used a *lot* so it needs to be performant, not recursive - var dom = element.dom(); - var ret = []; - - while (dom.parentNode !== null && dom.parentNode !== undefined) { - var rawParent = dom.parentNode; - var parent = Element.fromDom(rawParent); - ret.push(parent); - - if (stop(parent) === true) break; - else dom = rawParent; - } - return ret; - }; - - var siblings = function (element) { - // TODO: Refactor out children so we can just not add self instead of filtering afterwards - var filterSelf = function (elements) { - return Arr.filter(elements, function (x) { - return !Compare.eq(element, x); - }); - }; - - return parent(element).map(children).map(filterSelf).getOr([]); - }; - - var offsetParent = function (element) { - var dom = element.dom(); - return Option.from(dom.offsetParent).map(Element.fromDom); - }; - - var prevSibling = function (element) { - var dom = element.dom(); - return Option.from(dom.previousSibling).map(Element.fromDom); - }; - - var nextSibling = function (element) { - var dom = element.dom(); - return Option.from(dom.nextSibling).map(Element.fromDom); - }; - - var prevSiblings = function (element) { - // This one needs to be reversed, so they're still in DOM order - return Arr.reverse(Recurse.toArray(element, prevSibling)); - }; - - var nextSiblings = function (element) { - return Recurse.toArray(element, nextSibling); - }; - - var children = function (element) { - var dom = element.dom(); - return Arr.map(dom.childNodes, Element.fromDom); - }; - - var child = function (element, index) { - var children = element.dom().childNodes; - return Option.from(children[index]).map(Element.fromDom); - }; - - var firstChild = function (element) { - return child(element, 0); - }; - - var lastChild = function (element) { - return child(element, element.dom().childNodes.length - 1); - }; - - var spot = Struct.immutable('element', 'offset'); - var leaf = function (element, offset) { - var cs = children(element); - return cs.length > 0 && offset < cs.length ? spot(cs[offset], 0) : spot(element, offset); - }; - - return { - owner: owner, - defaultView: defaultView, - documentElement: documentElement, - parent: parent, - findIndex: findIndex, - parents: parents, - siblings: siblings, - prevSibling: prevSibling, - offsetParent: offsetParent, - prevSiblings: prevSiblings, - nextSibling: nextSibling, - nextSiblings: nextSiblings, - children: children, - child: child, - firstChild: firstChild, - lastChild: lastChild, - leaf: leaf - }; - } -); - /** * CaretUtils.js * @@ -25822,21 +26465,42 @@ define( [ 'ephox.katamari.api.Fun', 'ephox.katamari.api.Option', + 'tinymce.core.caret.CaretCandidate', 'tinymce.core.caret.CaretPosition', - 'tinymce.core.caret.CaretWalker' + 'tinymce.core.caret.CaretWalker', + 'tinymce.core.dom.NodeType' ], - function (Fun, Option, CaretPosition, CaretWalker) { + function (Fun, Option, CaretCandidate, CaretPosition, CaretWalker, NodeType) { var fromPosition = function (forward, rootElement, position) { var walker = new CaretWalker(rootElement); return Option.from(forward ? walker.next(position) : walker.prev(position)); }; - var positionIn = function (forward, element) { - var caretWalker = new CaretWalker(element); - var startPos = forward ? CaretPosition.before(element) : CaretPosition.after(element); + var walkToPositionIn = function (forward, rootNode, startNode) { + var caretWalker = new CaretWalker(rootNode); + var startPos = forward ? CaretPosition.before(startNode) : CaretPosition.after(startNode); return Option.from(forward ? caretWalker.next(startPos) : caretWalker.prev(startPos)); }; + var afterElement = function (node) { + return NodeType.isBr(node) ? CaretPosition.before(node) : CaretPosition.after(node); + }; + + var positionIn = function (forward, element) { + var startNode = forward ? element.firstChild : element.lastChild; + if (NodeType.isText(startNode)) { + return Option.some(new CaretPosition(startNode, forward ? 0 : startNode.data.length)); + } else if (startNode) { + if (CaretCandidate.isCaretCandidate(startNode)) { + return Option.some(forward ? CaretPosition.before(startNode) : afterElement(startNode)); + } else { + return walkToPositionIn(forward, element, startNode); + } + } else { + return Option.none(); + } + }; + return { fromPosition: fromPosition, positionIn: positionIn @@ -26185,157 +26849,6 @@ define( } ); -define( - 'ephox.sugar.api.dom.Insert', - - [ - 'ephox.sugar.api.search.Traverse' - ], - - function (Traverse) { - var before = function (marker, element) { - var parent = Traverse.parent(marker); - parent.each(function (v) { - v.dom().insertBefore(element.dom(), marker.dom()); - }); - }; - - var after = function (marker, element) { - var sibling = Traverse.nextSibling(marker); - sibling.fold(function () { - var parent = Traverse.parent(marker); - parent.each(function (v) { - append(v, element); - }); - }, function (v) { - before(v, element); - }); - }; - - var prepend = function (parent, element) { - var firstChild = Traverse.firstChild(parent); - firstChild.fold(function () { - append(parent, element); - }, function (v) { - parent.dom().insertBefore(element.dom(), v.dom()); - }); - }; - - var append = function (parent, element) { - parent.dom().appendChild(element.dom()); - }; - - var appendAt = function (parent, element, index) { - Traverse.child(parent, index).fold(function () { - append(parent, element); - }, function (v) { - before(v, element); - }); - }; - - var wrap = function (element, wrapper) { - before(element, wrapper); - append(wrapper, element); - }; - - return { - before: before, - after: after, - prepend: prepend, - append: append, - appendAt: appendAt, - wrap: wrap - }; - } -); - -define( - 'ephox.sugar.api.dom.InsertAll', - - [ - 'ephox.katamari.api.Arr', - 'ephox.sugar.api.dom.Insert' - ], - - function (Arr, Insert) { - var before = function (marker, elements) { - Arr.each(elements, function (x) { - Insert.before(marker, x); - }); - }; - - var after = function (marker, elements) { - Arr.each(elements, function (x, i) { - var e = i === 0 ? marker : elements[i - 1]; - Insert.after(e, x); - }); - }; - - var prepend = function (parent, elements) { - Arr.each(elements.slice().reverse(), function (x) { - Insert.prepend(parent, x); - }); - }; - - var append = function (parent, elements) { - Arr.each(elements, function (x) { - Insert.append(parent, x); - }); - }; - - return { - before: before, - after: after, - prepend: prepend, - append: append - }; - } -); - -define( - 'ephox.sugar.api.dom.Remove', - - [ - 'ephox.katamari.api.Arr', - 'ephox.sugar.api.dom.InsertAll', - 'ephox.sugar.api.search.Traverse' - ], - - function (Arr, InsertAll, Traverse) { - var empty = function (element) { - // shortcut "empty node" trick. Requires IE 9. - element.dom().textContent = ''; - - // If the contents was a single empty text node, the above doesn't remove it. But, it's still faster in general - // than removing every child node manually. - // The following is (probably) safe for performance as 99.9% of the time the trick works and - // Traverse.children will return an empty array. - Arr.each(Traverse.children(element), function (rogue) { - remove(rogue); - }); - }; - - var remove = function (element) { - var dom = element.dom(); - if (dom.parentNode !== null) - dom.parentNode.removeChild(dom); - }; - - var unwrap = function (wrapper) { - var children = Traverse.children(wrapper); - if (children.length > 0) - InsertAll.before(wrapper, children); - remove(wrapper); - }; - - return { - empty: empty, - remove: remove, - unwrap: unwrap - }; - } -); - /** * MergeBlocks.js * @@ -26366,12 +26879,14 @@ define( if (NodeType.isBr(toPosition.getNode())) { Remove.remove(Element.fromDom(toPosition.getNode())); - toPosition = CaretFinder.positionIn(false, toBlock.dom()).getOr(); + toPosition = CaretFinder.positionIn(false, toBlock.dom()).getOr(toPosition); } - Arr.each(children, function (node) { - Insert.append(toBlock, node); - }); + if (Empty.isEmpty(fromBlock) === false) { + Arr.each(children, function (node) { + Insert.append(toBlock, node); + }); + } if (Empty.isEmpty(fromBlock)) { Remove.remove(fromBlock); @@ -26382,13 +26897,23 @@ define( var mergeBlocks = function (forward, block1, block2) { if (forward) { - return CaretFinder.positionIn(false, block1.dom()).bind(function (toPosition) { - return mergeBlocksAndReposition(forward, block2, block1, toPosition); - }); + if (Empty.isEmpty(block1)) { + Remove.remove(block1); + return CaretFinder.positionIn(true, block2.dom()); + } else { + return CaretFinder.positionIn(false, block1.dom()).bind(function (toPosition) { + return mergeBlocksAndReposition(forward, block2, block1, toPosition); + }); + } } else { - return CaretFinder.positionIn(false, block2.dom()).bind(function (toPosition) { - return mergeBlocksAndReposition(forward, block1, block2, toPosition); - }); + if (Empty.isEmpty(block2)) { + Remove.remove(block2); + return CaretFinder.positionIn(true, block1.dom()); + } else { + return CaretFinder.positionIn(false, block2.dom()).bind(function (toPosition) { + return mergeBlocksAndReposition(forward, block1, block2, toPosition); + }); + } } }; @@ -26847,18 +27372,20 @@ define( [ 'ephox.katamari.api.Fun', 'ephox.katamari.api.Option', + 'ephox.katamari.api.Options', 'ephox.sugar.api.dom.Insert', 'ephox.sugar.api.dom.Remove', 'ephox.sugar.api.node.Element', 'ephox.sugar.api.node.Node', 'ephox.sugar.api.search.PredicateFind', + 'ephox.sugar.api.search.Traverse', 'tinymce.core.caret.CaretCandidate', 'tinymce.core.caret.CaretPosition', 'tinymce.core.dom.Empty', 'tinymce.core.dom.NodeType', 'tinymce.core.keyboard.InlineUtils' ], - function (Fun, Option, Insert, Remove, Element, Node, PredicateFind, CaretCandidate, CaretPosition, Empty, NodeType, InlineUtils) { + function (Fun, Option, Options, Insert, Remove, Element, Node, PredicateFind, Traverse, CaretCandidate, CaretPosition, Empty, NodeType, InlineUtils) { var needsReposition = function (pos, elm) { var container = pos.container(); var offset = pos.offset(); @@ -26968,15 +27495,39 @@ define( } }; + // When deleting an element between two text nodes IE 11 doesn't automatically merge the adjacent text nodes + var deleteNormalized = function (elm, afterDeletePosOpt) { + return Options.liftN([Traverse.prevSibling(elm), Traverse.nextSibling(elm), afterDeletePosOpt], function (prev, next, afterDeletePos) { + var offset, prevNode = prev.dom(), nextNode = next.dom(); + + if (NodeType.isText(prevNode) && NodeType.isText(nextNode)) { + offset = prevNode.data.length; + prevNode.appendData(nextNode.data); + Remove.remove(next); + Remove.remove(elm); + if (afterDeletePos.container() === nextNode) { + return new CaretPosition(prevNode, offset); + } else { + return afterDeletePos; + } + } else { + Remove.remove(elm); + return afterDeletePos; + } + }).orThunk(function () { + Remove.remove(elm); + return afterDeletePosOpt; + }); + }; + var deleteElement = function (editor, forward, elm) { var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom()); var parentBlock = PredicateFind.ancestor(elm, Fun.curry(isBlock, editor), eqRawNode(editor.getBody())); - - Remove.remove(elm); + var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos); parentBlock.bind(paddEmptyBlock).fold( function () { - setSelection(editor, forward, afterDeletePos); + setSelection(editor, forward, normalizedAfterDeletePos); }, function (paddPos) { setSelection(editor, forward, Option.some(paddPos)); @@ -28678,6 +29229,10 @@ define( function execCommand(command, ui, value, args) { var func, customCommand, state = 0; + if (editor.removed) { + return; + } + if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) { editor.focus(); } @@ -28738,8 +29293,7 @@ define( function queryCommandState(command) { var func; - // Is hidden then return undefined - if (editor.quirks.isHidden()) { + if (editor.quirks.isHidden() || editor.removed) { return; } @@ -28768,8 +29322,7 @@ define( function queryCommandValue(command) { var func; - // Is hidden then return undefined - if (editor.quirks.isHidden()) { + if (editor.quirks.isHidden() || editor.removed) { return; } @@ -37125,7 +37678,7 @@ define( * @param {String} eventName Name of the event for example "click". */ function bindEventDelegate(editor, eventName) { - var eventRootElm = getEventTarget(editor, eventName), delegate; + var eventRootElm, delegate; function isListening(editor) { return !editor.hidden && !editor.readonly; @@ -37135,10 +37688,12 @@ define( editor.delegates = {}; } - if (editor.delegates[eventName]) { + if (editor.delegates[eventName] || editor.removed) { return; } + eventRootElm = getEventTarget(editor, eventName); + if (editor.settings.event_root) { if (!customEventRootDelegates) { customEventRootDelegates = {}; @@ -38009,55 +38564,21 @@ define( return (prefix || 'blobid') + (count++); }; - return function (uploadStatus, blobCache) { - var cachedPromises = {}; + var imageToBlobInfo = function (blobCache, img, resolve, reject) { + var base64, blobInfo; - function findAll(elm, predicate) { - var images, promises; + if (img.src.indexOf('blob:') === 0) { + blobInfo = blobCache.getByUri(img.src); - function imageToBlobInfo(img, resolve, reject) { - var base64, blobInfo; - - if (img.src.indexOf('blob:') === 0) { - blobInfo = blobCache.getByUri(img.src); - - if (blobInfo) { - resolve({ - image: img, - blobInfo: blobInfo - }); - } else { - Conversions.uriToBlob(img.src).then(function (blob) { - Conversions.blobToDataUri(blob).then(function (dataUri) { - base64 = Conversions.parseDataUri(dataUri).data; - blobInfo = blobCache.create(uniqueId(), blob, base64); - blobCache.add(blobInfo); - - resolve({ - image: img, - blobInfo: blobInfo - }); - }); - }, function (err) { - reject(err); - }); - } - - return; - } - - base64 = Conversions.parseDataUri(img.src).data; - blobInfo = blobCache.findFirst(function (cachedBlobInfo) { - return cachedBlobInfo.base64() === base64; + if (blobInfo) { + resolve({ + image: img, + blobInfo: blobInfo }); - - if (blobInfo) { - resolve({ - image: img, - blobInfo: blobInfo - }); - } else { - Conversions.uriToBlob(img.src).then(function (blob) { + } else { + Conversions.uriToBlob(img.src).then(function (blob) { + Conversions.blobToDataUri(blob).then(function (dataUri) { + base64 = Conversions.parseDataUri(dataUri).data; blobInfo = blobCache.create(uniqueId(), blob, base64); blobCache.add(blobInfo); @@ -38065,17 +38586,55 @@ define( image: img, blobInfo: blobInfo }); - }, function (err) { - reject(err); }); - } + }, function (err) { + reject(err); + }); } + return; + } + + base64 = Conversions.parseDataUri(img.src).data; + blobInfo = blobCache.findFirst(function (cachedBlobInfo) { + return cachedBlobInfo.base64() === base64; + }); + + if (blobInfo) { + resolve({ + image: img, + blobInfo: blobInfo + }); + } else { + Conversions.uriToBlob(img.src).then(function (blob) { + blobInfo = blobCache.create(uniqueId(), blob, base64); + blobCache.add(blobInfo); + + resolve({ + image: img, + blobInfo: blobInfo + }); + }, function (err) { + reject(err); + }); + } + }; + + var getAllImages = function (elm) { + return elm ? elm.getElementsByTagName('img') : []; + }; + + return function (uploadStatus, blobCache) { + var cachedPromises = {}; + + function findAll(elm, predicate) { + var images, promises; + if (!predicate) { predicate = Fun.constant(true); } - images = Arr.filter(elm.getElementsByTagName('img'), function (img) { + images = Arr.filter(getAllImages(elm), function (img) { var src = img.src; if (!Env.fileApi) { @@ -38125,7 +38684,7 @@ define( } newPromise = new Promise(function (resolve, reject) { - imageToBlobInfo(img, resolve, reject); + imageToBlobInfo(blobCache, img, resolve, reject); }).then(function (result) { delete cachedPromises[result.image.src]; return result; @@ -38792,6 +39351,752 @@ define( }; } ); +/** + * Dimensions.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module measures nodes and returns client rects. The client rects has an + * extra node property. + * + * @private + * @class tinymce.dom.Dimensions + */ +define( + 'tinymce.core.dom.Dimensions', + [ + "tinymce.core.util.Arr", + "tinymce.core.dom.NodeType", + "tinymce.core.geom.ClientRect" + ], + function (Arr, NodeType, ClientRect) { + + function getClientRects(node) { + function toArrayWithNode(clientRects) { + return Arr.map(clientRects, function (clientRect) { + clientRect = ClientRect.clone(clientRect); + clientRect.node = node; + + return clientRect; + }); + } + + if (Arr.isArray(node)) { + return Arr.reduce(node, function (result, node) { + return result.concat(getClientRects(node)); + }, []); + } + + if (NodeType.isElement(node)) { + return toArrayWithNode(node.getClientRects()); + } + + if (NodeType.isText(node)) { + var rng = node.ownerDocument.createRange(); + + rng.setStart(node, 0); + rng.setEnd(node, node.data.length); + + return toArrayWithNode(rng.getClientRects()); + } + } + + return { + /** + * Returns the client rects for a specific node. + * + * @method getClientRects + * @param {Array/DOMNode} node Node or array of nodes to get client rects on. + * @param {Array} Array of client rects with a extra node property. + */ + getClientRects: getClientRects + }; + } +); +/** + * LineUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility functions for working with lines. + * + * @private + * @class tinymce.caret.LineUtils + */ +define( + 'tinymce.core.caret.LineUtils', + [ + "tinymce.core.util.Fun", + "tinymce.core.util.Arr", + "tinymce.core.dom.NodeType", + "tinymce.core.dom.Dimensions", + "tinymce.core.geom.ClientRect", + "tinymce.core.caret.CaretUtils", + "tinymce.core.caret.CaretCandidate" + ], + function (Fun, Arr, NodeType, Dimensions, ClientRect, CaretUtils, CaretCandidate) { + var isContentEditableFalse = NodeType.isContentEditableFalse, + findNode = CaretUtils.findNode, + curry = Fun.curry; + + function distanceToRectLeft(clientRect, clientX) { + return Math.abs(clientRect.left - clientX); + } + + function distanceToRectRight(clientRect, clientX) { + return Math.abs(clientRect.right - clientX); + } + + function findClosestClientRect(clientRects, clientX) { + function isInside(clientX, clientRect) { + return clientX >= clientRect.left && clientX <= clientRect.right; + } + + return Arr.reduce(clientRects, function (oldClientRect, clientRect) { + var oldDistance, newDistance; + + oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX)); + newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX)); + + if (isInside(clientX, clientRect)) { + return clientRect; + } + + if (isInside(clientX, oldClientRect)) { + return oldClientRect; + } + + // cE=false has higher priority + if (newDistance == oldDistance && isContentEditableFalse(clientRect.node)) { + return clientRect; + } + + if (newDistance < oldDistance) { + return clientRect; + } + + return oldClientRect; + }); + } + + function walkUntil(direction, rootNode, predicateFn, node) { + while ((node = findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { + if (predicateFn(node)) { + return; + } + } + } + + function findLineNodeRects(rootNode, targetNodeRect) { + var clientRects = []; + + function collect(checkPosFn, node) { + var lineRects; + + lineRects = Arr.filter(Dimensions.getClientRects(node), function (clientRect) { + return !checkPosFn(clientRect, targetNodeRect); + }); + + clientRects = clientRects.concat(lineRects); + + return lineRects.length === 0; + } + + clientRects.push(targetNodeRect); + walkUntil(-1, rootNode, curry(collect, ClientRect.isAbove), targetNodeRect.node); + walkUntil(1, rootNode, curry(collect, ClientRect.isBelow), targetNodeRect.node); + + return clientRects; + } + + function getContentEditableFalseChildren(rootNode) { + return Arr.filter(Arr.toArray(rootNode.getElementsByTagName('*')), isContentEditableFalse); + } + + function caretInfo(clientRect, clientX) { + return { + node: clientRect.node, + before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX) + }; + } + + function closestCaret(rootNode, clientX, clientY) { + var contentEditableFalseNodeRects, closestNodeRect; + + contentEditableFalseNodeRects = Dimensions.getClientRects(getContentEditableFalseChildren(rootNode)); + contentEditableFalseNodeRects = Arr.filter(contentEditableFalseNodeRects, function (clientRect) { + return clientY >= clientRect.top && clientY <= clientRect.bottom; + }); + + closestNodeRect = findClosestClientRect(contentEditableFalseNodeRects, clientX); + if (closestNodeRect) { + closestNodeRect = findClosestClientRect(findLineNodeRects(rootNode, closestNodeRect), clientX); + if (closestNodeRect && isContentEditableFalse(closestNodeRect.node)) { + return caretInfo(closestNodeRect, clientX); + } + } + + return null; + } + + return { + findClosestClientRect: findClosestClientRect, + findLineNodeRects: findLineNodeRects, + closestCaret: closestCaret + }; + } +); +/** + * LineWalker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module lets you walk the document line by line + * returing nodes and client rects for each line. + * + * @private + * @class tinymce.caret.LineWalker + */ +define( + 'tinymce.core.caret.LineWalker', + [ + "tinymce.core.util.Fun", + "tinymce.core.util.Arr", + "tinymce.core.dom.Dimensions", + "tinymce.core.caret.CaretCandidate", + "tinymce.core.caret.CaretUtils", + "tinymce.core.caret.CaretWalker", + "tinymce.core.caret.CaretPosition", + "tinymce.core.geom.ClientRect" + ], + function (Fun, Arr, Dimensions, CaretCandidate, CaretUtils, CaretWalker, CaretPosition, ClientRect) { + var curry = Fun.curry; + + function findUntil(direction, rootNode, predicateFn, node) { + while ((node = CaretUtils.findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { + if (predicateFn(node)) { + return; + } + } + } + + function walkUntil(direction, isAboveFn, isBeflowFn, rootNode, predicateFn, caretPosition) { + var line = 0, node, result = [], targetClientRect; + + function add(node) { + var i, clientRect, clientRects; + + clientRects = Dimensions.getClientRects(node); + if (direction == -1) { + clientRects = clientRects.reverse(); + } + + for (i = 0; i < clientRects.length; i++) { + clientRect = clientRects[i]; + if (isBeflowFn(clientRect, targetClientRect)) { + continue; + } + + if (result.length > 0 && isAboveFn(clientRect, Arr.last(result))) { + line++; + } + + clientRect.line = line; + + if (predicateFn(clientRect)) { + return true; + } + + result.push(clientRect); + } + } + + targetClientRect = Arr.last(caretPosition.getClientRects()); + if (!targetClientRect) { + return result; + } + + node = caretPosition.getNode(); + add(node); + findUntil(direction, rootNode, add, node); + + return result; + } + + function aboveLineNumber(lineNumber, clientRect) { + return clientRect.line > lineNumber; + } + + function isLine(lineNumber, clientRect) { + return clientRect.line === lineNumber; + } + + var upUntil = curry(walkUntil, -1, ClientRect.isAbove, ClientRect.isBelow); + var downUntil = curry(walkUntil, 1, ClientRect.isBelow, ClientRect.isAbove); + + function positionsUntil(direction, rootNode, predicateFn, node) { + var caretWalker = new CaretWalker(rootNode), walkFn, isBelowFn, isAboveFn, + caretPosition, result = [], line = 0, clientRect, targetClientRect; + + function getClientRect(caretPosition) { + if (direction == 1) { + return Arr.last(caretPosition.getClientRects()); + } + + return Arr.last(caretPosition.getClientRects()); + } + + if (direction == 1) { + walkFn = caretWalker.next; + isBelowFn = ClientRect.isBelow; + isAboveFn = ClientRect.isAbove; + caretPosition = CaretPosition.after(node); + } else { + walkFn = caretWalker.prev; + isBelowFn = ClientRect.isAbove; + isAboveFn = ClientRect.isBelow; + caretPosition = CaretPosition.before(node); + } + + targetClientRect = getClientRect(caretPosition); + + do { + if (!caretPosition.isVisible()) { + continue; + } + + clientRect = getClientRect(caretPosition); + + if (isAboveFn(clientRect, targetClientRect)) { + continue; + } + + if (result.length > 0 && isBelowFn(clientRect, Arr.last(result))) { + line++; + } + + clientRect = ClientRect.clone(clientRect); + clientRect.position = caretPosition; + clientRect.line = line; + + if (predicateFn(clientRect)) { + return result; + } + + result.push(clientRect); + } while ((caretPosition = walkFn(caretPosition))); + + return result; + } + + return { + upUntil: upUntil, + downUntil: downUntil, + + /** + * Find client rects with line and caret position until the predicate returns true. + * + * @method positionsUntil + * @param {Number} direction Direction forward/backward 1/-1. + * @param {DOMNode} rootNode Root node to walk within. + * @param {function} predicateFn Gets the client rect as it's input. + * @param {DOMNode} node Node to start walking from. + * @return {Array} Array of client rects with line and position properties. + */ + positionsUntil: positionsUntil, + + isAboveLine: curry(aboveLineNumber), + isLine: curry(isLine) + }; + } +); +/** + * CefUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.keyboard.CefUtils', + [ + 'tinymce.core.caret.CaretPosition', + 'tinymce.core.caret.CaretUtils', + 'tinymce.core.dom.NodeType', + 'tinymce.core.util.Fun' + ], + function (CaretPosition, CaretUtils, NodeType, Fun) { + var isContentEditableTrue = NodeType.isContentEditableTrue; + var isContentEditableFalse = NodeType.isContentEditableFalse; + + var showCaret = function (direction, editor, node, before) { + // TODO: Figure out a better way to handle this dependency + return editor._selectionOverrides.showCaret(direction, node, before); + }; + + var getNodeRange = function (node) { + var rng = node.ownerDocument.createRange(); + rng.selectNode(node); + return rng; + }; + + var selectNode = function (editor, node) { + var e; + + e = editor.fire('BeforeObjectSelected', { target: node }); + if (e.isDefaultPrevented()) { + return null; + } + + return getNodeRange(node); + }; + + var renderCaretAtRange = function (editor, range) { + var caretPosition, ceRoot; + + range = CaretUtils.normalizeRange(1, editor.getBody(), range); + caretPosition = CaretPosition.fromRangeStart(range); + + if (isContentEditableFalse(caretPosition.getNode())) { + return showCaret(1, editor, caretPosition.getNode(), !caretPosition.isAtEnd()); + } + + if (isContentEditableFalse(caretPosition.getNode(true))) { + return showCaret(1, editor, caretPosition.getNode(true), false); + } + + // TODO: Should render caret before/after depending on where you click on the page forces after now + ceRoot = editor.dom.getParent(caretPosition.getNode(), Fun.or(isContentEditableFalse, isContentEditableTrue)); + if (isContentEditableFalse(ceRoot)) { + return showCaret(1, editor, ceRoot, false); + } + + return null; + }; + + var renderRangeCaret = function (editor, range) { + var caretRange; + + if (!range || !range.collapsed) { + return range; + } + + caretRange = renderCaretAtRange(editor, range); + if (caretRange) { + return caretRange; + } + + return range; + }; + + return { + showCaret: showCaret, + selectNode: selectNode, + renderCaretAtRange: renderCaretAtRange, + renderRangeCaret: renderRangeCaret + }; + } +); + +/** + * CefNavigation.js + * + * Released under LGPL License. + * Copyright (c) 1999-2017 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define( + 'tinymce.core.keyboard.CefNavigation', + [ + 'tinymce.core.caret.CaretContainer', + 'tinymce.core.caret.CaretPosition', + 'tinymce.core.caret.CaretUtils', + 'tinymce.core.caret.CaretWalker', + 'tinymce.core.caret.LineUtils', + 'tinymce.core.caret.LineWalker', + 'tinymce.core.dom.NodeType', + 'tinymce.core.dom.RangeUtils', + 'tinymce.core.Env', + 'tinymce.core.keyboard.CefUtils', + 'tinymce.core.util.Arr', + 'tinymce.core.util.Fun' + ], + function (CaretContainer, CaretPosition, CaretUtils, CaretWalker, LineUtils, LineWalker, NodeType, RangeUtils, Env, CefUtils, Arr, Fun) { + var isContentEditableFalse = NodeType.isContentEditableFalse; + var getSelectedNode = RangeUtils.getSelectedNode; + var isAfterContentEditableFalse = CaretUtils.isAfterContentEditableFalse; + var isBeforeContentEditableFalse = CaretUtils.isBeforeContentEditableFalse; + + var getVisualCaretPosition = function (walkFn, caretPosition) { + while ((caretPosition = walkFn(caretPosition))) { + if (caretPosition.isVisible()) { + return caretPosition; + } + } + + return caretPosition; + }; + + var isMoveInsideSameBlock = function (fromCaretPosition, toCaretPosition) { + var inSameBlock = CaretUtils.isInSameBlock(fromCaretPosition, toCaretPosition); + + // Handle bogus BR

abc|

+ if (!inSameBlock && NodeType.isBr(fromCaretPosition.getNode())) { + return true; + } + + return inSameBlock; + }; + + var isRangeInCaretContainerBlock = function (range) { + return CaretContainer.isCaretContainerBlock(range.startContainer); + }; + + var getNormalizedRangeEndPoint = function (direction, rootNode, range) { + range = CaretUtils.normalizeRange(direction, rootNode, range); + + if (direction === -1) { + return CaretPosition.fromRangeStart(range); + } + + return CaretPosition.fromRangeEnd(range); + }; + + var moveToCeFalseHorizontally = function (direction, editor, getNextPosFn, isBeforeContentEditableFalseFn, range) { + var node, caretPosition, peekCaretPosition, rangeIsInContainerBlock; + + if (!range.collapsed) { + node = getSelectedNode(range); + if (isContentEditableFalse(node)) { + return CefUtils.showCaret(direction, editor, node, direction === -1); + } + } + + rangeIsInContainerBlock = isRangeInCaretContainerBlock(range); + caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range); + + if (isBeforeContentEditableFalseFn(caretPosition)) { + return CefUtils.selectNode(editor, caretPosition.getNode(direction === -1)); + } + + caretPosition = getNextPosFn(caretPosition); + if (!caretPosition) { + if (rangeIsInContainerBlock) { + return range; + } + + return null; + } + + if (isBeforeContentEditableFalseFn(caretPosition)) { + return CefUtils.showCaret(direction, editor, caretPosition.getNode(direction === -1), direction === 1); + } + + // Peek ahead for handling of ab|c -> abc| + peekCaretPosition = getNextPosFn(caretPosition); + if (isBeforeContentEditableFalseFn(peekCaretPosition)) { + if (isMoveInsideSameBlock(caretPosition, peekCaretPosition)) { + return CefUtils.showCaret(direction, editor, peekCaretPosition.getNode(direction === -1), direction === 1); + } + } + + if (rangeIsInContainerBlock) { + return CefUtils.renderRangeCaret(editor, caretPosition.toRange()); + } + + return null; + }; + + var moveToCeFalseVertically = function (direction, editor, walkerFn, range) { + var caretPosition, linePositions, nextLinePositions, + closestNextLineRect, caretClientRect, clientX, + dist1, dist2, contentEditableFalseNode; + + contentEditableFalseNode = getSelectedNode(range); + caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range); + linePositions = walkerFn(editor.getBody(), LineWalker.isAboveLine(1), caretPosition); + nextLinePositions = Arr.filter(linePositions, LineWalker.isLine(1)); + caretClientRect = Arr.last(caretPosition.getClientRects()); + + if (isBeforeContentEditableFalse(caretPosition)) { + contentEditableFalseNode = caretPosition.getNode(); + } + + if (isAfterContentEditableFalse(caretPosition)) { + contentEditableFalseNode = caretPosition.getNode(true); + } + + if (!caretClientRect) { + return null; + } + + clientX = caretClientRect.left; + + closestNextLineRect = LineUtils.findClosestClientRect(nextLinePositions, clientX); + if (closestNextLineRect) { + if (isContentEditableFalse(closestNextLineRect.node)) { + dist1 = Math.abs(clientX - closestNextLineRect.left); + dist2 = Math.abs(clientX - closestNextLineRect.right); + + return CefUtils.showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2); + } + } + + if (contentEditableFalseNode) { + var caretPositions = LineWalker.positionsUntil(direction, editor.getBody(), LineWalker.isAboveLine(1), contentEditableFalseNode); + + closestNextLineRect = LineUtils.findClosestClientRect(Arr.filter(caretPositions, LineWalker.isLine(1)), clientX); + if (closestNextLineRect) { + return CefUtils.renderRangeCaret(editor, closestNextLineRect.position.toRange()); + } + + closestNextLineRect = Arr.last(Arr.filter(caretPositions, LineWalker.isLine(0))); + if (closestNextLineRect) { + return CefUtils.renderRangeCaret(editor, closestNextLineRect.position.toRange()); + } + } + }; + + var createTextBlock = function (editor) { + var textBlock = editor.dom.create(editor.settings.forced_root_block); + + if (!Env.ie || Env.ie >= 11) { + textBlock.innerHTML = '
'; + } + + return textBlock; + }; + + var exitPreBlock = function (editor, direction, range) { + var pre, caretPos, newBlock; + var caretWalker = new CaretWalker(editor.getBody()); + var getNextVisualCaretPosition = Fun.curry(getVisualCaretPosition, caretWalker.next); + var getPrevVisualCaretPosition = Fun.curry(getVisualCaretPosition, caretWalker.prev); + + if (range.collapsed && editor.settings.forced_root_block) { + pre = editor.dom.getParent(range.startContainer, 'PRE'); + if (!pre) { + return; + } + + if (direction === 1) { + caretPos = getNextVisualCaretPosition(CaretPosition.fromRangeStart(range)); + } else { + caretPos = getPrevVisualCaretPosition(CaretPosition.fromRangeStart(range)); + } + + if (!caretPos) { + newBlock = createTextBlock(editor); + + if (direction === 1) { + editor.$(pre).after(newBlock); + } else { + editor.$(pre).before(newBlock); + } + + editor.selection.select(newBlock, true); + editor.selection.collapse(); + } + } + }; + + var getHorizontalRange = function (editor, forward) { + var caretWalker = new CaretWalker(editor.getBody()); + var getNextVisualCaretPosition = Fun.curry(getVisualCaretPosition, caretWalker.next); + var getPrevVisualCaretPosition = Fun.curry(getVisualCaretPosition, caretWalker.prev); + var newRange, direction = forward ? 1 : -1; + var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition; + var isBeforeContentEditableFalseFn = forward ? isBeforeContentEditableFalse : isAfterContentEditableFalse; + var range = editor.selection.getRng(); + + newRange = moveToCeFalseHorizontally(direction, editor, getNextPosFn, isBeforeContentEditableFalseFn, range); + if (newRange) { + return newRange; + } + + newRange = exitPreBlock(editor, direction, range); + if (newRange) { + return newRange; + } + + return null; + }; + + var getVerticalRange = function (editor, down) { + var newRange, direction = down ? 1 : -1; + var walkerFn = down ? LineWalker.downUntil : LineWalker.upUntil; + var range = editor.selection.getRng(); + + newRange = moveToCeFalseVertically(direction, editor, walkerFn, range); + if (newRange) { + return newRange; + } + + newRange = exitPreBlock(editor, direction, range); + if (newRange) { + return newRange; + } + + return null; + }; + + var moveH = function (editor, forward) { + return function () { + var newRng = getHorizontalRange(editor, forward); + + if (newRng) { + editor.selection.setRng(newRng); + return true; + } else { + return false; + } + }; + }; + + var moveV = function (editor, down) { + return function () { + var newRng = getVerticalRange(editor, down); + + if (newRng) { + editor.selection.setRng(newRng); + return true; + } else { + return false; + } + }; + }; + + return { + moveH: moveH, + moveV: moveV + }; + } +); + define( 'ephox.katamari.api.Merger', @@ -38916,13 +40221,18 @@ define( 'ephox.katamari.api.Arr', 'ephox.katamari.api.Cell', 'tinymce.core.keyboard.BoundarySelection', + 'tinymce.core.keyboard.CefNavigation', 'tinymce.core.keyboard.MatchKeys', 'tinymce.core.util.VK' ], - function (Arr, Cell, BoundarySelection, MatchKeys, VK) { + function (Arr, Cell, BoundarySelection, CefNavigation, MatchKeys, VK) { var setup = function (editor, caret) { editor.on('keydown', function (evt) { var matches = MatchKeys.match([ + { keyCode: VK.RIGHT, action: CefNavigation.moveH(editor, true) }, + { keyCode: VK.LEFT, action: CefNavigation.moveH(editor, false) }, + { keyCode: VK.UP, action: CefNavigation.moveV(editor, false) }, + { keyCode: VK.DOWN, action: CefNavigation.moveV(editor, true) }, { keyCode: VK.RIGHT, action: BoundarySelection.move(editor, caret, true) }, { keyCode: VK.LEFT, action: BoundarySelection.move(editor, caret, false) } ], evt); @@ -40069,6 +41379,10 @@ define( function (CaretContainer, CaretContainerRemove, CaretPosition, DomQuery, NodeType, RangeUtils, ClientRect, Delay) { var isContentEditableFalse = NodeType.isContentEditableFalse; + var isTableCell = function (node) { + return node && /^(TD|TH)$/i.test(node.nodeName); + }; + return function (rootNode, isBlock) { var cursorInterval, $lastVisualCaret, caretContainerNode; @@ -40144,6 +41458,10 @@ define( hide(); + if (isTableCell(node)) { + return null; + } + if (isBlock(node)) { caretContainerNode = CaretContainer.insertBlock('p', node, before); clientRect = getAbsoluteClientRect(node, before); @@ -40234,383 +41552,6 @@ define( }; } ); -/** - * Dimensions.js - * - * Released under LGPL License. - * Copyright (c) 1999-2017 Ephox Corp. All rights reserved - * - * License: http://www.tinymce.com/license - * Contributing: http://www.tinymce.com/contributing - */ - -/** - * This module measures nodes and returns client rects. The client rects has an - * extra node property. - * - * @private - * @class tinymce.dom.Dimensions - */ -define( - 'tinymce.core.dom.Dimensions', - [ - "tinymce.core.util.Arr", - "tinymce.core.dom.NodeType", - "tinymce.core.geom.ClientRect" - ], - function (Arr, NodeType, ClientRect) { - - function getClientRects(node) { - function toArrayWithNode(clientRects) { - return Arr.map(clientRects, function (clientRect) { - clientRect = ClientRect.clone(clientRect); - clientRect.node = node; - - return clientRect; - }); - } - - if (Arr.isArray(node)) { - return Arr.reduce(node, function (result, node) { - return result.concat(getClientRects(node)); - }, []); - } - - if (NodeType.isElement(node)) { - return toArrayWithNode(node.getClientRects()); - } - - if (NodeType.isText(node)) { - var rng = node.ownerDocument.createRange(); - - rng.setStart(node, 0); - rng.setEnd(node, node.data.length); - - return toArrayWithNode(rng.getClientRects()); - } - } - - return { - /** - * Returns the client rects for a specific node. - * - * @method getClientRects - * @param {Array/DOMNode} node Node or array of nodes to get client rects on. - * @param {Array} Array of client rects with a extra node property. - */ - getClientRects: getClientRects - }; - } -); -/** - * LineWalker.js - * - * Released under LGPL License. - * Copyright (c) 1999-2017 Ephox Corp. All rights reserved - * - * License: http://www.tinymce.com/license - * Contributing: http://www.tinymce.com/contributing - */ - -/** - * This module lets you walk the document line by line - * returing nodes and client rects for each line. - * - * @private - * @class tinymce.caret.LineWalker - */ -define( - 'tinymce.core.caret.LineWalker', - [ - "tinymce.core.util.Fun", - "tinymce.core.util.Arr", - "tinymce.core.dom.Dimensions", - "tinymce.core.caret.CaretCandidate", - "tinymce.core.caret.CaretUtils", - "tinymce.core.caret.CaretWalker", - "tinymce.core.caret.CaretPosition", - "tinymce.core.geom.ClientRect" - ], - function (Fun, Arr, Dimensions, CaretCandidate, CaretUtils, CaretWalker, CaretPosition, ClientRect) { - var curry = Fun.curry; - - function findUntil(direction, rootNode, predicateFn, node) { - while ((node = CaretUtils.findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { - if (predicateFn(node)) { - return; - } - } - } - - function walkUntil(direction, isAboveFn, isBeflowFn, rootNode, predicateFn, caretPosition) { - var line = 0, node, result = [], targetClientRect; - - function add(node) { - var i, clientRect, clientRects; - - clientRects = Dimensions.getClientRects(node); - if (direction == -1) { - clientRects = clientRects.reverse(); - } - - for (i = 0; i < clientRects.length; i++) { - clientRect = clientRects[i]; - if (isBeflowFn(clientRect, targetClientRect)) { - continue; - } - - if (result.length > 0 && isAboveFn(clientRect, Arr.last(result))) { - line++; - } - - clientRect.line = line; - - if (predicateFn(clientRect)) { - return true; - } - - result.push(clientRect); - } - } - - targetClientRect = Arr.last(caretPosition.getClientRects()); - if (!targetClientRect) { - return result; - } - - node = caretPosition.getNode(); - add(node); - findUntil(direction, rootNode, add, node); - - return result; - } - - function aboveLineNumber(lineNumber, clientRect) { - return clientRect.line > lineNumber; - } - - function isLine(lineNumber, clientRect) { - return clientRect.line === lineNumber; - } - - var upUntil = curry(walkUntil, -1, ClientRect.isAbove, ClientRect.isBelow); - var downUntil = curry(walkUntil, 1, ClientRect.isBelow, ClientRect.isAbove); - - function positionsUntil(direction, rootNode, predicateFn, node) { - var caretWalker = new CaretWalker(rootNode), walkFn, isBelowFn, isAboveFn, - caretPosition, result = [], line = 0, clientRect, targetClientRect; - - function getClientRect(caretPosition) { - if (direction == 1) { - return Arr.last(caretPosition.getClientRects()); - } - - return Arr.last(caretPosition.getClientRects()); - } - - if (direction == 1) { - walkFn = caretWalker.next; - isBelowFn = ClientRect.isBelow; - isAboveFn = ClientRect.isAbove; - caretPosition = CaretPosition.after(node); - } else { - walkFn = caretWalker.prev; - isBelowFn = ClientRect.isAbove; - isAboveFn = ClientRect.isBelow; - caretPosition = CaretPosition.before(node); - } - - targetClientRect = getClientRect(caretPosition); - - do { - if (!caretPosition.isVisible()) { - continue; - } - - clientRect = getClientRect(caretPosition); - - if (isAboveFn(clientRect, targetClientRect)) { - continue; - } - - if (result.length > 0 && isBelowFn(clientRect, Arr.last(result))) { - line++; - } - - clientRect = ClientRect.clone(clientRect); - clientRect.position = caretPosition; - clientRect.line = line; - - if (predicateFn(clientRect)) { - return result; - } - - result.push(clientRect); - } while ((caretPosition = walkFn(caretPosition))); - - return result; - } - - return { - upUntil: upUntil, - downUntil: downUntil, - - /** - * Find client rects with line and caret position until the predicate returns true. - * - * @method positionsUntil - * @param {Number} direction Direction forward/backward 1/-1. - * @param {DOMNode} rootNode Root node to walk within. - * @param {function} predicateFn Gets the client rect as it's input. - * @param {DOMNode} node Node to start walking from. - * @return {Array} Array of client rects with line and position properties. - */ - positionsUntil: positionsUntil, - - isAboveLine: curry(aboveLineNumber), - isLine: curry(isLine) - }; - } -); -/** - * LineUtils.js - * - * Released under LGPL License. - * Copyright (c) 1999-2017 Ephox Corp. All rights reserved - * - * License: http://www.tinymce.com/license - * Contributing: http://www.tinymce.com/contributing - */ - -/** - * Utility functions for working with lines. - * - * @private - * @class tinymce.caret.LineUtils - */ -define( - 'tinymce.core.caret.LineUtils', - [ - "tinymce.core.util.Fun", - "tinymce.core.util.Arr", - "tinymce.core.dom.NodeType", - "tinymce.core.dom.Dimensions", - "tinymce.core.geom.ClientRect", - "tinymce.core.caret.CaretUtils", - "tinymce.core.caret.CaretCandidate" - ], - function (Fun, Arr, NodeType, Dimensions, ClientRect, CaretUtils, CaretCandidate) { - var isContentEditableFalse = NodeType.isContentEditableFalse, - findNode = CaretUtils.findNode, - curry = Fun.curry; - - function distanceToRectLeft(clientRect, clientX) { - return Math.abs(clientRect.left - clientX); - } - - function distanceToRectRight(clientRect, clientX) { - return Math.abs(clientRect.right - clientX); - } - - function findClosestClientRect(clientRects, clientX) { - function isInside(clientX, clientRect) { - return clientX >= clientRect.left && clientX <= clientRect.right; - } - - return Arr.reduce(clientRects, function (oldClientRect, clientRect) { - var oldDistance, newDistance; - - oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX)); - newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX)); - - if (isInside(clientX, clientRect)) { - return clientRect; - } - - if (isInside(clientX, oldClientRect)) { - return oldClientRect; - } - - // cE=false has higher priority - if (newDistance == oldDistance && isContentEditableFalse(clientRect.node)) { - return clientRect; - } - - if (newDistance < oldDistance) { - return clientRect; - } - - return oldClientRect; - }); - } - - function walkUntil(direction, rootNode, predicateFn, node) { - while ((node = findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { - if (predicateFn(node)) { - return; - } - } - } - - function findLineNodeRects(rootNode, targetNodeRect) { - var clientRects = []; - - function collect(checkPosFn, node) { - var lineRects; - - lineRects = Arr.filter(Dimensions.getClientRects(node), function (clientRect) { - return !checkPosFn(clientRect, targetNodeRect); - }); - - clientRects = clientRects.concat(lineRects); - - return lineRects.length === 0; - } - - clientRects.push(targetNodeRect); - walkUntil(-1, rootNode, curry(collect, ClientRect.isAbove), targetNodeRect.node); - walkUntil(1, rootNode, curry(collect, ClientRect.isBelow), targetNodeRect.node); - - return clientRects; - } - - function getContentEditableFalseChildren(rootNode) { - return Arr.filter(Arr.toArray(rootNode.getElementsByTagName('*')), isContentEditableFalse); - } - - function caretInfo(clientRect, clientX) { - return { - node: clientRect.node, - before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX) - }; - } - - function closestCaret(rootNode, clientX, clientY) { - var contentEditableFalseNodeRects, closestNodeRect; - - contentEditableFalseNodeRects = Dimensions.getClientRects(getContentEditableFalseChildren(rootNode)); - contentEditableFalseNodeRects = Arr.filter(contentEditableFalseNodeRects, function (clientRect) { - return clientY >= clientRect.top && clientY <= clientRect.bottom; - }); - - closestNodeRect = findClosestClientRect(contentEditableFalseNodeRects, clientX); - if (closestNodeRect) { - closestNodeRect = findClosestClientRect(findLineNodeRects(rootNode, closestNodeRect), clientX); - if (closestNodeRect && isContentEditableFalse(closestNodeRect.node)) { - return caretInfo(closestNodeRect, clientX); - } - } - - return null; - } - - return { - findClosestClientRect: findClosestClientRect, - findLineNodeRects: findLineNodeRects, - closestCaret: closestCaret - }; - } -); /** * MousePosition.js * @@ -41007,50 +41948,31 @@ define( define( 'tinymce.core.SelectionOverrides', [ - "tinymce.core.Env", - "tinymce.core.caret.CaretWalker", - "tinymce.core.caret.CaretPosition", - "tinymce.core.caret.CaretContainer", - "tinymce.core.caret.CaretContainerRemove", - "tinymce.core.caret.CaretUtils", - "tinymce.core.caret.FakeCaret", - "tinymce.core.caret.LineWalker", - "tinymce.core.caret.LineUtils", - "tinymce.core.dom.NodeType", - "tinymce.core.dom.RangeUtils", - "tinymce.core.geom.ClientRect", - "tinymce.core.util.VK", - "tinymce.core.util.Fun", - "tinymce.core.util.Arr", - "tinymce.core.util.Delay", - "tinymce.core.DragDropOverrides" + 'tinymce.core.caret.CaretContainer', + 'tinymce.core.caret.CaretPosition', + 'tinymce.core.caret.CaretUtils', + 'tinymce.core.caret.CaretWalker', + 'tinymce.core.caret.FakeCaret', + 'tinymce.core.caret.LineUtils', + 'tinymce.core.dom.NodeType', + 'tinymce.core.DragDropOverrides', + 'tinymce.core.Env', + 'tinymce.core.geom.ClientRect', + 'tinymce.core.keyboard.CefUtils', + 'tinymce.core.util.Arr', + 'tinymce.core.util.Delay', + 'tinymce.core.util.Fun', + 'tinymce.core.util.VK' ], - function ( - Env, CaretWalker, CaretPosition, CaretContainer, CaretContainerRemove, CaretUtils, FakeCaret, LineWalker, - LineUtils, NodeType, RangeUtils, ClientRect, VK, Fun, Arr, Delay, DragDropOverrides -) { - var curry = Fun.curry, - isContentEditableTrue = NodeType.isContentEditableTrue, + function (CaretContainer, CaretPosition, CaretUtils, CaretWalker, FakeCaret, LineUtils, NodeType, DragDropOverrides, Env, ClientRect, CefUtils, Arr, Delay, Fun, VK) { + var isContentEditableTrue = NodeType.isContentEditableTrue, isContentEditableFalse = NodeType.isContentEditableFalse, isAfterContentEditableFalse = CaretUtils.isAfterContentEditableFalse, - isBeforeContentEditableFalse = CaretUtils.isBeforeContentEditableFalse, - getSelectedNode = RangeUtils.getSelectedNode; - - function getVisualCaretPosition(walkFn, caretPosition) { - while ((caretPosition = walkFn(caretPosition))) { - if (caretPosition.isVisible()) { - return caretPosition; - } - } - - return caretPosition; - } + isBeforeContentEditableFalse = CaretUtils.isBeforeContentEditableFalse; function SelectionOverrides(editor) { - var rootNode = editor.getBody(), caretWalker = new CaretWalker(rootNode); - var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next); - var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev), - fakeCaret = new FakeCaret(editor.getBody(), isBlock), + var rootNode = editor.getBody(); + var fakeCaret = new FakeCaret(editor.getBody(), isBlock), realSelectionId = 'sel-' + editor.dom.uniqueId(), selectedContentEditableNode; @@ -41100,36 +42022,6 @@ define( return fakeCaret.show(before, node); } - function selectNode(node) { - var e; - - e = editor.fire('BeforeObjectSelected', { target: node }); - if (e.isDefaultPrevented()) { - return null; - } - - return getNodeRange(node); - } - - function getNodeRange(node) { - var rng = node.ownerDocument.createRange(); - - rng.selectNode(node); - - return rng; - } - - function isMoveInsideSameBlock(fromCaretPosition, toCaretPosition) { - var inSameBlock = CaretUtils.isInSameBlock(fromCaretPosition, toCaretPosition); - - // Handle bogus BR

abc|

- if (!inSameBlock && NodeType.isBr(fromCaretPosition.getNode())) { - return true; - } - - return inSameBlock; - } - function getNormalizedRangeEndPoint(direction, range) { range = CaretUtils.normalizeRange(direction, rootNode, range); @@ -41140,177 +42032,6 @@ define( return CaretPosition.fromRangeEnd(range); } - function isRangeInCaretContainerBlock(range) { - return CaretContainer.isCaretContainerBlock(range.startContainer); - } - - function moveToCeFalseHorizontally(direction, getNextPosFn, isBeforeContentEditableFalseFn, range) { - var node, caretPosition, peekCaretPosition, rangeIsInContainerBlock; - - if (!range.collapsed) { - node = getSelectedNode(range); - if (isContentEditableFalse(node)) { - return showCaret(direction, node, direction == -1); - } - } - - rangeIsInContainerBlock = isRangeInCaretContainerBlock(range); - caretPosition = getNormalizedRangeEndPoint(direction, range); - - if (isBeforeContentEditableFalseFn(caretPosition)) { - return selectNode(caretPosition.getNode(direction == -1)); - } - - caretPosition = getNextPosFn(caretPosition); - if (!caretPosition) { - if (rangeIsInContainerBlock) { - return range; - } - - return null; - } - - if (isBeforeContentEditableFalseFn(caretPosition)) { - return showCaret(direction, caretPosition.getNode(direction == -1), direction == 1); - } - - // Peek ahead for handling of ab|c -> abc| - peekCaretPosition = getNextPosFn(caretPosition); - if (isBeforeContentEditableFalseFn(peekCaretPosition)) { - if (isMoveInsideSameBlock(caretPosition, peekCaretPosition)) { - return showCaret(direction, peekCaretPosition.getNode(direction == -1), direction == 1); - } - } - - if (rangeIsInContainerBlock) { - return renderRangeCaret(caretPosition.toRange()); - } - - return null; - } - - function moveToCeFalseVertically(direction, walkerFn, range) { - var caretPosition, linePositions, nextLinePositions, - closestNextLineRect, caretClientRect, clientX, - dist1, dist2, contentEditableFalseNode; - - contentEditableFalseNode = getSelectedNode(range); - caretPosition = getNormalizedRangeEndPoint(direction, range); - linePositions = walkerFn(rootNode, LineWalker.isAboveLine(1), caretPosition); - nextLinePositions = Arr.filter(linePositions, LineWalker.isLine(1)); - caretClientRect = Arr.last(caretPosition.getClientRects()); - - if (isBeforeContentEditableFalse(caretPosition)) { - contentEditableFalseNode = caretPosition.getNode(); - } - - if (isAfterContentEditableFalse(caretPosition)) { - contentEditableFalseNode = caretPosition.getNode(true); - } - - if (!caretClientRect) { - return null; - } - - clientX = caretClientRect.left; - - closestNextLineRect = LineUtils.findClosestClientRect(nextLinePositions, clientX); - if (closestNextLineRect) { - if (isContentEditableFalse(closestNextLineRect.node)) { - dist1 = Math.abs(clientX - closestNextLineRect.left); - dist2 = Math.abs(clientX - closestNextLineRect.right); - - return showCaret(direction, closestNextLineRect.node, dist1 < dist2); - } - } - - if (contentEditableFalseNode) { - var caretPositions = LineWalker.positionsUntil(direction, rootNode, LineWalker.isAboveLine(1), contentEditableFalseNode); - - closestNextLineRect = LineUtils.findClosestClientRect(Arr.filter(caretPositions, LineWalker.isLine(1)), clientX); - if (closestNextLineRect) { - return renderRangeCaret(closestNextLineRect.position.toRange()); - } - - closestNextLineRect = Arr.last(Arr.filter(caretPositions, LineWalker.isLine(0))); - if (closestNextLineRect) { - return renderRangeCaret(closestNextLineRect.position.toRange()); - } - } - } - - function exitPreBlock(direction, range) { - var pre, caretPos, newBlock; - - function createTextBlock() { - var textBlock = editor.dom.create(editor.settings.forced_root_block); - - if (!Env.ie || Env.ie >= 11) { - textBlock.innerHTML = '
'; - } - - return textBlock; - } - - if (range.collapsed && editor.settings.forced_root_block) { - pre = editor.dom.getParent(range.startContainer, 'PRE'); - if (!pre) { - return; - } - - if (direction == 1) { - caretPos = getNextVisualCaretPosition(CaretPosition.fromRangeStart(range)); - } else { - caretPos = getPrevVisualCaretPosition(CaretPosition.fromRangeStart(range)); - } - - if (!caretPos) { - newBlock = createTextBlock(); - - if (direction == 1) { - editor.$(pre).after(newBlock); - } else { - editor.$(pre).before(newBlock); - } - - editor.selection.select(newBlock, true); - editor.selection.collapse(); - } - } - } - - function moveH(direction, getNextPosFn, isBeforeContentEditableFalseFn, range) { - var newRange; - - newRange = moveToCeFalseHorizontally(direction, getNextPosFn, isBeforeContentEditableFalseFn, range); - if (newRange) { - return newRange; - } - - newRange = exitPreBlock(direction, range); - if (newRange) { - return newRange; - } - - return null; - } - - function moveV(direction, walkerFn, range) { - var newRange; - - newRange = moveToCeFalseVertically(direction, walkerFn, range); - if (newRange) { - return newRange; - } - - newRange = exitPreBlock(direction, range); - if (newRange) { - return newRange; - } - - return null; - } - function showBlockCaretContainer(blockCaretContainer) { if (blockCaretContainer.hasAttribute('data-mce-caret')) { CaretContainer.showCaretContainerBlock(blockCaretContainer); @@ -41319,61 +42040,7 @@ define( } } - function renderCaretAtRange(range) { - var caretPosition, ceRoot; - - range = CaretUtils.normalizeRange(1, rootNode, range); - caretPosition = CaretPosition.fromRangeStart(range); - - if (isContentEditableFalse(caretPosition.getNode())) { - return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd()); - } - - if (isContentEditableFalse(caretPosition.getNode(true))) { - return showCaret(1, caretPosition.getNode(true), false); - } - - // TODO: Should render caret before/after depending on where you click on the page forces after now - ceRoot = editor.dom.getParent(caretPosition.getNode(), Fun.or(isContentEditableFalse, isContentEditableTrue)); - if (isContentEditableFalse(ceRoot)) { - return showCaret(1, ceRoot, false); - } - - return null; - } - - function renderRangeCaret(range) { - var caretRange; - - if (!range || !range.collapsed) { - return range; - } - - caretRange = renderCaretAtRange(range); - if (caretRange) { - return caretRange; - } - - return range; - } - function registerEvents() { - var right = curry(moveH, 1, getNextVisualCaretPosition, isBeforeContentEditableFalse); - var left = curry(moveH, -1, getPrevVisualCaretPosition, isAfterContentEditableFalse); - var up = curry(moveV, -1, LineWalker.upUntil); - var down = curry(moveV, 1, LineWalker.downUntil); - - function override(evt, moveFn) { - if (evt.isDefaultPrevented() === false) { - var range = moveFn(getRange()); - - if (range) { - evt.preventDefault(); - setRange(range); - } - } - } - function getContentEditableRoot(node) { var root = editor.getBody(); @@ -41404,7 +42071,7 @@ define( var range = getRange(); if (range.collapsed) { - setRange(renderCaretAtRange(range)); + setRange(CefUtils.renderCaretAtRange(editor, range)); } }); @@ -41450,7 +42117,7 @@ define( if (isContentEditableFalse(contentEditableRoot)) { if (!moved) { e.preventDefault(); - setContentEditableSelection(selectNode(contentEditableRoot)); + setContentEditableSelection(CefUtils.selectNode(editor, contentEditableRoot)); } } }); @@ -41502,8 +42169,10 @@ define( if (contentEditableRoot) { if (isContentEditableFalse(contentEditableRoot)) { e.preventDefault(); - setContentEditableSelection(selectNode(contentEditableRoot)); + setContentEditableSelection(CefUtils.selectNode(editor, contentEditableRoot)); } else { + removeContentEditableSelection(); + // Check that we're not attempting a shift + click select within a contenteditable='true' element if (!(isContentEditableTrue(contentEditableRoot) && e.shiftKey) && !isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) { editor.selection.placeCaretAt(e.clientX, e.clientY); @@ -41532,22 +42201,6 @@ define( } switch (e.keyCode) { - case VK.RIGHT: - override(e, right); - break; - - case VK.DOWN: - override(e, down); - break; - - case VK.LEFT: - override(e, left); - break; - - case VK.UP: - override(e, up); - break; - default: if (isContentEditableFalse(editor.selection.getNode()) && isContentKey(e)) { e.preventDefault(); @@ -41595,7 +42248,7 @@ define( editor.on('focus', function () { // Make sure we have a proper fake caret on focus Delay.setEditorTimeout(editor, function () { - editor.selection.setRng(renderRangeCaret(editor.selection.getRng())); + editor.selection.setRng(CefUtils.renderRangeCaret(editor, editor.selection.getRng())); }, 0); }); @@ -41779,6 +42432,7 @@ define( } return { + showCaret: showCaret, showBlockCaretContainer: showBlockCaretContainer, hideFakeCaret: hideFakeCaret, destroy: destroy @@ -42884,7 +43538,7 @@ define( function isHidden() { var sel; - if (!isGecko) { + if (!isGecko || editor.removed) { return 0; } @@ -43489,8 +44143,31 @@ define( return o; }; + var relaxDomain = function (editor, ifr) { + // Domain relaxing is required since the user has messed around with document.domain + // This only applies to IE 11 other browsers including Edge seems to handle document.domain + if (document.domain !== window.location.hostname && Env.ie && Env.ie < 12) { + var bodyUuid = Uuid.uuid('mce'); + + editor[bodyUuid] = function () { + InitContentBody.initContentBody(editor); + }; + + /*eslint no-script-url:0 */ + var domainRelaxUrl = 'javascript:(function(){' + + 'document.open();document.domain="' + document.domain + '";' + + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + + 'document.close();ed.' + bodyUuid + '(true);})()'; + + DOM.setAttrib(ifr, 'src', domainRelaxUrl); + return true; + } + + return false; + }; + var createIframe = function (editor, o) { - var settings = editor.settings, bodyId, bodyClass, url; + var settings = editor.settings, bodyId, bodyClass; editor.iframeHTML = settings.doctype + ''; @@ -43527,31 +44204,10 @@ define( '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '">
'; - var bodyUuid = Uuid.uuid('mce'); - - editor[bodyUuid] = function () { - InitContentBody.initContentBody(editor); - }; - - /*eslint no-script-url:0 */ - var domainRelaxUrl = 'javascript:(function(){' + - 'document.open();document.domain="' + document.domain + '";' + - 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + - 'document.close();ed.' + bodyUuid + '(true);})()'; - - // Domain relaxing is required since the user has messed around with document.domain - if (document.domain != window.location.hostname) { - // Edge seems to be able to handle domain relaxing - if (Env.ie && Env.ie < 12) { - url = domainRelaxUrl; - } - } - // Create iframe // TODO: ACC add the appropriate description on this. var ifr = DOM.create('iframe', { id: editor.id + "_ifr", - //src: url || 'javascript:""', // Workaround for HTTPS warning in IE6/7 frameBorder: '0', allowTransparency: "true", title: editor.editorManager.translate( @@ -43570,29 +44226,18 @@ define( editor.fire("load"); }; - DOM.setAttrib(ifr, "src", url || 'javascript:""'); + var isDomainRelaxed = relaxDomain(editor, ifr); editor.contentAreaContainer = o.iframeContainer; editor.iframeElement = ifr; DOM.add(o.iframeContainer, ifr); - // Try accessing the document this will fail on IE when document.domain is set to the same as location.hostname - // Then we have to force domain relaxing using the domainRelaxUrl approach very ugly!! - if (Env.ie) { - try { - editor.getDoc(); - } catch (e) { - ifr.src = url = domainRelaxUrl; - } - } - - return url; + return isDomainRelaxed; }; var init = function (editor) { - var settings = editor.settings, elm = editor.getElement(); - var boxInfo, url; + var settings = editor.settings, elm = editor.getElement(), boxInfo; editor.rtl = settings.rtl_ui || editor.editorManager.i18n.rtl; editor.editorManager.i18n.setCode(settings.language); @@ -43621,7 +44266,7 @@ define( return InitContentBody.initContentBody(editor); } - url = createIframe(editor, boxInfo); + var isDomainRelaxed = createIframe(editor, boxInfo); if (boxInfo.editorContainer) { DOM.get(boxInfo.editorContainer).style.display = editor.orgDisplay; @@ -43631,7 +44276,7 @@ define( editor.getElement().style.display = 'none'; DOM.setAttrib(editor.id, 'aria-hidden', true); - if (!url) { + if (!isDomainRelaxed) { InitContentBody.initContentBody(editor); } }; @@ -44265,6 +44910,10 @@ define( }); } + if (self.removed) { + return; + } + if (!skipFocus) { // Get selected control element rng = selection.getRng(); @@ -44813,6 +45462,10 @@ define( load: function (args) { var self = this, elm = self.getElement(), html; + if (self.removed) { + return ''; + } + if (elm) { args = args || {}; args.load = true; @@ -44842,7 +45495,7 @@ define( save: function (args) { var self = this, elm = self.getElement(), html, form; - if (!elm || !self.initialized) { + if (!elm || !self.initialized || self.removed) { return; } @@ -45005,6 +45658,10 @@ define( getContent: function (args) { var self = this, content, body = self.getBody(); + if (self.removed) { + return ''; + } + // Setup args object args = args || {}; args.format = args.format || 'html'; @@ -46058,7 +46715,7 @@ define( * @property minorVersion * @type String */ - minorVersion: '6.1', + minorVersion: '6.2', /** * Release date of TinyMCE build. @@ -46066,7 +46723,7 @@ define( * @property releaseDate * @type String */ - releaseDate: '2017-05-10', + releaseDate: '2017-05-23', /** * Collection of editor instances. @@ -50577,19 +51234,22 @@ define( define( 'tinymce.core.fmt.FontInfo', [ - "tinymce.core.dom.DOMUtils" + 'ephox.katamari.api.Fun', + 'ephox.katamari.api.Option', + 'ephox.sugar.api.node.Element', + 'ephox.sugar.api.node.Node', + 'tinymce.core.dom.DOMUtils' ], - function (DOMUtils) { + function (Fun, Option, Element, Node, DOMUtils) { var getSpecifiedFontProp = function (propName, rootElm, elm) { while (elm !== rootElm) { if (elm.style[propName]) { - return elm.style[propName]; + var foundStyle = elm.style[propName]; + return foundStyle !== '' ? Option.some(foundStyle) : Option.none(); } - elm = elm.parentNode; } - - return ''; + return Option.none(); }; var toPt = function (fontSize) { @@ -50606,24 +51266,25 @@ define( }; var getComputedFontProp = function (propName, elm) { - return DOMUtils.DOM.getStyle(elm, propName, true); + return Option.from(DOMUtils.DOM.getStyle(elm, propName, true)); }; - var getFontSize = function (rootElm, elm) { - var specifiedFontSize = getSpecifiedFontProp('fontSize', rootElm, elm); - return specifiedFontSize !== '' ? specifiedFontSize : getComputedFontProp('fontSize', elm); - }; - - var getFontFamily = function (rootElm, elm) { - var specifiedFontSize = getSpecifiedFontProp('fontFamily', rootElm, elm); - var fontValue = specifiedFontSize !== '' ? specifiedFontSize : getComputedFontProp('fontFamily', elm); - - return fontValue !== undefined ? normalizeFontFamily(fontValue) : ''; + var getFontProp = function (propName) { + return function (rootElm, elm) { + return Option.from(elm) + .map(Element.fromDom) + .filter(Node.isElement) + .bind(function (element) { + return getSpecifiedFontProp(propName, rootElm, element.dom()) + .or(getComputedFontProp(propName, element.dom())); + }) + .getOr(''); + }; }; return { - getFontSize: getFontSize, - getFontFamily: getFontFamily, + getFontSize: getFontProp('fontSize'), + getFontFamily: Fun.compose(normalizeFontFamily, getFontProp('fontFamily')), toPt: toPt }; } diff --git a/src/wp-includes/js/tinymce/tinymce.min.js b/src/wp-includes/js/tinymce/tinymce.min.js index a5707d1cca..ebd3be51ec 100644 --- a/src/wp-includes/js/tinymce/tinymce.min.js +++ b/src/wp-includes/js/tinymce/tinymce.min.js @@ -1,16 +1,16 @@ -// 4.6.1 (2017-05-10) +// 4.6.2 (2017-05-23) !function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i=d.x&&f.x+f.w<=d.w+d.x&&f.y>=d.y&&f.y+f.h<=d.h+d.y)return e[g];return null}function c(a,b,c){return f(a.x-b,a.y-c,a.w+2*b,a.h+2*c)}function d(a,b){var c,d,e,g;return c=i(a.x,b.x),d=i(a.y,b.y),e=h(a.x+a.w,b.x+b.w),g=h(a.y+a.h,b.y+b.h),e-c<0||g-d<0?null:f(c,d,e-c,g-d)}function e(a,b,c){var d,e,g,h,j,k,l,m,n,o;return j=a.x,k=a.y,l=a.x+a.w,m=a.y+a.h,n=b.x+b.w,o=b.y+b.h,d=i(0,b.x-j),e=i(0,b.y-k),g=i(0,l-n),h=i(0,m-o),j+=d,k+=e,c&&(l+=d,m+=e,j-=g,k-=h),l-=g,m-=h,f(j,k,l-j,m-k)}function f(a,b,c,d){return{x:a,y:b,w:c,h:d}}function g(a){return f(a.left,a.top,a.width,a.height)}var h=Math.min,i=Math.max,j=Math.round;return{inflate:c,relativePosition:a,findBestRelativePosition:b,intersect:d,clamp:e,create:f,fromClientRect:g}}),g("4",[],function(){function a(a,b){return function(){a.apply(b,arguments)}}function b(b){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof b)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],h(b,a(d,this),a(e,this))}function c(a){var b=this;return null===this._state?void this._deferreds.push(a):void i(function(){var c=b._state?a.onFulfilled:a.onRejected;if(null===c)return void(b._state?a.resolve:a.reject)(b._value);var d;try{d=c(b._value)}catch(b){return void a.reject(b)}a.resolve(d)})}function d(b){try{if(b===this)throw new TypeError("A promise cannot be resolved with itself.");if(b&&("object"==typeof b||"function"==typeof b)){var c=b.then;if("function"==typeof c)return void h(a(c,b),a(d,this),a(e,this))}this._state=!0,this._value=b,f.call(this)}catch(a){e.call(this,a)}}function e(a){this._state=!1,this._value=a,f.call(this)}function f(){for(var a=0,b=this._deferreds.length;a=534;return{opera:b,webkit:c,ie:d,gecko:g,mac:h,iOS:i,android:j,contentEditable:q,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=d,range:window.getSelection&&"Range"in window,documentMode:d&&!f?document.documentMode||7:10,fileApi:k,ceFalse:d===!1||d>8,canHaveCSP:d===!1||d>11,desktop:!l&&!m,windowsPhone:n}}),g("7",["5","6"],function(a,b){"use strict";function c(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d||!1):a.attachEvent&&a.attachEvent("on"+b,c)}function d(a,b,c,d){a.removeEventListener?a.removeEventListener(b,c,d||!1):a.detachEvent&&a.detachEvent("on"+b,c)}function e(a,b){var c,d=b;return c=a.path,c&&c.length>0&&(d=c[0]),a.deepPath&&(c=a.deepPath(),c&&c.length>0&&(d=c[0])),d}function f(a,c){var d,f,g=c||{};for(d in a)k[d]||(g[d]=a[d]);if(g.target||(g.target=g.srcElement||document),b.experimentalShadowDom&&(g.target=e(a,g.target)),a&&j.test(a.type)&&a.pageX===f&&a.clientX!==f){var h=g.target.ownerDocument||document,i=h.documentElement,o=h.body;g.pageX=a.clientX+(i&&i.scrollLeft||o&&o.scrollLeft||0)-(i&&i.clientLeft||o&&o.clientLeft||0),g.pageY=a.clientY+(i&&i.scrollTop||o&&o.scrollTop||0)-(i&&i.clientTop||o&&o.clientTop||0)}return g.preventDefault=function(){g.isDefaultPrevented=n,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},g.stopPropagation=function(){g.isPropagationStopped=n,a&&(a.stopPropagation?a.stopPropagation():a.cancelBubble=!0)},g.stopImmediatePropagation=function(){g.isImmediatePropagationStopped=n,g.stopPropagation()},l(g)===!1&&(g.isDefaultPrevented=m,g.isPropagationStopped=m,g.isImmediatePropagationStopped=m),"undefined"==typeof g.metaKey&&(g.metaKey=!1),g}function g(e,f,g){function h(){return"complete"===l.readyState||"interactive"===l.readyState&&l.body}function i(){g.domLoaded||(g.domLoaded=!0,f(m))}function j(){h()&&(d(l,"readystatechange",j),i())}function k(){try{l.documentElement.doScroll("left")}catch(b){return void a.setTimeout(k)}i()}var l=e.document,m={type:"ready"};return g.domLoaded?void f(m):(!l.addEventListener||b.ie&&b.ie<11?(c(l,"readystatechange",j),l.documentElement.doScroll&&e.self===e.top&&k()):h()?i():c(e,"DOMContentLoaded",i),void c(e,"load",i))}function h(){function a(a,b){var c,d,e,f,g=m[b];if(c=g&&g[a.type])for(d=0,e=c.length;dv.cacheLength&&delete a[b.shift()],a[c+" "]=d}var b=[];return a}function c(a){return a[M]=!0,a}function d(a){var b=F.createElement("div");try{return!!a(b)}catch(a){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function e(a,b){for(var c=a.split("|"),d=a.length;d--;)v.attrHandle[c[d]]=b}function f(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||V)-(~a.sourceIndex||V);if(d)return d;if(c)for(;c=c.nextSibling;)if(c===b)return-1;return a?1:-1}function g(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function h(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function i(a){return c(function(b){return b=+b,c(function(c,d){for(var e,f=a([],c.length,b),g=f.length;g--;)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function j(a){return a&&typeof a.getElementsByTagName!==U&&a}function k(){}function l(a){for(var b=0,c=a.length,d="";b1?function(b,c,d){for(var e=a.length;e--;)if(!a[e](b,c,d))return!1;return!0}:a[0]}function o(b,c,d){for(var e=0,f=c.length;e-1&&(c[j]=!(g[j]=l))}}else t=p(t===g?t.splice(q,t.length):t),f?f(null,g,t,i):$.apply(g,t)})}function r(a){for(var b,c,d,e=a.length,f=v.relative[a[0].type],g=f||v.relative[" "],h=f?1:0,i=m(function(a){return a===b},g,!0),j=m(function(a){return aa.call(b,a)>-1},g,!0),k=[function(a,c,d){return!f&&(d||c!==B)||((b=c).nodeType?i(a,c,d):j(a,c,d))}];h1&&n(k),h>1&&l(a.slice(0,h-1).concat({value:" "===a[h-2].type?"*":""})).replace(ga,"$1"),c,h0,f=b.length>0,g=function(c,g,h,i,j){var k,l,m,n=0,o="0",q=c&&[],r=[],s=B,t=c||f&&v.find.TAG("*",j),u=O+=null==s?1:Math.random()||.1,w=t.length;for(j&&(B=g!==F&&g);o!==w&&null!=(k=t[o]);o++){if(f&&k){for(l=0;m=b[l++];)if(m(k,g,h)){i.push(k);break}j&&(O=u)}e&&((k=!m&&k)&&n--,c&&q.push(k))}if(n+=o,e&&o!==n){for(l=0;m=d[l++];)m(q,r,g,h);if(c){if(n>0)for(;o--;)q[o]||r[o]||(r[o]=Y.call(i));r=p(r)}$.apply(i,r),j&&!c&&r.length>0&&n+d.length>1&&a.uniqueSort(i)}return j&&(O=u,B=s),q};return e?c(g):g}var t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M="sizzle"+-new Date,N=window.document,O=0,P=0,Q=b(),R=b(),S=b(),T=function(a,b){return a===b&&(D=!0),0},U="undefined",V=1<<31,W={}.hasOwnProperty,X=[],Y=X.pop,Z=X.push,$=X.push,_=X.slice,aa=X.indexOf||function(a){for(var b=0,c=this.length;b+~]|"+ca+")"+ca+"*"),ja=new RegExp("="+ca+"*([^\\]'\"]*?)"+ca+"*\\]","g"),ka=new RegExp(fa),la=new RegExp("^"+da+"$"),ma={ID:new RegExp("^#("+da+")"),CLASS:new RegExp("^\\.("+da+")"),TAG:new RegExp("^("+da+"|[*])"),ATTR:new RegExp("^"+ea),PSEUDO:new RegExp("^"+fa),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ca+"*(even|odd|(([+-]|)(\\d*)n|)"+ca+"*(?:([+-]|)"+ca+"*(\\d+)|))"+ca+"*\\)|)","i"),bool:new RegExp("^(?:"+ba+")$","i"),needsContext:new RegExp("^"+ca+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ca+"*((?:-\\d)?\\d*)"+ca+"*\\)|)(?=[^-]|$)","i")},na=/^(?:input|select|textarea|button)$/i,oa=/^h\d$/i,pa=/^[^{]+\{\s*\[native \w/,qa=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ra=/[+~]/,sa=/'|\\/g,ta=new RegExp("\\\\([\\da-f]{1,6}"+ca+"?|("+ca+")|.)","ig"),ua=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{$.apply(X=_.call(N.childNodes),N.childNodes),X[N.childNodes.length].nodeType}catch(a){$={apply:X.length?function(a,b){Z.apply(a,_.call(b))}:function(a,b){for(var c=a.length,d=0;a[c++]=b[d++];);a.length=c-1}}}u=a.support={},x=a.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},E=a.setDocument=function(a){function b(a){try{return a.top}catch(a){}return null}var c,e=a?a.ownerDocument||a:N,g=e.defaultView;return e!==F&&9===e.nodeType&&e.documentElement?(F=e,G=e.documentElement,H=!x(e),g&&g!==b(g)&&(g.addEventListener?g.addEventListener("unload",function(){E()},!1):g.attachEvent&&g.attachEvent("onunload",function(){E()})),u.attributes=d(function(a){return a.className="i",!a.getAttribute("className")}),u.getElementsByTagName=d(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),u.getElementsByClassName=pa.test(e.getElementsByClassName),u.getById=d(function(a){return G.appendChild(a).id=M,!e.getElementsByName||!e.getElementsByName(M).length}),u.getById?(v.find.ID=function(a,b){if(typeof b.getElementById!==U&&H){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},v.filter.ID=function(a){var b=a.replace(ta,ua);return function(a){return a.getAttribute("id")===b}}):(delete v.find.ID,v.filter.ID=function(a){var b=a.replace(ta,ua);return function(a){var c=typeof a.getAttributeNode!==U&&a.getAttributeNode("id");return c&&c.value===b}}),v.find.TAG=u.getElementsByTagName?function(a,b){if(typeof b.getElementsByTagName!==U)return b.getElementsByTagName(a)}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){for(;c=f[e++];)1===c.nodeType&&d.push(c);return d}return f},v.find.CLASS=u.getElementsByClassName&&function(a,b){if(H)return b.getElementsByClassName(a)},J=[],I=[],(u.qsa=pa.test(e.querySelectorAll))&&(d(function(a){a.innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&I.push("[*^$]="+ca+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||I.push("\\["+ca+"*(?:value|"+ba+")"),a.querySelectorAll(":checked").length||I.push(":checked")}),d(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&I.push("name"+ca+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||I.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),I.push(",.*:")})),(u.matchesSelector=pa.test(K=G.matches||G.webkitMatchesSelector||G.mozMatchesSelector||G.oMatchesSelector||G.msMatchesSelector))&&d(function(a){u.disconnectedMatch=K.call(a,"div"),K.call(a,"[s!='']:x"),J.push("!=",fa)}),I=I.length&&new RegExp(I.join("|")),J=J.length&&new RegExp(J.join("|")),c=pa.test(G.compareDocumentPosition),L=c||pa.test(G.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b=b.parentNode;)if(b===a)return!0;return!1},T=c?function(a,b){if(a===b)return D=!0,0;var c=!a.compareDocumentPosition-!b.compareDocumentPosition;return c?c:(c=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&c||!u.sortDetached&&b.compareDocumentPosition(a)===c?a===e||a.ownerDocument===N&&L(N,a)?-1:b===e||b.ownerDocument===N&&L(N,b)?1:C?aa.call(C,a)-aa.call(C,b):0:4&c?-1:1)}:function(a,b){if(a===b)return D=!0,0;var c,d=0,g=a.parentNode,h=b.parentNode,i=[a],j=[b];if(!g||!h)return a===e?-1:b===e?1:g?-1:h?1:C?aa.call(C,a)-aa.call(C,b):0;if(g===h)return f(a,b);for(c=a;c=c.parentNode;)i.unshift(c);for(c=b;c=c.parentNode;)j.unshift(c);for(;i[d]===j[d];)d++;return d?f(i[d],j[d]):i[d]===N?-1:j[d]===N?1:0},e):F},a.matches=function(b,c){return a(b,null,null,c)},a.matchesSelector=function(b,c){if((b.ownerDocument||b)!==F&&E(b),c=c.replace(ja,"='$1']"),u.matchesSelector&&H&&(!J||!J.test(c))&&(!I||!I.test(c)))try{var d=K.call(b,c);if(d||u.disconnectedMatch||b.document&&11!==b.document.nodeType)return d}catch(a){}return a(c,F,null,[b]).length>0},a.contains=function(a,b){return(a.ownerDocument||a)!==F&&E(a),L(a,b)},a.attr=function(a,b){(a.ownerDocument||a)!==F&&E(a);var c=v.attrHandle[b.toLowerCase()],d=c&&W.call(v.attrHandle,b.toLowerCase())?c(a,b,!H):void 0;return void 0!==d?d:u.attributes||!H?a.getAttribute(b):(d=a.getAttributeNode(b))&&d.specified?d.value:null},a.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},a.uniqueSort=function(a){var b,c=[],d=0,e=0;if(D=!u.detectDuplicates,C=!u.sortStable&&a.slice(0),a.sort(T),D){for(;b=a[e++];)b===a[e]&&(d=c.push(e));for(;d--;)a.splice(c[d],1)}return C=null,a},w=a.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(1===e||9===e||11===e){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=w(a)}else if(3===e||4===e)return a.nodeValue}else for(;b=a[d++];)c+=w(b);return c},v=a.selectors={cacheLength:50,createPseudo:c,match:ma,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ta,ua),a[3]=(a[3]||a[4]||a[5]||"").replace(ta,ua),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(b){return b[1]=b[1].toLowerCase(),"nth"===b[1].slice(0,3)?(b[3]||a.error(b[0]),b[4]=+(b[4]?b[5]+(b[6]||1):2*("even"===b[3]||"odd"===b[3])),b[5]=+(b[7]+b[8]||"odd"===b[3])):b[3]&&a.error(b[0]),b},PSEUDO:function(a){var b,c=!a[6]&&a[2];return ma.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&ka.test(c)&&(b=y(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ta,ua).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=Q[a+" "];return b||(b=new RegExp("(^|"+ca+")"+a+"("+ca+"|$)"))&&Q(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==U&&a.getAttribute("class")||"")})},ATTR:function(b,c,d){return function(e){var f=a.attr(e,b);return null==f?"!="===c:!c||(f+="","="===c?f===d:"!="===c?f!==d:"^="===c?d&&0===f.indexOf(d):"*="===c?d&&f.indexOf(d)>-1:"$="===c?d&&f.slice(-d.length)===d:"~="===c?(" "+f+" ").indexOf(d)>-1:"|="===c&&(f===d||f.slice(0,d.length+1)===d+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){for(;p;){for(l=b;l=l[p];)if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){for(k=q[M]||(q[M]={}),j=k[a]||[],n=j[0]===O&&j[1],m=j[0]===O&&j[2],l=n&&q.childNodes[n];l=++n&&l&&l[p]||(m=n=0)||o.pop();)if(1===l.nodeType&&++m&&l===b){k[a]=[O,n,m];break}}else if(s&&(j=(b[M]||(b[M]={}))[a])&&j[0]===O)m=j[1];else for(;(l=++n&&l&&l[p]||(m=n=0)||o.pop())&&((h?l.nodeName.toLowerCase()!==r:1!==l.nodeType)||!++m||(s&&((l[M]||(l[M]={}))[a]=[O,m]),l!==b)););return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(b,d){var e,f=v.pseudos[b]||v.setFilters[b.toLowerCase()]||a.error("unsupported pseudo: "+b);return f[M]?f(d):f.length>1?(e=[b,b,"",d],v.setFilters.hasOwnProperty(b.toLowerCase())?c(function(a,b){for(var c,e=f(a,d),g=e.length;g--;)c=aa.call(a,e[g]),a[c]=!(b[c]=e[g])}):function(a){return f(a,0,e)}):f}},pseudos:{not:c(function(a){var b=[],d=[],e=z(a.replace(ga,"$1"));return e[M]?c(function(a,b,c,d){for(var f,g=e(a,null,d,[]),h=a.length;h--;)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,c,f){return b[0]=a,e(b,null,f,d),!d.pop()}}),has:c(function(b){return function(c){return a(b,c).length>0}}),contains:c(function(a){return a=a.replace(ta,ua),function(b){return(b.textContent||b.innerText||w(b)).indexOf(a)>-1}}),lang:c(function(b){return la.test(b||"")||a.error("unsupported lang: "+b),b=b.replace(ta,ua).toLowerCase(),function(a){var c;do if(c=H?a.lang:a.getAttribute("xml:lang")||a.getAttribute("lang"))return c=c.toLowerCase(),c===b||0===c.indexOf(b+"-");while((a=a.parentNode)&&1===a.nodeType);return!1}}),target:function(a){var b=window.location&&window.location.hash;return b&&b.slice(1)===a.id},root:function(a){return a===G},focus:function(a){return a===F.activeElement&&(!F.hasFocus||F.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!v.pseudos.empty(a)},header:function(a){return oa.test(a.nodeName)},input:function(a){return na.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:i(function(){return[0]}),last:i(function(a,b){return[b-1]}),eq:i(function(a,b,c){return[c<0?c+b:c]}),even:i(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:i(function(a,b,c){for(var d=c<0?c+b:c;++d2&&"ID"===(g=f[0]).type&&u.getById&&9===b.nodeType&&H&&v.relative[f[1].type]){if(b=(v.find.ID(g.matches[0].replace(ta,ua),b)||[])[0],!b)return c;k&&(b=b.parentNode),a=a.slice(f.shift().value.length)}for(e=ma.needsContext.test(a)?0:f.length;e--&&(g=f[e],!v.relative[h=g.type]);)if((i=v.find[h])&&(d=i(g.matches[0].replace(ta,ua),ra.test(f[0].type)&&j(b.parentNode)||b))){if(f.splice(e,1),a=d.length&&l(f),!a)return $.apply(c,d),c;break}}return(k||z(a,m))(d,b,!H,c,ra.test(a)&&j(b.parentNode)||b),c},u.sortStable=M.split("").sort(T).join("")===M,u.detectDuplicates=!!D,E(),u.sortDetached=d(function(a){return 1&a.compareDocumentPosition(F.createElement("div"))}),d(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||e("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),u.attributes&&d(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||e("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),d(function(a){return null==a.getAttribute("disabled")})||e(ba,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),a}),g("1g",[],function(){function a(a){var b,c,d=a;if(!j(a))for(d=[],b=0,c=a.length;b=0;e--)i(a,b[e],c,d);else for(e=0;e)[^>]*$|#([\w\-]*)$)/,A=a.Event,B=c.makeMap("children,contents,next,prev"),C=c.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," "),D=c.makeMap("checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected"," "),E={"for":"htmlFor","class":"className",readonly:"readOnly"},F={"float":"cssFloat"},G={},H={},I=/^\s*|\s*$/g;return l.fn=l.prototype={constructor:l,selector:"",context:null,length:0,init:function(a,b){var c,d,e=this;if(!a)return e;if(a.nodeType)return e.context=e[0]=a,e.length=1,e;if(b&&b.nodeType)e.context=b;else{if(b)return l(a).attr(b);e.context=b=document}if(f(a)){if(e.selector=a,c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c)return l(b).find(a);if(c[1])for(d=h(a,q(b)).firstChild;d;)x.call(e,d),d=d.nextSibling;else{if(d=q(b).getElementById(c[2]),!d)return e;if(d.id!==c[2])return e.find(a);e.length=1,e[0]=d}}else this.add(a,!1);return e},toArray:function(){return c.toArray(this)},add:function(a,b){var c,d,e=this;if(f(a))return e.add(l(a));if(b!==!1)for(c=l.unique(e.toArray().concat(l.makeArray(a))),e.length=c.length,d=0;d1&&(B[a]||(e=l.unique(e)),0===a.indexOf("parents")&&(e=e.reverse())),e=l(e),c?e.filter(c):e}}),o({parentsUntil:function(a,b){return r(a,"parentNode",b)},nextUntil:function(a,b){return s(a,"nextSibling",1,b).slice(1)},prevUntil:function(a,b){return s(a,"previousSibling",1,b).slice(1)}},function(a,b){l.fn[a]=function(c,d){var e=this,f=[];return e.each(function(){var a=b.call(f,this,c,f);a&&(l.isArray(a)?f.push.apply(f,a):f.push(a))}),this.length>1&&(f=l.unique(f),0!==a.indexOf("parents")&&"prevUntil"!==a||(f=f.reverse())),f=l(f),d?f.filter(d):f}}),l.fn.is=function(a){return!!a&&this.filter(a).length>0},l.fn.init.prototype=l.fn,l.overrideDefaults=function(a){function b(d,e){return c=c||a(),0===arguments.length&&(d=c.element),e||(e=c.context),new b.fn.init(d,e)}var c;return l.extend(b,this),b},d.ie&&d.ie<8&&(u(G,"get",{maxlength:function(a){var b=a.maxLength;return 2147483647===b?v:b},size:function(a){var b=a.size;return 20===b?v:b},"class":function(a){return a.className},style:function(a){var b=a.style.cssText;return 0===b.length?v:b}}),u(G,"set",{"class":function(a,b){a.className=b},style:function(a,b){a.style.cssText=b}})),d.ie&&d.ie<9&&(F["float"]="styleFloat",u(H,"set",{opacity:function(a,b){var c=a.style;null===b||""===b?c.removeAttribute("filter"):(c.zoom=1,c.filter="alpha(opacity="+100*b+")")}})),l.attrHooks=G,l.cssHooks=H,l}),g("b",[],function(){return function(a,b){function c(a,b,c,d){function e(a){return a=parseInt(a,10).toString(16),a.length>1?a:"0"+a}return"#"+e(b)+e(c)+e(d)}var d,e,f,g,h=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,j=/\s*([^:]+):\s*([^;]+);?/g,k=/\s+$/,l={},m="\ufeff";for(a=a||{},b&&(f=b.getValidStyles(),g=b.getInvalidStyles()),e=("\\\" \\' \\; \\: ; : "+m).split(" "),d=0;d-1&&c||(w[a+b]=d==-1?i[0]:i.join(" "),delete w[a+"-top"+b],delete w[a+"-right"+b],delete w[a+"-bottom"+b],delete w[a+"-left"+b])}}function f(a){var b,c=w[a];if(c){for(c=c.split(" "),b=c.length;b--;)if(c[b]!==c[0])return!1;return w[a]=c[0],!0}}function g(a,b,c,d){f(b)&&f(c)&&f(d)&&(w[a]=w[b]+" "+w[c]+" "+w[d],delete w[b],delete w[c],delete w[d])}function n(a){return v=!0,l[a]}function o(a,b){return v&&(a=a.replace(/\uFEFF[0-9]/g,function(a){return l[a]})),b||(a=a.replace(/\\([\'\";:])/g,"$1")),a}function p(a){return String.fromCharCode(parseInt(a.slice(1),16))}function q(a){return a.replace(/\\[0-9a-f]+/gi,p)}function r(b,c,d,e,f,g){if(f=f||g)return f=o(f),"'"+f.replace(/\'/g,"\\'")+"'";if(c=o(c||d||e),!a.allow_script_urls){var h=c.replace(/[\s\r\n]+/g,"");if(/(java|vb)script:/i.test(h))return"";if(!a.allow_svg_data_urls&&/^data:image\/svg/i.test(h))return""}return x&&(c=x.call(y,c,"style")),"url('"+c.replace(/\'/g,"\\'")+"')"}var s,t,u,v,w={},x=a.url_converter,y=a.url_converter_scope||this;if(b){for(b=b.replace(/[\u0000-\u001F]/g,""),b=b.replace(/\\[\"\';:\uFEFF]/g,n).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(a){return a.replace(/[;:]/g,n)});s=j.exec(b);)if(j.lastIndex=s.index+s[0].length,t=s[1].replace(k,"").toLowerCase(),u=s[2].replace(k,""),t&&u){if(t=q(t),u=q(u),t.indexOf(m)!==-1||t.indexOf('"')!==-1)continue;if(!a.allow_script_urls&&("behavior"==t||/expression\s*\(|\/\*|\*\//.test(u)))continue;"font-weight"===t&&"700"===u?u="bold":"color"!==t&&"background-color"!==t||(u=u.toLowerCase()),u=u.replace(h,c),u=u.replace(i,r),w[t]=v?o(u,!0):u}e("border","",!0),e("border","-width"),e("border","-color"),e("border","-style"),e("padding",""),e("margin",""),g("border","border-width","border-style","border-color"),"medium none"===w.border&&delete w.border,"none"===w["border-image"]&&delete w["border-image"]}return w},serialize:function(a,b){function c(b){var c,d,e,g;if(c=f[b])for(d=0,e=c.length;d0?" ":"")+b+": "+g+";")}function d(a,b){var c;return c=g["*"],(!c||!c[a])&&(c=g[b],!c||!c[a])}var e,h,i="";if(b&&f)c("*"),c(b);else for(e in a)h=a[e],!h||g&&!d(e,b)||(i+=(i.length>0?" ":"")+e+": "+h+";");return i}}}}),g("c",[],function(){return function(a,b){function c(a,c,d,e){var f,g;if(a){if(!e&&a[c])return a[c];if(a!=b){if(f=a[d])return f;for(g=a.parentNode;g&&g!=b;g=g.parentNode)if(f=g[d])return f}}}function d(a,c,d,e){var f,g,h;if(a){if(f=a[d],b&&f===b)return;if(f){if(!e)for(h=f[c];h;h=h[c])if(!h[c])return h;return f}if(g=a.parentNode,g&&g!==b)return g}}var e=a;this.current=function(){return e},this.next=function(a){return e=c(e,"firstChild","nextSibling",a)},this.prev=function(a){return e=c(e,"lastChild","previousSibling",a)},this.prev2=function(a){return e=d(e,"lastChild","previousSibling",a)}}}),g("d",["9"],function(a){function b(a){var b;return b=document.createElement("div"),b.innerHTML=a,b.textContent||b.innerText||a}function c(a,b){var c,d,f,g={};if(a){for(a=a.split(","),b=b||10,c=0;c\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,i=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,j=/[<>&\"\']/g,k=/&#([a-z0-9]+);?|&([a-z0-9]+);/gi,l={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};e={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},f={"<":"<",">":">","&":"&",""":'"',"'":"'"},d=c("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var m={encodeRaw:function(a,b){return a.replace(b?h:i,function(a){return e[a]||a})},encodeAllRaw:function(a){return(""+a).replace(j,function(a){return e[a]||a})},encodeNumeric:function(a,b){return a.replace(b?h:i,function(a){return a.length>1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":e[a]||"&#"+a.charCodeAt(0)+";"})},encodeNamed:function(a,b,c){return c=c||d,a.replace(b?h:i,function(a){return e[a]||c[a]||a})},getEncodeFunc:function(a,b){function f(a,c){return a.replace(c?h:i,function(a){return void 0!==e[a]?e[a]:void 0!==b[a]?b[a]:a.length>1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":"&#"+a.charCodeAt(0)+";"})}function j(a,c){return m.encodeNamed(a,c,b)}return b=c(b)||d,a=g(a.replace(/\+/g,",")),a.named&&a.numeric?f:a.named?b?j:m.encodeNamed:a.numeric?m.encodeNumeric:m.encodeRaw},decode:function(a){return a.replace(k,function(a,c){return c?(c="x"===c.charAt(0).toLowerCase()?parseInt(c.substr(1),16):parseInt(c,10),c>65535?(c-=65536,String.fromCharCode(55296+(c>>10),56320+(1023&c))):l[c]||String.fromCharCode(c)):f[a]||d[a]||b(a)})}};return m}),g("1h",["9"],function(a){function b(c){function d(){return J.createDocumentFragment()}function e(a,b){x(N,a,b)}function f(a,b){x(O,a,b)}function g(a){e(a.parentNode,U(a))}function h(a){e(a.parentNode,U(a)+1)}function i(a){f(a.parentNode,U(a))}function j(a){f(a.parentNode,U(a)+1)}function k(a){a?(I[R]=I[Q],I[S]=I[P]):(I[Q]=I[R],I[P]=I[S]),I.collapsed=N}function l(a){g(a),j(a)}function m(a){e(a,0),f(a,1===a.nodeType?a.childNodes.length:a.nodeValue.length)}function n(a,b){var c=I[Q],d=I[P],e=I[R],f=I[S],g=b.startContainer,h=b.startOffset,i=b.endContainer,j=b.endOffset;return 0===a?w(c,d,g,h):1===a?w(e,f,g,h):2===a?w(e,f,i,j):3===a?w(c,d,i,j):void 0}function o(){y(M)}function p(){return y(K)}function q(){return y(L)}function r(a){var b,d,e=this[Q],f=this[P];3!==e.nodeType&&4!==e.nodeType||!e.nodeValue?(e.childNodes.length>0&&(d=e.childNodes[f]),d?e.insertBefore(a,d):3==e.nodeType?c.insertAfter(a,e):e.appendChild(a)):f?f>=e.nodeValue.length?c.insertAfter(a,e):(b=e.splitText(f),e.parentNode.insertBefore(a,b)):e.parentNode.insertBefore(a,e)}function s(a){var b=I.extractContents();I.insertNode(a),a.appendChild(b),I.selectNode(a)}function t(){return T(new b(c),{startContainer:I[Q],startOffset:I[P],endContainer:I[R],endOffset:I[S],collapsed:I.collapsed,commonAncestorContainer:I.commonAncestorContainer})}function u(a,b){var c;if(3==a.nodeType)return a;if(b<0)return a;for(c=a.firstChild;c&&b>0;)--b,c=c.nextSibling;return c?c:a}function v(){return I[Q]==I[R]&&I[P]==I[S]}function w(a,b,d,e){var f,g,h,i,j,k;if(a==d)return b==e?0:b0&&I.collapse(a):I.collapse(a),I.collapsed=v(),I.commonAncestorContainer=c.findCommonAncestor(I[Q],I[R])}function y(a){var b,c,d,e,f,g,h,i=0,j=0;if(I[Q]==I[R])return z(a);for(b=I[R],c=b.parentNode;c;b=c,c=c.parentNode){if(c==I[Q])return A(b,a);++i}for(b=I[Q],c=b.parentNode;c;b=c,c=c.parentNode){if(c==I[R])return B(b,a);++j}for(d=j-i,e=I[Q];d>0;)e=e.parentNode,d--;for(f=I[R];d<0;)f=f.parentNode,d++;for(g=e.parentNode,h=f.parentNode;g!=h;g=g.parentNode,h=h.parentNode)e=g,f=h;return C(e,f,a)}function z(a){var b,c,e,f,g,h,i,j,k;if(a!=M&&(b=d()),I[P]==I[S])return b;if(3==I[Q].nodeType){if(c=I[Q].nodeValue,e=c.substring(I[P],I[S]),a!=L&&(f=I[Q],j=I[P],k=I[S]-I[P],0===j&&k>=f.nodeValue.length-1?f.parentNode.removeChild(f):f.deleteData(j,k),I.collapse(N)),a==M)return;return e.length>0&&b.appendChild(J.createTextNode(e)),b}for(f=u(I[Q],I[P]),g=I[S]-I[P];f&&g>0;)h=f.nextSibling,i=G(f,a),b&&b.appendChild(i),--g,f=h;return a!=L&&I.collapse(N),b}function A(a,b){var c,e,f,g,h,i;if(b!=M&&(c=d()),e=D(a,b),c&&c.appendChild(e),f=U(a),g=f-I[P],g<=0)return b!=L&&(I.setEndBefore(a),I.collapse(O)),c;for(e=a.previousSibling;g>0;)h=e.previousSibling,i=G(e,b),c&&c.insertBefore(i,c.firstChild),--g,e=h;return b!=L&&(I.setEndBefore(a),I.collapse(O)),c}function B(a,b){var c,e,f,g,h,i;for(b!=M&&(c=d()),f=E(a,b),c&&c.appendChild(f),e=U(a),++e,g=I[S]-e,f=a.nextSibling;f&&g>0;)h=f.nextSibling,i=G(f,b),c&&c.appendChild(i),--g,f=h;return b!=L&&(I.setStartAfter(a),I.collapse(N)),c}function C(a,b,c){var e,f,g,h,i,j,k;for(c!=M&&(f=d()),e=E(a,c),f&&f.appendChild(e),g=U(a),h=U(b),++g,i=h-g,j=a.nextSibling;i>0;)k=j.nextSibling,e=G(j,c),f&&f.appendChild(e),j=k,--i;return e=D(b,c),f&&f.appendChild(e),c!=L&&(I.setStartAfter(a),I.collapse(N)),f}function D(a,b){var c,d,e,f,g,h=u(I[R],I[S]-1),i=h!=I[R];if(h==a)return F(h,i,O,b);for(c=h.parentNode,d=F(c,O,O,b);c;){for(;h;)e=h.previousSibling,f=F(h,i,O,b),b!=M&&d.insertBefore(f,d.firstChild),i=N,h=e;if(c==a)return d;h=c.previousSibling,c=c.parentNode,g=F(c,O,O,b),b!=M&&g.appendChild(d),d=g}}function E(a,b){var c,d,e,f,g,h=u(I[Q],I[P]),i=h!=I[Q];if(h==a)return F(h,i,N,b);for(c=h.parentNode,d=F(c,O,N,b);c;){for(;h;)e=h.nextSibling,f=F(h,i,N,b),b!=M&&d.appendChild(f),i=N,h=e;if(c==a)return d;h=c.nextSibling,c=c.parentNode,g=F(c,O,N,b),b!=M&&g.appendChild(d),d=g}}function F(a,b,d,e){var f,g,h,i,j;if(b)return G(a,e);if(3==a.nodeType){if(f=a.nodeValue,d?(i=I[P],g=f.substring(i),h=f.substring(0,i)):(i=I[S],g=f.substring(0,i),h=f.substring(i)),e!=L&&(a.nodeValue=h),e==M)return;return j=c.clone(a,O),j.nodeValue=g,j}if(e!=M)return c.clone(a,O)}function G(a,b){return b!=M?b==L?c.clone(a,N):a:void a.parentNode.removeChild(a)}function H(){return c.create("body",null,q()).outerText}var I=this,J=c.doc,K=0,L=1,M=2,N=!0,O=!1,P="startOffset",Q="startContainer",R="endContainer",S="endOffset",T=a.extend,U=c.nodeIndex;return T(I,{startContainer:J,startOffset:0,endContainer:J,endOffset:0,collapsed:N,commonAncestorContainer:J,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:e,setEnd:f,setStartBefore:g,setStartAfter:h,setEndBefore:i,setEndAfter:j,collapse:k,selectNode:l,selectNodeContents:m,compareBoundaryPoints:n,deleteContents:o,extractContents:p,cloneContents:q,insertNode:r,surroundContents:s,cloneRange:t,toStringIE:H}),I}return b.prototype.toString=function(){return this.toStringIE()},b}),h("4i",Array),h("4j",Error),g("3s",["4i","4j"],function(a,b){var c=function(){},d=function(a,b){return function(){return a(b.apply(null,arguments))}},e=function(a){return function(){return a}},f=function(a){return a},g=function(a,b){return a===b},h=function(b){for(var c=new a(arguments.length-1),d=1;d-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e=b.length&&c(d)}};0===b.length?c([]):a.each(b,function(a,b){a.get(f(b))})})};return{par:b}}),g("3u",["3r","3t","4n"],function(a,b,c){var d=function(a){return c.par(a,b.nu)},e=function(b,c){var e=a.map(b,c);return d(e)},f=function(a,b){return function(c){return b(c).bind(a)}};return{par:d,mapM:e,compose:f}}),g("3v",["3s","4h"],function(a,b){var c=function(d){var e=function(a){return d===a},f=function(a){return c(d)},g=function(a){return c(d)},h=function(a){return c(a(d))},i=function(a){a(d)},j=function(a){return a(d)},k=function(a,b){return b(d)},l=function(a){return a(d)},m=function(a){return a(d)},n=function(){return b.some(d)};return{is:e,isValue:a.constant(!0),isError:a.constant(!1),getOr:a.constant(d),getOrThunk:a.constant(d),getOrDie:a.constant(d),or:f,orThunk:g,fold:k,map:h,each:i,bind:j,exists:l,forall:m,toOption:n}},d=function(c){var e=function(a){return a()},f=function(){return a.die(c)()},g=function(a){return a},h=function(a){return a()},i=function(a){return d(c)},j=function(a){return d(c)},k=function(a,b){return a(c)};return{is:a.constant(!1),isValue:a.constant(!1),isError:a.constant(!0),getOr:a.identity,getOrThunk:e,getOrDie:f,or:g,orThunk:h,fold:k,map:i,each:a.noop,bind:j,exists:a.constant(!1),forall:a.constant(!0),toOption:b.none}};return{value:c,error:d}}),g("1i",["3r","3s","3t","3u","3v","5","9"],function(a,b,c,d,e,f,g){"use strict";return function(h,i){function j(a){h.getElementsByTagName("head")[0].appendChild(a)}function k(a,b,c){function d(){for(var a=t.passed,b=a.length;b--;)a[b]();t.status=2,t.passed=[],t.failed=[]}function e(){for(var a=t.failed,b=a.length;b--;)a[b]();t.status=3,t.passed=[],t.failed=[]}function i(){var a=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(a&&a[1]<536)}function k(a,b){a()||((new Date).getTime()-s0)return r=h.createElement("style"), +grep:b.filter,inArray:b.indexOf,hasOwn:f,extend:h,create:g,walk:i,createNS:j,resolve:k,explode:l,_addCacheSuffix:m}}),g("a",["7","8","9","6"],function(a,b,c,d){function e(a){return"undefined"!=typeof a}function f(a){return"string"==typeof a}function g(a){return a&&a==a.window}function h(a,b){var c,d,e;for(b=b||w,e=b.createElement("div"),c=b.createDocumentFragment(),e.innerHTML=a;d=e.firstChild;)c.appendChild(d);return c}function i(a,b,c,d){var e;if(f(b))b=h(b,q(a[0]));else if(b.length&&!b.nodeType){if(b=l.makeArray(b),d)for(e=b.length-1;e>=0;e--)i(a,b[e],c,d);else for(e=0;e)[^>]*$|#([\w\-]*)$)/,A=a.Event,B=c.makeMap("children,contents,next,prev"),C=c.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," "),D=c.makeMap("checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected"," "),E={"for":"htmlFor","class":"className",readonly:"readOnly"},F={"float":"cssFloat"},G={},H={},I=/^\s*|\s*$/g;return l.fn=l.prototype={constructor:l,selector:"",context:null,length:0,init:function(a,b){var c,d,e=this;if(!a)return e;if(a.nodeType)return e.context=e[0]=a,e.length=1,e;if(b&&b.nodeType)e.context=b;else{if(b)return l(a).attr(b);e.context=b=document}if(f(a)){if(e.selector=a,c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c)return l(b).find(a);if(c[1])for(d=h(a,q(b)).firstChild;d;)x.call(e,d),d=d.nextSibling;else{if(d=q(b).getElementById(c[2]),!d)return e;if(d.id!==c[2])return e.find(a);e.length=1,e[0]=d}}else this.add(a,!1);return e},toArray:function(){return c.toArray(this)},add:function(a,b){var c,d,e=this;if(f(a))return e.add(l(a));if(b!==!1)for(c=l.unique(e.toArray().concat(l.makeArray(a))),e.length=c.length,d=0;d1&&(B[a]||(e=l.unique(e)),0===a.indexOf("parents")&&(e=e.reverse())),e=l(e),c?e.filter(c):e}}),o({parentsUntil:function(a,b){return r(a,"parentNode",b)},nextUntil:function(a,b){return s(a,"nextSibling",1,b).slice(1)},prevUntil:function(a,b){return s(a,"previousSibling",1,b).slice(1)}},function(a,b){l.fn[a]=function(c,d){var e=this,f=[];return e.each(function(){var a=b.call(f,this,c,f);a&&(l.isArray(a)?f.push.apply(f,a):f.push(a))}),this.length>1&&(f=l.unique(f),0!==a.indexOf("parents")&&"prevUntil"!==a||(f=f.reverse())),f=l(f),d?f.filter(d):f}}),l.fn.is=function(a){return!!a&&this.filter(a).length>0},l.fn.init.prototype=l.fn,l.overrideDefaults=function(a){function b(d,e){return c=c||a(),0===arguments.length&&(d=c.element),e||(e=c.context),new b.fn.init(d,e)}var c;return l.extend(b,this),b},d.ie&&d.ie<8&&(u(G,"get",{maxlength:function(a){var b=a.maxLength;return 2147483647===b?v:b},size:function(a){var b=a.size;return 20===b?v:b},"class":function(a){return a.className},style:function(a){var b=a.style.cssText;return 0===b.length?v:b}}),u(G,"set",{"class":function(a,b){a.className=b},style:function(a,b){a.style.cssText=b}})),d.ie&&d.ie<9&&(F["float"]="styleFloat",u(H,"set",{opacity:function(a,b){var c=a.style;null===b||""===b?c.removeAttribute("filter"):(c.zoom=1,c.filter="alpha(opacity="+100*b+")")}})),l.attrHooks=G,l.cssHooks=H,l}),g("b",[],function(){return function(a,b){function c(a,b,c,d){function e(a){return a=parseInt(a,10).toString(16),a.length>1?a:"0"+a}return"#"+e(b)+e(c)+e(d)}var d,e,f,g,h=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,j=/\s*([^:]+):\s*([^;]+);?/g,k=/\s+$/,l={},m="\ufeff";for(a=a||{},b&&(f=b.getValidStyles(),g=b.getInvalidStyles()),e=("\\\" \\' \\; \\: ; : "+m).split(" "),d=0;d-1&&c||(w[a+b]=d==-1?i[0]:i.join(" "),delete w[a+"-top"+b],delete w[a+"-right"+b],delete w[a+"-bottom"+b],delete w[a+"-left"+b])}}function f(a){var b,c=w[a];if(c){for(c=c.split(" "),b=c.length;b--;)if(c[b]!==c[0])return!1;return w[a]=c[0],!0}}function g(a,b,c,d){f(b)&&f(c)&&f(d)&&(w[a]=w[b]+" "+w[c]+" "+w[d],delete w[b],delete w[c],delete w[d])}function n(a){return v=!0,l[a]}function o(a,b){return v&&(a=a.replace(/\uFEFF[0-9]/g,function(a){return l[a]})),b||(a=a.replace(/\\([\'\";:])/g,"$1")),a}function p(a){return String.fromCharCode(parseInt(a.slice(1),16))}function q(a){return a.replace(/\\[0-9a-f]+/gi,p)}function r(b,c,d,e,f,g){if(f=f||g)return f=o(f),"'"+f.replace(/\'/g,"\\'")+"'";if(c=o(c||d||e),!a.allow_script_urls){var h=c.replace(/[\s\r\n]+/g,"");if(/(java|vb)script:/i.test(h))return"";if(!a.allow_svg_data_urls&&/^data:image\/svg/i.test(h))return""}return x&&(c=x.call(y,c,"style")),"url('"+c.replace(/\'/g,"\\'")+"')"}var s,t,u,v,w={},x=a.url_converter,y=a.url_converter_scope||this;if(b){for(b=b.replace(/[\u0000-\u001F]/g,""),b=b.replace(/\\[\"\';:\uFEFF]/g,n).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(a){return a.replace(/[;:]/g,n)});s=j.exec(b);)if(j.lastIndex=s.index+s[0].length,t=s[1].replace(k,"").toLowerCase(),u=s[2].replace(k,""),t&&u){if(t=q(t),u=q(u),t.indexOf(m)!==-1||t.indexOf('"')!==-1)continue;if(!a.allow_script_urls&&("behavior"==t||/expression\s*\(|\/\*|\*\//.test(u)))continue;"font-weight"===t&&"700"===u?u="bold":"color"!==t&&"background-color"!==t||(u=u.toLowerCase()),u=u.replace(h,c),u=u.replace(i,r),w[t]=v?o(u,!0):u}e("border","",!0),e("border","-width"),e("border","-color"),e("border","-style"),e("padding",""),e("margin",""),g("border","border-width","border-style","border-color"),"medium none"===w.border&&delete w.border,"none"===w["border-image"]&&delete w["border-image"]}return w},serialize:function(a,b){function c(b){var c,d,e,g;if(c=f[b])for(d=0,e=c.length;d0?" ":"")+b+": "+g+";")}function d(a,b){var c;return c=g["*"],(!c||!c[a])&&(c=g[b],!c||!c[a])}var e,h,i="";if(b&&f)c("*"),c(b);else for(e in a)h=a[e],!h||g&&!d(e,b)||(i+=(i.length>0?" ":"")+e+": "+h+";");return i}}}}),g("c",[],function(){return function(a,b){function c(a,c,d,e){var f,g;if(a){if(!e&&a[c])return a[c];if(a!=b){if(f=a[d])return f;for(g=a.parentNode;g&&g!=b;g=g.parentNode)if(f=g[d])return f}}}function d(a,c,d,e){var f,g,h;if(a){if(f=a[d],b&&f===b)return;if(f){if(!e)for(h=f[c];h;h=h[c])if(!h[c])return h;return f}if(g=a.parentNode,g&&g!==b)return g}}var e=a;this.current=function(){return e},this.next=function(a){return e=c(e,"firstChild","nextSibling",a)},this.prev=function(a){return e=c(e,"lastChild","previousSibling",a)},this.prev2=function(a){return e=d(e,"lastChild","previousSibling",a)}}}),g("d",["9"],function(a){function b(a){var b;return b=document.createElement("div"),b.innerHTML=a,b.textContent||b.innerText||a}function c(a,b){var c,d,f,g={};if(a){for(a=a.split(","),b=b||10,c=0;c\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,i=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,j=/[<>&\"\']/g,k=/&#([a-z0-9]+);?|&([a-z0-9]+);/gi,l={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};e={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},f={"<":"<",">":">","&":"&",""":'"',"'":"'"},d=c("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var m={encodeRaw:function(a,b){return a.replace(b?h:i,function(a){return e[a]||a})},encodeAllRaw:function(a){return(""+a).replace(j,function(a){return e[a]||a})},encodeNumeric:function(a,b){return a.replace(b?h:i,function(a){return a.length>1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":e[a]||"&#"+a.charCodeAt(0)+";"})},encodeNamed:function(a,b,c){return c=c||d,a.replace(b?h:i,function(a){return e[a]||c[a]||a})},getEncodeFunc:function(a,b){function f(a,c){return a.replace(c?h:i,function(a){return void 0!==e[a]?e[a]:void 0!==b[a]?b[a]:a.length>1?"&#"+(1024*(a.charCodeAt(0)-55296)+(a.charCodeAt(1)-56320)+65536)+";":"&#"+a.charCodeAt(0)+";"})}function j(a,c){return m.encodeNamed(a,c,b)}return b=c(b)||d,a=g(a.replace(/\+/g,",")),a.named&&a.numeric?f:a.named?b?j:m.encodeNamed:a.numeric?m.encodeNumeric:m.encodeRaw},decode:function(a){return a.replace(k,function(a,c){return c?(c="x"===c.charAt(0).toLowerCase()?parseInt(c.substr(1),16):parseInt(c,10),c>65535?(c-=65536,String.fromCharCode(55296+(c>>10),56320+(1023&c))):l[c]||String.fromCharCode(c)):f[a]||d[a]||b(a)})}};return m}),g("1h",["9"],function(a){function b(c){function d(){return J.createDocumentFragment()}function e(a,b){x(N,a,b)}function f(a,b){x(O,a,b)}function g(a){e(a.parentNode,U(a))}function h(a){e(a.parentNode,U(a)+1)}function i(a){f(a.parentNode,U(a))}function j(a){f(a.parentNode,U(a)+1)}function k(a){a?(I[R]=I[Q],I[S]=I[P]):(I[Q]=I[R],I[P]=I[S]),I.collapsed=N}function l(a){g(a),j(a)}function m(a){e(a,0),f(a,1===a.nodeType?a.childNodes.length:a.nodeValue.length)}function n(a,b){var c=I[Q],d=I[P],e=I[R],f=I[S],g=b.startContainer,h=b.startOffset,i=b.endContainer,j=b.endOffset;return 0===a?w(c,d,g,h):1===a?w(e,f,g,h):2===a?w(e,f,i,j):3===a?w(c,d,i,j):void 0}function o(){y(M)}function p(){return y(K)}function q(){return y(L)}function r(a){var b,d,e=this[Q],f=this[P];3!==e.nodeType&&4!==e.nodeType||!e.nodeValue?(e.childNodes.length>0&&(d=e.childNodes[f]),d?e.insertBefore(a,d):3==e.nodeType?c.insertAfter(a,e):e.appendChild(a)):f?f>=e.nodeValue.length?c.insertAfter(a,e):(b=e.splitText(f),e.parentNode.insertBefore(a,b)):e.parentNode.insertBefore(a,e)}function s(a){var b=I.extractContents();I.insertNode(a),a.appendChild(b),I.selectNode(a)}function t(){return T(new b(c),{startContainer:I[Q],startOffset:I[P],endContainer:I[R],endOffset:I[S],collapsed:I.collapsed,commonAncestorContainer:I.commonAncestorContainer})}function u(a,b){var c;if(3==a.nodeType)return a;if(b<0)return a;for(c=a.firstChild;c&&b>0;)--b,c=c.nextSibling;return c?c:a}function v(){return I[Q]==I[R]&&I[P]==I[S]}function w(a,b,d,e){var f,g,h,i,j,k;if(a==d)return b==e?0:b0&&I.collapse(a):I.collapse(a),I.collapsed=v(),I.commonAncestorContainer=c.findCommonAncestor(I[Q],I[R])}function y(a){var b,c,d,e,f,g,h,i=0,j=0;if(I[Q]==I[R])return z(a);for(b=I[R],c=b.parentNode;c;b=c,c=c.parentNode){if(c==I[Q])return A(b,a);++i}for(b=I[Q],c=b.parentNode;c;b=c,c=c.parentNode){if(c==I[R])return B(b,a);++j}for(d=j-i,e=I[Q];d>0;)e=e.parentNode,d--;for(f=I[R];d<0;)f=f.parentNode,d++;for(g=e.parentNode,h=f.parentNode;g!=h;g=g.parentNode,h=h.parentNode)e=g,f=h;return C(e,f,a)}function z(a){var b,c,e,f,g,h,i,j,k;if(a!=M&&(b=d()),I[P]==I[S])return b;if(3==I[Q].nodeType){if(c=I[Q].nodeValue,e=c.substring(I[P],I[S]),a!=L&&(f=I[Q],j=I[P],k=I[S]-I[P],0===j&&k>=f.nodeValue.length-1?f.parentNode.removeChild(f):f.deleteData(j,k),I.collapse(N)),a==M)return;return e.length>0&&b.appendChild(J.createTextNode(e)),b}for(f=u(I[Q],I[P]),g=I[S]-I[P];f&&g>0;)h=f.nextSibling,i=G(f,a),b&&b.appendChild(i),--g,f=h;return a!=L&&I.collapse(N),b}function A(a,b){var c,e,f,g,h,i;if(b!=M&&(c=d()),e=D(a,b),c&&c.appendChild(e),f=U(a),g=f-I[P],g<=0)return b!=L&&(I.setEndBefore(a),I.collapse(O)),c;for(e=a.previousSibling;g>0;)h=e.previousSibling,i=G(e,b),c&&c.insertBefore(i,c.firstChild),--g,e=h;return b!=L&&(I.setEndBefore(a),I.collapse(O)),c}function B(a,b){var c,e,f,g,h,i;for(b!=M&&(c=d()),f=E(a,b),c&&c.appendChild(f),e=U(a),++e,g=I[S]-e,f=a.nextSibling;f&&g>0;)h=f.nextSibling,i=G(f,b),c&&c.appendChild(i),--g,f=h;return b!=L&&(I.setStartAfter(a),I.collapse(N)),c}function C(a,b,c){var e,f,g,h,i,j,k;for(c!=M&&(f=d()),e=E(a,c),f&&f.appendChild(e),g=U(a),h=U(b),++g,i=h-g,j=a.nextSibling;i>0;)k=j.nextSibling,e=G(j,c),f&&f.appendChild(e),j=k,--i;return e=D(b,c),f&&f.appendChild(e),c!=L&&(I.setStartAfter(a),I.collapse(N)),f}function D(a,b){var c,d,e,f,g,h=u(I[R],I[S]-1),i=h!=I[R];if(h==a)return F(h,i,O,b);for(c=h.parentNode,d=F(c,O,O,b);c;){for(;h;)e=h.previousSibling,f=F(h,i,O,b),b!=M&&d.insertBefore(f,d.firstChild),i=N,h=e;if(c==a)return d;h=c.previousSibling,c=c.parentNode,g=F(c,O,O,b),b!=M&&g.appendChild(d),d=g}}function E(a,b){var c,d,e,f,g,h=u(I[Q],I[P]),i=h!=I[Q];if(h==a)return F(h,i,N,b);for(c=h.parentNode,d=F(c,O,N,b);c;){for(;h;)e=h.nextSibling,f=F(h,i,N,b),b!=M&&d.appendChild(f),i=N,h=e;if(c==a)return d;h=c.nextSibling,c=c.parentNode,g=F(c,O,N,b),b!=M&&g.appendChild(d),d=g}}function F(a,b,d,e){var f,g,h,i,j;if(b)return G(a,e);if(3==a.nodeType){if(f=a.nodeValue,d?(i=I[P],g=f.substring(i),h=f.substring(0,i)):(i=I[S],g=f.substring(0,i),h=f.substring(i)),e!=L&&(a.nodeValue=h),e==M)return;return j=c.clone(a,O),j.nodeValue=g,j}if(e!=M)return c.clone(a,O)}function G(a,b){return b!=M?b==L?c.clone(a,N):a:void a.parentNode.removeChild(a)}function H(){return c.create("body",null,q()).outerText}var I=this,J=c.doc,K=0,L=1,M=2,N=!0,O=!1,P="startOffset",Q="startContainer",R="endContainer",S="endOffset",T=a.extend,U=c.nodeIndex;return T(I,{startContainer:J,startOffset:0,endContainer:J,endOffset:0,collapsed:N,commonAncestorContainer:J,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:e,setEnd:f,setStartBefore:g,setStartAfter:h,setEndBefore:i,setEndAfter:j,collapse:k,selectNode:l,selectNodeContents:m,compareBoundaryPoints:n,deleteContents:o,extractContents:p,cloneContents:q,insertNode:r,surroundContents:s,cloneRange:t,toStringIE:H}),I}return b.prototype.toString=function(){return this.toStringIE()},b}),h("4r",Array),h("4s",Error),g("3t",["4r","4s"],function(a,b){var c=function(){},d=function(a,b){return function(){return a(b.apply(null,arguments))}},e=function(a){return function(){return a}},f=function(a){return a},g=function(a,b){return a===b},h=function(b){for(var c=new a(arguments.length-1),d=1;d-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e=b.length&&c(d)}};0===b.length?c([]):a.each(b,function(a,b){a.get(f(b))})})};return{par:b}}),g("3v",["3s","3u","4w"],function(a,b,c){var d=function(a){return c.par(a,b.nu)},e=function(b,c){var e=a.map(b,c);return d(e)},f=function(a,b){return function(c){return b(c).bind(a)}};return{par:d,mapM:e,compose:f}}),g("3w",["3t","4q"],function(a,b){var c=function(d){var e=function(a){return d===a},f=function(a){return c(d)},g=function(a){return c(d)},h=function(a){return c(a(d))},i=function(a){a(d)},j=function(a){return a(d)},k=function(a,b){return b(d)},l=function(a){return a(d)},m=function(a){return a(d)},n=function(){return b.some(d)};return{is:e,isValue:a.constant(!0),isError:a.constant(!1),getOr:a.constant(d),getOrThunk:a.constant(d),getOrDie:a.constant(d),or:f,orThunk:g,fold:k,map:h,each:i,bind:j,exists:l,forall:m,toOption:n}},d=function(c){var e=function(a){return a()},f=function(){return a.die(c)()},g=function(a){return a},h=function(a){return a()},i=function(a){return d(c)},j=function(a){return d(c)},k=function(a,b){return a(c)};return{is:a.constant(!1),isValue:a.constant(!1),isError:a.constant(!0),getOr:a.identity,getOrThunk:e,getOrDie:f,or:g,orThunk:h,fold:k,map:i,each:a.noop,bind:j,exists:a.constant(!1),forall:a.constant(!0),toOption:b.none}};return{value:c,error:d}}),g("1i",["3s","3t","3u","3v","3w","5","9"],function(a,b,c,d,e,f,g){"use strict";return function(h,i){function j(a){h.getElementsByTagName("head")[0].appendChild(a)}function k(a,b,c){function d(){for(var a=t.passed,b=a.length;b--;)a[b]();t.status=2,t.passed=[],t.failed=[]}function e(){for(var a=t.failed,b=a.length;b--;)a[b]();t.status=3,t.passed=[],t.failed=[]}function i(){var a=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(a&&a[1]<536)}function k(a,b){a()||((new Date).getTime()-s0)return r=h.createElement("style"), r.textContent='@import "'+a+'"',p(),void j(r);o()}j(q),q.href=a}}var l,m=0,n={};i=i||{},l=i.maxLoadTime||5e3;var o=function(a){return c.nu(function(c){k(a,b.compose(c,b.constant(e.value(a))),b.compose(c,b.constant(e.error(a))))})},p=function(a){return a.fold(b.identity,b.identity)},q=function(b,c,e){d.par(a.map(b,o)).get(function(b){var d=a.partition(b,function(a){return a.isValue()});d.fail.length>0?e(d.fail.map(p)):c(d.pass.map(p))})};return{load:k,loadAll:q}}}),g("j",["9"],function(a){function b(b,c){return b=a.trim(b),b?b.split(c||" "):[]}function c(a){function c(a,c,d){function e(a,b){var c,d,e={};for(c=0,d=a.length;c