diff options
| author | Paramjit Singh Sahota <psa@tinyerp.com> | 2013-12-24 11:01:25 +0530 |
|---|---|---|
| committer | Paramjit Singh Sahota <psa@tinyerp.com> | 2013-12-24 11:01:25 +0530 |
| commit | 18d8368ee11eef0a74bacdb8f293414331bfa8da (patch) | |
| tree | fc21df70cbd2901396c2bcf2fee0b52d750abd43 /addons/website/static/lib/ckeditor/plugins | |
| parent | 5900672160c2bd5ae1d9257f20dbb5c51a193996 (diff) | |
| parent | 123185757f51ee7e146d7295864556999d2a6938 (diff) | |
[MERGE] Merged lp:~openerp-dev/openobject-addons/trunk-website-al
bzr revid: psa@tinyerp.com-20131224053125-3lrogsrgd3ccp0i6
Diffstat (limited to 'addons/website/static/lib/ckeditor/plugins')
368 files changed, 0 insertions, 51304 deletions
diff --git a/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js b/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js deleted file mode 100644 index 770ea36c604..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'a11yHelp', function( editor ) { - var lang = editor.lang.a11yhelp, - id = CKEDITOR.tools.getNextId(); - - // CharCode <-> KeyChar. - var keyMap = { - 8: "BACKSPACE", - 9: "TAB", - 13: "ENTER", - 16: "SHIFT", - 17: "CTRL", - 18: "ALT", - 19: "PAUSE", - 20: "CAPSLOCK", - 27: "ESCAPE", - 33: "PAGE UP", - 34: "PAGE DOWN", - 35: "END", - 36: "HOME", - 37: "LEFT ARROW", - 38: "UP ARROW", - 39: "RIGHT ARROW", - 40: "DOWN ARROW", - 45: "INSERT", - 46: "DELETE", - 91: "LEFT WINDOW KEY", - 92: "RIGHT WINDOW KEY", - 93: "SELECT KEY", - 96: "NUMPAD 0", - 97: "NUMPAD 1", - 98: "NUMPAD 2", - 99: "NUMPAD 3", - 100: "NUMPAD 4", - 101: "NUMPAD 5", - 102: "NUMPAD 6", - 103: "NUMPAD 7", - 104: "NUMPAD 8", - 105: "NUMPAD 9", - 106: "MULTIPLY", - 107: "ADD", - 109: "SUBTRACT", - 110: "DECIMAL POINT", - 111: "DIVIDE", - 112: "F1", - 113: "F2", - 114: "F3", - 115: "F4", - 116: "F5", - 117: "F6", - 118: "F7", - 119: "F8", - 120: "F9", - 121: "F10", - 122: "F11", - 123: "F12", - 144: "NUM LOCK", - 145: "SCROLL LOCK", - 186: "SEMI-COLON", - 187: "EQUAL SIGN", - 188: "COMMA", - 189: "DASH", - 190: "PERIOD", - 191: "FORWARD SLASH", - 192: "GRAVE ACCENT", - 219: "OPEN BRACKET", - 220: "BACK SLASH", - 221: "CLOSE BRAKET", - 222: "SINGLE QUOTE" - }; - - // Modifier keys override. - keyMap[ CKEDITOR.ALT ] = 'ALT'; - keyMap[ CKEDITOR.SHIFT ] = 'SHIFT'; - keyMap[ CKEDITOR.CTRL ] = 'CTRL'; - - // Sort in desc. - var modifiers = [ CKEDITOR.ALT, CKEDITOR.SHIFT, CKEDITOR.CTRL ]; - - function representKeyStroke( keystroke ) { - var quotient, modifier, - presentation = []; - - for ( var i = 0; i < modifiers.length; i++ ) { - modifier = modifiers[ i ]; - quotient = keystroke / modifiers[ i ]; - if ( quotient > 1 && quotient <= 2 ) { - keystroke -= modifier; - presentation.push( keyMap[ modifier ] ); - } - } - - presentation.push( keyMap[ keystroke ] || String.fromCharCode( keystroke ) ); - - return presentation.join( '+' ); - } - - var variablesPattern = /\$\{(.*?)\}/g; - - var replaceVariables = (function() { - // Swaps keystrokes with their commands in object literal. - // This makes searching keystrokes by command much easier. - var keystrokesByCode = editor.keystrokeHandler.keystrokes, - keystrokesByName = {}; - - for ( var i in keystrokesByCode ) - keystrokesByName[ keystrokesByCode[ i ] ] = i; - - return function( match, name ) { - // Return the keystroke representation or leave match untouched - // if there's no keystroke for such command. - return keystrokesByName[ name ] ? representKeyStroke( keystrokesByName[ name ] ) : match; - }; - })(); - - // Create the help list directly from lang file entries. - function buildHelpContents() { - var pageTpl = '<div class="cke_accessibility_legend" role="document" aria-labelledby="' + id + '_arialbl" tabIndex="-1">%1</div>' + - '<span id="' + id + '_arialbl" class="cke_voice_label">' + lang.contents + ' </span>', - sectionTpl = '<h1>%1</h1><dl>%2</dl>', - itemTpl = '<dt>%1</dt><dd>%2</dd>'; - - var pageHtml = [], - sections = lang.legend, - sectionLength = sections.length; - - for ( var i = 0; i < sectionLength; i++ ) { - var section = sections[ i ], - sectionHtml = [], - items = section.items, - itemsLength = items.length; - - for ( var j = 0; j < itemsLength; j++ ) { - var item = items[ j ], - itemLegend = item.legend.replace( variablesPattern, replaceVariables ); - - // (#9765) If some commands haven't been replaced in the legend, - // most likely their keystrokes are unavailable and we shouldn't include - // them in our help list. - if ( itemLegend.match( variablesPattern ) ) - continue; - - sectionHtml.push( itemTpl.replace( '%1', item.name ).replace( '%2', itemLegend ) ); - } - - pageHtml.push( sectionTpl.replace( '%1', section.name ).replace( '%2', sectionHtml.join( '' ) ) ); - } - - return pageTpl.replace( '%1', pageHtml.join( '' ) ); - } - - return { - title: lang.title, - minWidth: 600, - minHeight: 400, - contents: [ - { - id: 'info', - label: editor.lang.common.generalTab, - expand: true, - elements: [ - { - type: 'html', - id: 'legends', - style: 'white-space:normal;', - focus: function() { this.getElement().focus(); }, - html: buildHelpContents() + '<style type="text/css">' + - '.cke_accessibility_legend' + - '{' + - 'width:600px;' + - 'height:400px;' + - 'padding-right:5px;' + - 'overflow-y:auto;' + - 'overflow-x:hidden;' + - '}' + - // Some adjustments are to be done for IE6 and Quirks to work "properly" (#5757) - '.cke_browser_quirks .cke_accessibility_legend,' + - '.cke_browser_ie6 .cke_accessibility_legend' + - '{' + - 'height:390px' + - '}' + - // Override non-wrapping white-space rule in reset css. - '.cke_accessibility_legend *' + - '{' + - 'white-space:normal;' + - '}' + - '.cke_accessibility_legend h1' + - '{' + - 'font-size: 20px;' + - 'border-bottom: 1px solid #AAA;' + - 'margin: 5px 0px 15px;' + - '}' + - '.cke_accessibility_legend dl' + - '{' + - 'margin-left: 5px;' + - '}' + - '.cke_accessibility_legend dt' + - '{' + - 'font-size: 13px;' + - 'font-weight: bold;' + - '}' + - '.cke_accessibility_legend dd' + - '{' + - 'margin:10px' + - '}' + - '</style>' - } - ] - } - ], - buttons: [ CKEDITOR.dialog.cancelButton ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/lang/en.js b/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/lang/en.js deleted file mode 100644 index 1df642771b5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/a11yhelp/dialogs/lang/en.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'a11yhelp', 'en', { - title: 'Accessibility Instructions', - contents: 'Help Contents. To close this dialog press ESC.', - legend: [ - { - name: 'General', - items: [ - { - name: 'Editor Toolbar', - legend: 'Press ${toolbarFocus} to navigate to the toolbar. ' + - 'Move to the next and previous toolbar group with TAB and SHIFT-TAB. ' + - 'Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. ' + - 'Press SPACE or ENTER to activate the toolbar button.' - }, - - { - name: 'Editor Dialog', - legend: 'Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. ' + - 'For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. ' + - 'Then move to next tab with TAB OR RIGTH ARROW. ' + - 'Move to previous tab with SHIFT + TAB or LEFT ARROW. ' + - 'Press SPACE or ENTER to select the tab page.' - }, - - { - name: 'Editor Context Menu', - legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. ' + - 'Then move to next menu option with TAB or DOWN ARROW. ' + - 'Move to previous option with SHIFT+TAB or UP ARROW. ' + - 'Press SPACE or ENTER to select the menu option. ' + - 'Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. ' + - 'Go back to parent menu item with ESC or LEFT ARROW. ' + - 'Close context menu with ESC.' - }, - - { - name: 'Editor List Box', - legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. ' + - 'Move to previous list item with SHIFT + TAB or UP ARROW. ' + - 'Press SPACE or ENTER to select the list option. ' + - 'Press ESC to close the list-box.' - }, - - { - name: 'Editor Element Path Bar', - legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. ' + - 'Move to next element button with TAB or RIGHT ARROW. ' + - 'Move to previous button with SHIFT+TAB or LEFT ARROW. ' + - 'Press SPACE or ENTER to select the element in editor.' - } - ] - }, - { - name: 'Commands', - items: [ - { - name: ' Undo command', - legend: 'Press ${undo}' - }, - { - name: ' Redo command', - legend: 'Press ${redo}' - }, - { - name: ' Bold command', - legend: 'Press ${bold}' - }, - { - name: ' Italic command', - legend: 'Press ${italic}' - }, - { - name: ' Underline command', - legend: 'Press ${underline}' - }, - { - name: ' Link command', - legend: 'Press ${link}' - }, - { - name: ' Toolbar Collapse command', - legend: 'Press ${toolbarCollapse}' - }, - { - name: ' Access previous focus space command', - legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, ' + - 'for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' - }, - { - name: ' Access next focus space command', - legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, ' + - 'for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' - }, - { - name: ' Accessibility Help', - legend: 'Press ${a11yHelp}' - } - ] - } - ] -}); diff --git a/addons/website/static/lib/ckeditor/plugins/a11yhelp/plugin.js b/addons/website/static/lib/ckeditor/plugins/a11yhelp/plugin.js deleted file mode 100644 index 556c9672bcc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/a11yhelp/plugin.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Plugin definition for the a11yhelp, which provides a dialog - * with accessibility related help. - */ - -(function() { - var pluginName = 'a11yhelp', - commandName = 'a11yHelp'; - - CKEDITOR.plugins.add( pluginName, { - requires: 'dialog', - - // List of available localizations. - availableLangs: { ar:1,bg:1,ca:1,cs:1,cy:1,da:1,de:1,el:1,en:1,eo:1,es:1,et:1,fa:1,fi:1,fr:1,'fr-ca':1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,it:1,ja:1,km:1,ku:1,lt:1,lv:1,mk:1,mn:1,nb:1,nl:1,no:1,pl:1,pt:1,'pt-br':1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,sr:1,'sr-latn':1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,'zh-cn':1 }, - - init: function( editor ) { - var plugin = this; - editor.addCommand( commandName, { - exec: function() { - var langCode = editor.langCode; - langCode = - plugin.availableLangs[ langCode ] ? langCode : - plugin.availableLangs[ langCode.replace( /-.*/, '' ) ] ? langCode.replace( /-.*/, '' ) : - 'en'; - - CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( plugin.path + 'dialogs/lang/' + langCode + '.js' ), function() { - editor.lang.a11yhelp = plugin.langEntries[ langCode ]; - editor.openDialog( commandName ); - }); - }, - modes: { wysiwyg:1,source:1 }, - readOnly: 1, - canUndo: false - }); - - editor.setKeystroke( CKEDITOR.ALT + 48 /*0*/, 'a11yHelp' ); - CKEDITOR.dialog.add( commandName, this.path + 'dialogs/a11yhelp.js' ); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/about/dialogs/about.js b/addons/website/static/lib/ckeditor/plugins/about/dialogs/about.js deleted file mode 100644 index d68c88bce9f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/dialogs/about.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'about', function( editor ) { - var lang = editor.lang.about, - imagePath = CKEDITOR.plugins.get( 'about' ).path + 'dialogs/' + ( CKEDITOR.env.hidpi ? 'hidpi/' : '' ) + 'logo_ckeditor.png'; - - return { - title: CKEDITOR.env.ie ? lang.dlgTitle : lang.title, - minWidth: 390, - minHeight: 230, - contents: [ - { - id: 'tab1', - label: '', - title: '', - expand: true, - padding: 0, - elements: [ - { - type: 'html', - html: '<style type="text/css">' + - '.cke_about_container' + - '{' + - 'color:#000 !important;' + - 'padding:10px 10px 0;' + - 'margin-top:5px' + - '}' + - '.cke_about_container p' + - '{' + - 'margin: 0 0 10px;' + - '}' + - '.cke_about_container .cke_about_logo' + - '{' + - 'height:81px;' + - 'background-color:#fff;' + - 'background-image:url(' + imagePath + ');' + - ( CKEDITOR.env.hidpi ? 'background-size:163px 58px;' : '' ) + - 'background-position:center; ' + - 'background-repeat:no-repeat;' + - 'margin-bottom:10px;' + - '}' + - '.cke_about_container a' + - '{' + - 'cursor:pointer !important;' + - 'color:#00B2CE !important;' + - 'text-decoration:underline !important;' + - '}' + - '</style>' + - '<div class="cke_about_container">' + - '<div class="cke_about_logo"></div>' + - '<p>' + - 'CKEditor ' + CKEDITOR.version + ' (revision ' + CKEDITOR.revision + ')<br>' + - '<a href="http://ckeditor.com/">http://ckeditor.com</a>' + - '</p>' + - '<p>' + - lang.help.replace( '$1', '<a href="http://docs.ckeditor.com/user">' + lang.userGuide + '</a>' ) + - '</p>' + - '<p>' + - lang.moreInfo + '<br>' + - '<a href="http://ckeditor.com/about/license">http://ckeditor.com/about/license</a>' + - '</p>' + - '<p>' + - lang.copy.replace( '$1', '<a href="http://cksource.com/">CKSource</a> - Frederico Knabben' ) + - '</p>' + - '</div>' - } - ] - } - ], - buttons: [ CKEDITOR.dialog.cancelButton ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png b/addons/website/static/lib/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png Binary files differdeleted file mode 100644 index 10cc7368ad1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/about/dialogs/logo_ckeditor.png b/addons/website/static/lib/ckeditor/plugins/about/dialogs/logo_ckeditor.png Binary files differdeleted file mode 100644 index f186eb87a09..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/dialogs/logo_ckeditor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/about/icons/about.png b/addons/website/static/lib/ckeditor/plugins/about/icons/about.png Binary files differdeleted file mode 100644 index a087ac15918..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/icons/about.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/about/icons/hidpi/about.png b/addons/website/static/lib/ckeditor/plugins/about/icons/hidpi/about.png Binary files differdeleted file mode 100644 index 8cc0e9fb2c1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/icons/hidpi/about.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/about/lang/en.js b/addons/website/static/lib/ckeditor/plugins/about/lang/en.js deleted file mode 100644 index 316efaea785..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/lang/en.js +++ /dev/null @@ -1,12 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'about', 'en', { - copy: 'Copyright © $1. All rights reserved.', - dlgTitle: 'About CKEditor', - help: 'Check $1 for help.', - moreInfo: 'For licensing information please visit our web site:', - title: 'About CKEditor', - userGuide: 'CKEditor User\'s Guide' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/about/plugin.js b/addons/website/static/lib/ckeditor/plugins/about/plugin.js deleted file mode 100644 index d63fe8ff5df..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/about/plugin.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'about', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'about', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var command = editor.addCommand( 'about', new CKEDITOR.dialogCommand( 'about' ) ); - command.modes = { wysiwyg:1,source:1 }; - command.canUndo = false; - command.readOnly = 1; - - editor.ui.addButton && editor.ui.addButton( 'About', { - label: editor.lang.about.title, - command: 'about', - toolbar: 'about' - }); - - CKEDITOR.dialog.add( 'about', this.path + 'dialogs/about.js' ); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/adobeair/plugin.js b/addons/website/static/lib/ckeditor/plugins/adobeair/plugin.js deleted file mode 100644 index d022febe6d5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/adobeair/plugin.js +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var eventNameList = [ 'click', 'keydown', 'mousedown', 'keypress', 'mouseover', 'mouseout' ]; - - // Inline event callbacks assigned via innerHTML/outerHTML, such as - // onclick/onmouseover, are ignored in AIR. - // Use DOM2 event listeners to substitue inline handlers instead. - function convertInlineHandlers( container ) { - // TODO: document.querySelectorAll is not supported in AIR. - var children = container.getElementsByTag( '*' ), - count = children.count(), - child; - - for ( var i = 0; i < count; i++ ) { - child = children.getItem( i ); - - (function( node ) { - for ( var j = 0; j < eventNameList.length; j++ ) { - (function( eventName ) { - var inlineEventHandler = node.getAttribute( 'on' + eventName ); - if ( node.hasAttribute( 'on' + eventName ) ) { - node.removeAttribute( 'on' + eventName ); - node.on( eventName, function( evt ) { - var callFunc = /(return\s*)?CKEDITOR\.tools\.callFunction\(([^)]+)\)/.exec( inlineEventHandler ), - hasReturn = callFunc && callFunc[ 1 ], - callFuncArgs = callFunc && callFunc[ 2 ].split( ',' ), - preventDefault = /return false;/.test( inlineEventHandler ); - - if ( callFuncArgs ) { - var nums = callFuncArgs.length, - argName; - - for ( var i = 0; i < nums; i++ ) { - // Trim spaces around param. - callFuncArgs[ i ] = argName = CKEDITOR.tools.trim( callFuncArgs[ i ] ); - - // String form param. - var strPattern = argName.match( /^(["'])([^"']*?)\1$/ ); - if ( strPattern ) { - callFuncArgs[ i ] = strPattern[ 2 ]; - continue; - } - - // Integer form param. - if ( argName.match( /\d+/ ) ) { - callFuncArgs[ i ] = parseInt( argName, 10 ); - continue; - } - - // Speical variables. - switch ( argName ) { - case 'this': - callFuncArgs[ i ] = node.$; - break; - case 'event': - callFuncArgs[ i ] = evt.data.$; - break; - case 'null': - callFuncArgs[ i ] = null; - break; - } - } - - var retval = CKEDITOR.tools.callFunction.apply( window, callFuncArgs ); - if ( hasReturn && retval === false ) - preventDefault = 1; - } - - if ( preventDefault ) - evt.data.preventDefault(); - }); - } - })( eventNameList[ j ] ); - } - })( child ); - } - } - - CKEDITOR.plugins.add( 'adobeair', { - onLoad: function() { - if ( !CKEDITOR.env.air ) - return; - - CKEDITOR.dom.document.prototype.write = CKEDITOR.tools.override( CKEDITOR.dom.document.prototype.write, function( original_write ) { - function appendElement( parent, tagName, fullTag, text ) { - var node = parent.append( tagName ), - attrs = CKEDITOR.htmlParser.fragment.fromHtml( fullTag ).children[ 0 ].attributes; - attrs && node.setAttributes( attrs ); - text && node.append( parent.getDocument().createText( text ) ); - } - - return function( html, mode ) { - // document.write() or document.writeln() fail silently after - // the page load event in Adobe AIR. - // DOM manipulation could be used instead. - if ( this.getBody() ) { - // We're taking the below extra work only because innerHTML - // on <html> element doesn't work as expected. - var doc = this, - head = this.getHead(); - - // Create style nodes for inline css. ( <style> content doesn't applied when setting via innerHTML ) - html = html.replace( /(<style[^>]*>)([\s\S]*?)<\/style>/gi, function( match, startTag, styleText ) { - appendElement( head, 'style', startTag, styleText ); - return ''; - }); - - html = html.replace( /<base\b[^>]*\/>/i, function( match ) { - appendElement( head, 'base', match ); - return ''; - }); - - html = html.replace( /<title>([\s\S]*)<\/title>/i, function( match, title ) { - doc.$.title = title; - return ''; - }); - - // Move the rest of head stuff. - html = html.replace( /<head>([\s\S]*)<\/head>/i, function( headHtml ) { - // Inject the <head> HTML inside a <div>. - // Do that before getDocumentHead because WebKit moves - // <link css> elements to the <head> at this point. - var div = new CKEDITOR.dom.element( 'div', doc ); - div.setHtml( headHtml ); - // Move the <div> nodes to <head>. - div.moveChildren( head ); - return ''; - }); - - html.replace( /(<body[^>]*>)([\s\S]*)(?=$|<\/body>)/i, function( match, startTag, innerHTML ) { - doc.getBody().setHtml( innerHTML ); - var attrs = CKEDITOR.htmlParser.fragment.fromHtml( startTag ).children[ 0 ].attributes; - attrs && doc.getBody().setAttributes( attrs ); - }); - } else - original_write.apply( this, arguments ); - }; - }); - - // Body doesn't get default margin on AIR. - CKEDITOR.addCss( 'body.cke_editable { padding: 8px }' ); - CKEDITOR.ui.on( 'ready', function( evt ) { - var ui = evt.data; - // richcombo, panelbutton and menu - if ( ui._.panel ) { - var panel = ui._.panel._.panel, - holder; - - (function() { - // Adding dom event listeners off-line are not supported in AIR, - // waiting for panel iframe loaded. - if ( !panel.isLoaded ) { - setTimeout( arguments.callee, 30 ); - return; - } - holder = panel._.holder; - convertInlineHandlers( holder ); - })(); - } else if ( ui instanceof CKEDITOR.dialog ) - convertInlineHandlers( ui._.element ); - }); - }, - init: function( editor ) { - if ( !CKEDITOR.env.air ) - return; - - editor.on( 'uiReady', function() { - convertInlineHandlers( editor.container ); - - editor.on( 'elementsPathUpdate', function( evt ) { - convertInlineHandlers( evt.data.space ); - }); - }); - - editor.on( 'contentDom', function() { - // Hyperlinks are enabled in editable documents in Adobe - // AIR. Prevent their click behavior. - editor.document.on( 'click', function( ev ) { - ev.data.preventDefault( true ); - }); - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/ajax/plugin.js b/addons/website/static/lib/ckeditor/plugins/ajax/plugin.js deleted file mode 100644 index cbb32bbbe53..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/ajax/plugin.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Defines the {@link CKEDITOR.ajax} object, which holds ajax methods for - * data loading. - */ - -(function() { - CKEDITOR.plugins.add( 'ajax', { - requires: 'xml' - }); - - /** - * Ajax methods for data loading. - * - * @class - * @singleton - */ - CKEDITOR.ajax = (function() { - var createXMLHttpRequest = function() { - // In IE, using the native XMLHttpRequest for local files may throw - // "Access is Denied" errors. - if ( !CKEDITOR.env.ie || location.protocol != 'file:' ) - try { - return new XMLHttpRequest(); - } catch ( e ) {} - - try { - return new ActiveXObject( 'Msxml2.XMLHTTP' ); - } catch ( e ) {} - try { - return new ActiveXObject( 'Microsoft.XMLHTTP' ); - } catch ( e ) {} - - return null; - }; - - var checkStatus = function( xhr ) { - // HTTP Status Codes: - // 2xx : Success - // 304 : Not Modified - // 0 : Returned when running locally (file://) - // 1223 : IE may change 204 to 1223 (see http://dev.jquery.com/ticket/1450) - - return ( xhr.readyState == 4 && ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status === 0 || xhr.status == 1223 ) ); - }; - - var getResponseText = function( xhr ) { - if ( checkStatus( xhr ) ) - return xhr.responseText; - return null; - }; - - var getResponseXml = function( xhr ) { - if ( checkStatus( xhr ) ) { - var xml = xhr.responseXML; - return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText ); - } - return null; - }; - - var load = function( url, callback, getResponseFn ) { - var async = !!callback; - - var xhr = createXMLHttpRequest(); - - if ( !xhr ) - return null; - - xhr.open( 'GET', url, async ); - - if ( async ) { - // TODO: perform leak checks on this closure. - xhr.onreadystatechange = function() { - if ( xhr.readyState == 4 ) { - callback( getResponseFn( xhr ) ); - xhr = null; - } - }; - } - - xhr.send( null ); - - return async ? '' : getResponseFn( xhr ); - }; - - return { - /** - * Loads data from an URL as plain text. - * - * // Load data synchronously. - * var data = CKEDITOR.ajax.load( 'somedata.txt' ); - * alert( data ); - * - * // Load data asynchronously. - * var data = CKEDITOR.ajax.load( 'somedata.txt', function( data ) { - * alert( data ); - * } ); - * - * @param {String} url The URL from which load data. - * @param {Function} [callback] A callback function to be called on - * data load. If not provided, the data will be loaded - * synchronously. - * @returns {String} The loaded data. For asynchronous requests, an - * empty string. For invalid requests, `null`. - */ - load: function( url, callback ) { - return load( url, callback, getResponseText ); - }, - - /** - * Loads data from an URL as XML. - * - * // Load XML synchronously. - * var xml = CKEDITOR.ajax.loadXml( 'somedata.xml' ); - * alert( xml.getInnerXml( '//' ) ); - * - * // Load XML asynchronously. - * var data = CKEDITOR.ajax.loadXml( 'somedata.xml', function( xml ) { - * alert( xml.getInnerXml( '//' ) ); - * } ); - * - * @param {String} url The URL from which load data. - * @param {Function} [callback] A callback function to be called on - * data load. If not provided, the data will be loaded synchronously. - * @returns {CKEDITOR.xml} An XML object holding the loaded data. For asynchronous requests, an - * empty string. For invalid requests, `null`. - */ - loadXml: function( url, callback ) { - return load( url, callback, getResponseXml ); - } - }; - })(); - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/autogrow/plugin.js b/addons/website/static/lib/ckeditor/plugins/autogrow/plugin.js deleted file mode 100644 index 53c0ab32676..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/autogrow/plugin.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview AutoGrow plugin. - */ - -(function() { - - // Actual content height, figured out by appending check the last element's document position. - function contentHeight( scrollable ) { - var overflowY = scrollable.getStyle( 'overflow-y' ); - - var doc = scrollable.getDocument(); - // Create a temporary marker element. - var marker = CKEDITOR.dom.element.createFromHtml( '<span style="margin:0;padding:0;border:0;clear:both;width:1px;height:1px;display:block;">' + ( CKEDITOR.env.webkit ? ' ' : '' ) + '</span>', doc ); - doc[ CKEDITOR.env.ie ? 'getBody' : 'getDocumentElement' ]().append( marker ); - - var height = marker.getDocumentPosition( doc ).y + marker.$.offsetHeight; - marker.remove(); - scrollable.setStyle( 'overflow-y', overflowY ); - return height; - } - - function getScrollable( editor ) { - var doc = editor.document, - body = doc.getBody(), - htmlElement = doc.getDocumentElement(); - - // Quirks mode overflows body, standards overflows document element - return doc.$.compatMode == 'BackCompat' ? body : htmlElement; - } - - // @param editor - // @param {Number} lastHeight The last height set by autogrow. - // @returns {Number} New height if has been changed, or the passed `lastHeight`. - var resizeEditor = function( editor, lastHeight ) { - if ( !editor.window ) - return null; - - var maximize = editor.getCommand( 'maximize' ); - // Disable autogrow when the editor is maximized .(#6339) - if( maximize && maximize.state == CKEDITOR.TRISTATE_ON ) - return null; - - var scrollable = getScrollable( editor ), - currentHeight = editor.window.getViewPaneSize().height, - newHeight = contentHeight( scrollable ); - - // Additional space specified by user. - newHeight += ( editor.config.autoGrow_bottomSpace || 0 ); - - var min = editor.config.autoGrow_minHeight != undefined ? editor.config.autoGrow_minHeight : 200, - max = editor.config.autoGrow_maxHeight || Infinity; - - newHeight = Math.max( newHeight, min ); - newHeight = Math.min( newHeight, max ); - - // #10196 Do not resize editor if new height is equal - // to the one set by previous resizeEditor() call. - if ( newHeight != currentHeight && lastHeight != newHeight ) { - newHeight = editor.fire( 'autoGrow', { currentHeight: currentHeight, newHeight: newHeight } ).newHeight; - editor.resize( editor.container.getStyle( 'width' ), newHeight, true ); - lastHeight = newHeight; - } - - if ( scrollable.$.scrollHeight > scrollable.$.clientHeight && newHeight < max ) - scrollable.setStyle( 'overflow-y', 'hidden' ); - else - scrollable.removeStyle( 'overflow-y' ); - - return lastHeight; - }; - - CKEDITOR.plugins.add( 'autogrow', { - init: function( editor ) { - - // This feature is available only for themed ui instance. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - return; - - editor.on( 'instanceReady', function() { - - var editable = editor.editable(), - lastHeight; - - // Simply set auto height with div wysiwyg. - if ( editable.isInline() ) - editor.ui.space( 'contents' ).setStyle( 'height', 'auto' ); - // For framed wysiwyg we need to resize the editor. - else - { - editor.addCommand( 'autogrow', { - exec: function( editor ) { - lastHeight = resizeEditor( editor, lastHeight ); - }, - modes:{ wysiwyg:1 }, - readOnly: 1, - canUndo: false, - editorFocus: false - } ); - - var eventsList = { contentDom:1,key:1,selectionChange:1,insertElement:1,mode:1 }; - for ( var eventName in eventsList ) { - editor.on( eventName, function( evt ) { - // Some time is required for insertHtml, and it gives other events better performance as well. - if ( evt.editor.mode == 'wysiwyg' ) { - setTimeout( function() { - lastHeight = resizeEditor( evt.editor, lastHeight ); - // Second pass to make correction upon - // the first resize, e.g. scrollbar. - lastHeight = resizeEditor( evt.editor, lastHeight ); - }, 100 ); - } - }); - } - - // Coordinate with the "maximize" plugin. (#9311) - editor.on( 'afterCommandExec', function( evt ) { - if ( evt.data.name == 'maximize' && evt.editor.mode == 'wysiwyg' ) { - if ( evt.data.command.state == CKEDITOR.TRISTATE_ON ) { - var scrollable = getScrollable( editor ); - scrollable.removeStyle( 'overflow' ); - } - else - lastHeight = resizeEditor( editor, lastHeight ); - } - }); - - editor.config.autoGrow_onStartup && editor.execCommand( 'autogrow' ); - } - }); - } - }); -})(); - -/** - * The minimum height that the editor can reach using the AutoGrow feature. - * - * config.autoGrow_minHeight = 300; - * - * @since 3.4 - * @cfg {Number} [autoGrow_minHeight=200] - * @member CKEDITOR.config - */ - -/** - * The maximum height that the editor can reach using the AutoGrow feature. Zero means unlimited. - * - * config.autoGrow_maxHeight = 400; - * - * @since 3.4 - * @cfg {Number} [autoGrow_maxHeight=0] - * @member CKEDITOR.config - */ - -/** - * Whether to have the auto grow happen on editor creation. - * - * config.autoGrow_onStartup = true; - * - * @since 3.6.2 - * @cfg {Boolean} [autoGrow_onStartup=false] - * @member CKEDITOR.config - */ - -/** - * Extra height in pixel to leave between the bottom boundary of content with document size when auto resizing. - * - * @since 3.6.2 - * @cfg {Number} [autoGrow_bottomSpace=0] - * @member CKEDITOR.config - */ - -/** - * Fired when the AutoGrow plugin is about to change the size of the editor. - * - * @event autogrow - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {Number} data.currentHeight The current height of the editor (before resizing). - * @param {Number} data.newHeight The new height of the editor (after resizing). It can be changed - * to determine a different height value to be used instead. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/bold.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/bold.png Binary files differdeleted file mode 100644 index 5ff84fec0e1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/bold.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/bold.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/bold.png Binary files differdeleted file mode 100644 index 65acb2939a8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/bold.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/italic.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/italic.png Binary files differdeleted file mode 100644 index 2b0f44e7aeb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/italic.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/strike.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/strike.png Binary files differdeleted file mode 100644 index ef045c844b1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/strike.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/subscript.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/subscript.png Binary files differdeleted file mode 100644 index f12f4be2bbe..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/subscript.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/superscript.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/superscript.png Binary files differdeleted file mode 100644 index 4f7b762f739..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/superscript.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/underline.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/underline.png Binary files differdeleted file mode 100644 index 79702f69e3e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/hidpi/underline.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/italic.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/italic.png Binary files differdeleted file mode 100644 index 64d1332c976..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/italic.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/strike.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/strike.png Binary files differdeleted file mode 100644 index 31ea47a1cc9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/strike.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/subscript.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/subscript.png Binary files differdeleted file mode 100644 index bfe5420eba4..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/subscript.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/superscript.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/superscript.png Binary files differdeleted file mode 100644 index a1eb2f1e821..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/superscript.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/underline.png b/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/underline.png Binary files differdeleted file mode 100644 index 1dd0c593c5f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/icons/underline.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/lang/en.js b/addons/website/static/lib/ckeditor/plugins/basicstyles/lang/en.js deleted file mode 100644 index 7a782d0c35d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/lang/en.js +++ /dev/null @@ -1,12 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'basicstyles', 'en', { - bold: 'Bold', - italic: 'Italic', - strike: 'Strike Through', - subscript: 'Subscript', - superscript: 'Superscript', - underline: 'Underline' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/basicstyles/plugin.js b/addons/website/static/lib/ckeditor/plugins/basicstyles/plugin.js deleted file mode 100644 index e206b0e04d9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/basicstyles/plugin.js +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'basicstyles', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'bold,italic,underline,strike,subscript,superscript', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var order = 0; - // All buttons use the same code to register. So, to avoid - // duplications, let's use this tool function. - var addButtonCommand = function( buttonName, buttonLabel, commandName, styleDefiniton ) { - // Disable the command if no definition is configured. - if ( !styleDefiniton ) - return; - - var style = new CKEDITOR.style( styleDefiniton ), - forms = contentForms[ commandName ]; - - // Put the style as the most important form. - forms.unshift( style ); - - // Listen to contextual style activation. - editor.attachStyleStateChange( style, function( state ) { - !editor.readOnly && editor.getCommand( commandName ).setState( state ); - }); - - // Create the command that can be used to apply the style. - editor.addCommand( commandName, new CKEDITOR.styleCommand( style, { - contentForms: forms - } ) ); - - // Register the button, if the button plugin is loaded. - if ( editor.ui.addButton ) { - editor.ui.addButton( buttonName, { - label: buttonLabel, - command: commandName, - toolbar: 'basicstyles,' + ( order += 10 ) - }); - } - }; - - var contentForms = { - bold: [ - 'strong', - 'b', - [ 'span', function( el ) { - var fw = el.styles[ 'font-weight' ]; - return fw == 'bold' || +fw >= 700; - } ] - ], - - italic: [ - 'em', - 'i', - [ 'span', function( el ) { - return el.styles[ 'font-style' ] == 'italic'; - } ] - ], - - underline: [ - 'u', - [ 'span', function( el ) { - return el.styles[ 'text-decoration' ] == 'underline'; - } ] - ], - - strike: [ - 's', - 'strike', - [ 'span', function( el ) { - return el.styles[ 'text-decoration' ] == 'line-through'; - } ] - ], - - subscript: [ - 'sub' - ], - - superscript: [ - 'sup' - ] - }, - config = editor.config, - lang = editor.lang.basicstyles; - - addButtonCommand( 'Bold', lang.bold, 'bold', config.coreStyles_bold ); - addButtonCommand( 'Italic', lang.italic, 'italic', config.coreStyles_italic ); - addButtonCommand( 'Underline', lang.underline, 'underline', config.coreStyles_underline ); - addButtonCommand( 'Strike', lang.strike, 'strike', config.coreStyles_strike ); - addButtonCommand( 'Subscript', lang.subscript, 'subscript', config.coreStyles_subscript ); - addButtonCommand( 'Superscript', lang.superscript, 'superscript', config.coreStyles_superscript ); - - editor.setKeystroke( [ - [ CKEDITOR.CTRL + 66 /*B*/, 'bold' ], - [ CKEDITOR.CTRL + 73 /*I*/, 'italic' ], - [ CKEDITOR.CTRL + 85 /*U*/, 'underline' ] - ] ); - } -}); - -// Basic Inline Styles. - -/** - * The style definition that applies the **bold** style to the text. - * - * config.coreStyles_bold = { element: 'b', overrides: 'strong' }; - * - * config.coreStyles_bold = { - * element: 'span', - * attributes: { 'class': 'Bold' } - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_bold = { element: 'strong', overrides: 'b' }; - -/** - * The style definition that applies the *italics* style to the text. - * - * config.coreStyles_italic = { element: 'i', overrides: 'em' }; - * - * CKEDITOR.config.coreStyles_italic = { - * element: 'span', - * attributes: { 'class': 'Italic' } - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_italic = { element: 'em', overrides: 'i' }; - -/** - * The style definition that applies the <u>underline</u> style to the text. - * - * CKEDITOR.config.coreStyles_underline = { - * element: 'span', - * attributes: { 'class': 'Underline' } - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_underline = { element: 'u' }; - -/** - * The style definition that applies the <strike>strike-through</strike> style to the text. - * - * CKEDITOR.config.coreStyles_strike = { - * element: 'span', - * attributes: { 'class': 'StrikeThrough' }, - * overrides: 'strike' - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_strike = { element: 's', overrides: 'strike' }; - -/** - * The style definition that applies the subscript style to the text. - * - * CKEDITOR.config.coreStyles_subscript = { - * element: 'span', - * attributes: { 'class': 'Subscript' }, - * overrides: 'sub' - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_subscript = { element: 'sub' }; - -/** - * The style definition that applies the superscript style to the text. - * - * CKEDITOR.config.coreStyles_superscript = { - * element: 'span', - * attributes: { 'class': 'Superscript' }, - * overrides: 'sup' - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.coreStyles_superscript = { element: 'sup' }; diff --git a/addons/website/static/lib/ckeditor/plugins/bbcode/dev/bbcode.html b/addons/website/static/lib/ckeditor/plugins/bbcode/dev/bbcode.html deleted file mode 100644 index d9ac869b85b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bbcode/dev/bbcode.html +++ /dev/null @@ -1,172 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license ---> -<html> -<head> - <meta charset="utf-8"> - <title>BBCode plugin playground – CKEditor Sample</title> - <script src="../../../ckeditor.js"></script> - <link href="../../../samples/sample.css" rel="stylesheet"> - <style> -body { - margin: 0; -} - -#editables -{ - float:left; - width: 49% -} - -#preview -{ - width: 50%; - float:right; -} - -#console -{ - height: 300px; - padding: 5px 10px; - border: solid 3px #555; - overflow: auto; - color: #000; - -webkit-transition: border-color 0.5s; - -moz-transition: border-color 0.5s; - -o-transition: border-color 0.5s; - -ms-transition: border-color 0.5s; - transition: border-color 0.5s; - font-family: Monaco, monospace; - font-size: 13px; - white-space: normal; -} - -#console.updated { - border-color: #0B0; -} - </style> -</head> -<body> - <h1 class="samples"> - CKEditor Sample — BBCode plugin playground - </h1> - <div id="main"> - <div class="description"> - <p> - This sample shows how to configure CKEditor to output <a href="http://en.wikipedia.org/wiki/BBCode">BBCode</a> format instead of HTML. - Please note that the editor configuration was modified to reflect what is needed in a BBCode editing environment. - Smiley images, for example, were stripped to the emoticons that are commonly used in some BBCode dialects. - </p> - <p> - Please note that currently there is no standard for the BBCode markup language, so its implementation - for different platforms (message boards, blogs etc.) can vary. This means that before using CKEditor to - output BBCode you may need to adjust the implementation to your own environment. - </p> - <p> - A snippet of the configuration code can be seen below; check the source of this page for - a full definition: - </p> - <pre class="samples"> -CKEDITOR.inline( 'editor1', { - <strong>extraPlugins : 'bbcode',</strong> - <i>(below configurations details omitted:)</i> - toolbar : ..., - fontSize_sizes : ..., - smiley_images : ..., - smiley_descriptions : ... -});</pre> - </div> - - <div id="editables"> - <textarea id="editor1"> -[img]http://a.cksource.com/f/1/img/logo-ckeditor.gif[/img] -"[b]Little Red Riding Hood[/b]" is a famous [url=http://en.wikipedia.org/wiki/Fairy_tale]fairy tale[/url] about a young girl's encounter with a wolf. The story has been changed considerably in its history and subject to numerous modern adaptations and readings. -[list] -[*]Chinese: [i]小紅帽[/i] -[*]Italian: [i]Cappuccetto Rosso[/i] -[*]Spanish: [i]Caperucita Roja[/i] -[/list] -[quote]It is about a girl called [color=#FF0000]Little Red Riding Hood :)[/color], after the red [url=http://en.wikipedia.org/wiki/Hood_%28headgear%29]hooded[/url] [url=http://en.wikipedia.org/wiki/Cape]cape[/url] or [url=http://en.wikipedia.org/wiki/Cloak]cloak[/url] she wears. -The girl walks through the woods to deliver food to her sick grandmother. A wolf wants to eat the girl but is afraid to do so in public. He approaches the girl, and she naïvely tells him where she is going. -He suggests the girl pick some flowers, which she does. In the meantime, he goes to the grandmother's house and gains entry by pretending to be the girl. He swallows the grandmother whole, and waits for the girl, disguised as the grandmother. When the girl arrives, she notices he looks very strange to be her grandma. In most retellings, this eventually culminates with Little Red Riding Hood saying, "My, what big teeth you have!" -To which the wolf replies, "The better to eat you with," and swallows her whole, too.[/quote] -The above version most widely known today is based on the [url=http://en.wikipedia.org/wiki/Brothers_Grimm]Brothers Grimm[/url] variant. - </textarea> - </div> - <div id="preview"> - <h3 for="console">BBCode Output: </h3> - <pre id="console"> - </pre> - </div> - </div> - <div id="footer"> - <hr> - <p> - CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a> - </p> - <p id="copy"> - Copyright © 2003-2013, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico - Knabben. All rights reserved. - </p> - </div> - <script> -(function() { - 'use strict'; - - var editor = CKEDITOR.replace( 'editor1', { - extraPlugins: 'bbcode', - // Remove unused plugins. - removePlugins: 'bidi,dialogadvtab,div,filebrowser,flash,format,forms,horizontalrule,iframe,justify,liststyle,pagebreak,showborders,stylescombo,table,tabletools,templates', - // Width and height are not supported in the BBCode format, so object resizing is disabled. - disableObjectResizing: true, - height: 250, - toolbar: [ - ['Source', '-', 'Save', 'NewPage', '-', 'Undo', 'Redo'], - ['Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'], - ['Link', 'Unlink', 'Image'], - '/', - ['FontSize', 'Bold', 'Italic', 'Underline'], - ['NumberedList', 'BulletedList', '-', 'Blockquote'], - ['TextColor', '-', 'Smiley', 'SpecialChar', '-', 'Maximize'] - ], - // Define font sizes in percent values. - fontSize_sizes: '30/30%;50/50%;100/100%;120/120%;150/150%;200/200%;300/300%', - // Strip CKEditor smileys to those commonly used in BBCode. - smiley_images: [ - 'regular_smile.gif', 'sad_smile.gif', 'wink_smile.gif', 'teeth_smile.gif', 'tounge_smile.gif', - 'embarrassed_smile.gif', 'omg_smile.gif', 'whatchutalkingabout_smile.gif', 'angel_smile.gif', 'shades_smile.gif', - 'cry_smile.gif', 'kiss.gif' - ], - smiley_descriptions: [ - 'smiley', 'sad', 'wink', 'laugh', 'cheeky', 'blush', 'surprise', - 'indecision', 'angel', 'cool', 'crying', 'kiss' - ] - } ); - - function updatePreview() { - var consoleEl = CKEDITOR.document.getById( 'console' ); - consoleEl.addClass( 'updated' ); - setTimeout( function() { consoleEl.removeClass( 'updated' ); }, 500 ); - // IE needs <br>, it doesn't even understand new lines. - consoleEl.setHtml( editor.getData().replace( /\n\r?/g, '<br>' ) ); - } - - function checkUpdatePreview() { - setTimeout( function() { - if ( editor.checkDirty() ) { - updatePreview(); - editor.resetDirty(); - } - }, 0 ); - } - - editor.on( 'instanceReady', updatePreview ); - editor.on( 'key', checkUpdatePreview ); - editor.on( 'selectionChange', checkUpdatePreview ); - -})(); - </script> -</body> -</html> diff --git a/addons/website/static/lib/ckeditor/plugins/bbcode/plugin.js b/addons/website/static/lib/ckeditor/plugins/bbcode/plugin.js deleted file mode 100644 index ec988d3ae4a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bbcode/plugin.js +++ /dev/null @@ -1,779 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.on( 'dialogDefinition', function( ev ) { - var tab, - name = ev.data.name, - definition = ev.data.definition; - - if ( name == 'link' ) { - definition.removeContents( 'target' ); - definition.removeContents( 'upload' ); - definition.removeContents( 'advanced' ); - tab = definition.getContents( 'info' ); - tab.remove( 'emailSubject' ); - tab.remove( 'emailBody' ); - } else if ( name == 'image' ) { - definition.removeContents( 'advanced' ); - tab = definition.getContents( 'Link' ); - tab.remove( 'cmbTarget' ); - tab = definition.getContents( 'info' ); - tab.remove( 'txtAlt' ); - tab.remove( 'basic' ); - } - }); - - var bbcodeMap = { b: 'strong', u: 'u', i: 'em', color: 'span', size: 'span', quote: 'blockquote', code: 'code', url: 'a', email: 'span', img: 'span', '*': 'li', list: 'ol' }, - convertMap = { strong: 'b', b: 'b', u: 'u', em: 'i', i: 'i', code: 'code', li: '*' }, - tagnameMap = { strong: 'b', em: 'i', u: 'u', li: '*', ul: 'list', ol: 'list', code: 'code', a: 'link', img: 'img', blockquote: 'quote' }, - stylesMap = { color: 'color', size: 'font-size' }, - attributesMap = { url: 'href', email: 'mailhref', quote: 'cite', list: 'listType' }; - - // List of block-like tags. - var dtd = CKEDITOR.dtd, - blockLikeTags = CKEDITOR.tools.extend( { table:1 }, dtd.$block, dtd.$listItem, dtd.$tableContent, dtd.$list ); - - var semicolonFixRegex = /\s*(?:;\s*|$)/; - - function serializeStyleText( stylesObject ) { - var styleText = ''; - for ( var style in stylesObject ) { - var styleVal = stylesObject[ style ], - text = ( style + ':' + styleVal ).replace( semicolonFixRegex, ';' ); - - styleText += text; - } - return styleText; - } - - // Maintain the map of smiley-to-description. - var smileyMap = { smiley: ':)', sad: ':(', wink: ';)', laugh: ':D', cheeky: ':P', blush: ':*)', surprise: ':-o', indecision: ':|', angry: '>:(', angel: 'o:)', cool: '8-)', devil: '>:-)', crying: ';(', kiss: ':-*' }, - smileyReverseMap = {}, - smileyRegExp = []; - - // Build regexp for the list of smiley text. - for ( var i in smileyMap ) { - smileyReverseMap[ smileyMap[ i ] ] = i; - smileyRegExp.push( smileyMap[ i ].replace( /\(|\)|\:|\/|\*|\-|\|/g, function( match ) { - return '\\' + match; - })); - } - - smileyRegExp = new RegExp( smileyRegExp.join( '|' ), 'g' ); - - var decodeHtml = (function() { - var regex = [], - entities = { - nbsp: '\u00A0', // IE | FF - shy: '\u00AD', // IE - gt: '\u003E', // IE | FF | -- | Opera - lt: '\u003C' // IE | FF | Safari | Opera - }; - - for ( var entity in entities ) - regex.push( entity ); - - regex = new RegExp( '&(' + regex.join( '|' ) + ');', 'g' ); - - return function( html ) { - return html.replace( regex, function( match, entity ) { - return entities[ entity ]; - }); - }; - })(); - - CKEDITOR.BBCodeParser = function() { - this._ = { - bbcPartsRegex: /(?:\[([^\/\]=]*?)(?:=([^\]]*?))?\])|(?:\[\/([a-z]{1,16})\])/ig - }; - }; - - CKEDITOR.BBCodeParser.prototype = { - parse: function( bbcode ) { - var parts, part, - lastIndex = 0; - - while ( ( parts = this._.bbcPartsRegex.exec( bbcode ) ) ) { - var tagIndex = parts.index; - if ( tagIndex > lastIndex ) { - var text = bbcode.substring( lastIndex, tagIndex ); - this.onText( text, 1 ); - } - - lastIndex = this._.bbcPartsRegex.lastIndex; - - // "parts" is an array with the following items: - // 0 : The entire match for opening/closing tags and line-break; - // 1 : line-break; - // 2 : open of tag excludes option; - // 3 : tag option; - // 4 : close of tag; - - part = ( parts[ 1 ] || parts[ 3 ] || '' ).toLowerCase(); - // Unrecognized tags should be delivered as a simple text (#7860). - if ( part && !bbcodeMap[ part ] ) { - this.onText( parts[ 0 ] ); - continue; - } - - // Opening tag - if ( parts[ 1 ] ) { - var tagName = bbcodeMap[ part ], - attribs = {}, - styles = {}, - optionPart = parts[ 2 ]; - - if ( optionPart ) { - if ( part == 'list' ) { - if ( !isNaN( optionPart ) ) - optionPart = 'decimal'; - else if ( /^[a-z]+$/.test( optionPart ) ) - optionPart = 'lower-alpha'; - else if ( /^[A-Z]+$/.test( optionPart ) ) - optionPart = 'upper-alpha'; - } - - if ( stylesMap[ part ] ) { - // Font size represents percentage. - if ( part == 'size' ) - optionPart += '%'; - - styles[ stylesMap[ part ] ] = optionPart; - attribs.style = serializeStyleText( styles ); - } else if ( attributesMap[ part ] ) - attribs[ attributesMap[ part ] ] = optionPart; - } - - // Two special handling - image and email, protect them - // as "span" with an attribute marker. - if ( part == 'email' || part == 'img' ) - attribs[ 'bbcode' ] = part; - - this.onTagOpen( tagName, attribs, CKEDITOR.dtd.$empty[ tagName ] ); - } - // Closing tag - else if ( parts[ 3 ] ) - this.onTagClose( bbcodeMap[ part ] ); - } - - if ( bbcode.length > lastIndex ) - this.onText( bbcode.substring( lastIndex, bbcode.length ), 1 ); - } - }; - - /** - * Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string. - * - * var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' ); - * alert( fragment.children[ 0 ].name ); // 'b' - * alert( fragment.children[ 1 ].value ); // ' Text' - * - * @static - * @member CKEDITOR.htmlParser.fragment - * @param {String} source The HTML to be parsed, filling the fragment. - * @returns {CKEDITOR.htmlParser.fragment} The fragment created. - */ - CKEDITOR.htmlParser.fragment.fromBBCode = function( source ) { - var parser = new CKEDITOR.BBCodeParser(), - fragment = new CKEDITOR.htmlParser.fragment(), - pendingInline = [], - pendingBrs = 0, - currentNode = fragment, - returnPoint; - - function checkPending( newTagName ) { - if ( pendingInline.length > 0 ) { - for ( var i = 0; i < pendingInline.length; i++ ) { - var pendingElement = pendingInline[ i ], - pendingName = pendingElement.name, - pendingDtd = CKEDITOR.dtd[ pendingName ], - currentDtd = currentNode.name && CKEDITOR.dtd[ currentNode.name ]; - - if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) ) { - // Get a clone for the pending element. - pendingElement = pendingElement.clone(); - - // Add it to the current node and make it the current, - // so the new element will be added inside of it. - pendingElement.parent = currentNode; - currentNode = pendingElement; - - // Remove the pending element (back the index by one - // to properly process the next entry). - pendingInline.splice( i, 1 ); - i--; - } - } - } - } - - function checkPendingBrs( tagName, closing ) { - var len = currentNode.children.length, - previous = len > 0 && currentNode.children[ len - 1 ], - lineBreakParent = !previous && writer.getRule( tagnameMap[ currentNode.name ], 'breakAfterOpen' ), - lineBreakPrevious = previous && previous.type == CKEDITOR.NODE_ELEMENT && writer.getRule( tagnameMap[ previous.name ], 'breakAfterClose' ), - lineBreakCurrent = tagName && writer.getRule( tagnameMap[ tagName ], closing ? 'breakBeforeClose' : 'breakBeforeOpen' ); - - if ( pendingBrs && ( lineBreakParent || lineBreakPrevious || lineBreakCurrent ) ) - pendingBrs--; - - // 1. Either we're at the end of block, where it requires us to compensate the br filler - // removing logic (from htmldataprocessor). - // 2. Or we're at the end of pseudo block, where it requires us to compensate - // the bogus br effect. - if ( pendingBrs && tagName in blockLikeTags ) - pendingBrs++; - - while ( pendingBrs && pendingBrs-- ) - currentNode.children.push( previous = new CKEDITOR.htmlParser.element( 'br' ) ); - } - - function addElement( node, target ) { - checkPendingBrs( node.name, 1 ); - - target = target || currentNode || fragment; - - var len = target.children.length, - previous = len > 0 && target.children[ len - 1 ] || null; - - node.previous = previous; - node.parent = target; - - target.children.push( node ); - - if ( node.returnPoint ) { - currentNode = node.returnPoint; - delete node.returnPoint; - } - } - - parser.onTagOpen = function( tagName, attributes, selfClosing ) { - var element = new CKEDITOR.htmlParser.element( tagName, attributes ); - - // This is a tag to be removed if empty, so do not add it immediately. - if ( CKEDITOR.dtd.$removeEmpty[ tagName ] ) { - pendingInline.push( element ); - return; - } - - var currentName = currentNode.name; - - var currentDtd = currentName && ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ); - - // If the element cannot be child of the current element. - if ( currentDtd && !currentDtd[ tagName ] ) { - var reApply = false, - addPoint; // New position to start adding nodes. - - // If the element name is the same as the current element name, - // then just close the current one and append the new one to the - // parent. This situation usually happens with <p>, <li>, <dt> and - // <dd>, specially in IE. Do not enter in this if block in this case. - if ( tagName == currentName ) - addElement( currentNode, currentNode.parent ); - else if ( tagName in CKEDITOR.dtd.$listItem ) { - parser.onTagOpen( 'ul', {} ); - addPoint = currentNode; - reApply = true; - } else { - addElement( currentNode, currentNode.parent ); - - // The current element is an inline element, which - // cannot hold the new one. Put it in the pending list, - // and try adding the new one after it. - pendingInline.unshift( currentNode ); - reApply = true; - } - - if ( addPoint ) - currentNode = addPoint; - // Try adding it to the return point, or the parent element. - else - currentNode = currentNode.returnPoint || currentNode.parent; - - if ( reApply ) { - parser.onTagOpen.apply( this, arguments ); - return; - } - } - - checkPending( tagName ); - checkPendingBrs( tagName ); - - element.parent = currentNode; - element.returnPoint = returnPoint; - returnPoint = 0; - - if ( element.isEmpty ) - addElement( element ); - else - currentNode = element; - }; - - parser.onTagClose = function( tagName ) { - // Check if there is any pending tag to be closed. - for ( var i = pendingInline.length - 1; i >= 0; i-- ) { - // If found, just remove it from the list. - if ( tagName == pendingInline[ i ].name ) { - pendingInline.splice( i, 1 ); - return; - } - } - - var pendingAdd = [], - newPendingInline = [], - candidate = currentNode; - - while ( candidate.type && candidate.name != tagName ) { - // If this is an inline element, add it to the pending list, if we're - // really closing one of the parents element later, they will continue - // after it. - if ( !candidate._.isBlockLike ) - newPendingInline.unshift( candidate ); - - // This node should be added to it's parent at this point. But, - // it should happen only if the closing tag is really closing - // one of the nodes. So, for now, we just cache it. - pendingAdd.push( candidate ); - - candidate = candidate.parent; - } - - if ( candidate.type ) { - // Add all elements that have been found in the above loop. - for ( i = 0; i < pendingAdd.length; i++ ) { - var node = pendingAdd[ i ]; - addElement( node, node.parent ); - } - - currentNode = candidate; - - - addElement( candidate, candidate.parent ); - - // The parent should start receiving new nodes now, except if - // addElement changed the currentNode. - if ( candidate == currentNode ) - currentNode = currentNode.parent; - - pendingInline = pendingInline.concat( newPendingInline ); - } - }; - - parser.onText = function( text ) { - var currentDtd = CKEDITOR.dtd[ currentNode.name ]; - if ( !currentDtd || currentDtd[ '#' ] ) { - checkPendingBrs(); - checkPending(); - - text.replace( /(\r\n|[\r\n])|[^\r\n]*/g, function( piece, lineBreak ) { - if ( lineBreak !== undefined && lineBreak.length ) - pendingBrs++; - else if ( piece.length ) { - var lastIndex = 0; - - // Create smiley from text emotion. - piece.replace( smileyRegExp, function( match, index ) { - addElement( new CKEDITOR.htmlParser.text( piece.substring( lastIndex, index ) ), currentNode ); - addElement( new CKEDITOR.htmlParser.element( 'smiley', { desc: smileyReverseMap[ match ] } ), currentNode ); - lastIndex = index + match.length; - }); - - if ( lastIndex != piece.length ) - addElement( new CKEDITOR.htmlParser.text( piece.substring( lastIndex, piece.length ) ), currentNode ); - } - }); - } - }; - - // Parse it. - parser.parse( CKEDITOR.tools.htmlEncode( source ) ); - - // Close all hanging nodes. - while ( currentNode.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT ) { - var parent = currentNode.parent, - node = currentNode; - - addElement( node, parent ); - currentNode = parent; - } - - return fragment; - }; - - var BBCodeWriter = CKEDITOR.tools.createClass({ - $: function() { - this._ = { - output: [], - rules: [] - }; - - // List and list item. - this.setRules( 'list', { breakBeforeOpen:1,breakAfterOpen:1,breakBeforeClose:1,breakAfterClose:1 }); - - this.setRules( '*', { - breakBeforeOpen: 1, - breakAfterOpen: 0, - breakBeforeClose: 1, - breakAfterClose: 0 - }); - - this.setRules( 'quote', { - breakBeforeOpen: 1, - breakAfterOpen: 0, - breakBeforeClose: 0, - breakAfterClose: 1 - }); - }, - - proto: { - // - // Sets formatting rules for a given tag. The possible rules are: - // <ul> - // <li><b>breakBeforeOpen</b>: break line before the opener tag for this element.</li> - // <li><b>breakAfterOpen</b>: break line after the opener tag for this element.</li> - // <li><b>breakBeforeClose</b>: break line before the closer tag for this element.</li> - // <li><b>breakAfterClose</b>: break line after the closer tag for this element.</li> - // </ul> - // - // All rules default to "false". Each call to the function overrides - // already present rules, leaving the undefined untouched. - // - // @param {String} tagName The tag name to which set the rules. - // @param {Object} rules An object containing the element rules. - // @example - // // Break line before and after "img" tags. - // writer.setRules( 'list', - // { - // breakBeforeOpen : true - // breakAfterOpen : true - // }); - setRules: function( tagName, rules ) { - var currentRules = this._.rules[ tagName ]; - - if ( currentRules ) - CKEDITOR.tools.extend( currentRules, rules, true ); - else - this._.rules[ tagName ] = rules; - }, - - getRule: function( tagName, ruleName ) { - return this._.rules[ tagName ] && this._.rules[ tagName ][ ruleName ]; - }, - - openTag : function( tag ) { - if ( tag in bbcodeMap ) { - if ( this.getRule( tag, 'breakBeforeOpen' ) ) - this.lineBreak( 1 ); - - this.write( '[', tag ); - } - }, - - openTagClose : function( tag ) { - if ( tag == 'br' ) - this._.output.push( '\n' ); - else if ( tag in bbcodeMap ) { - this.write( ']' ); - if ( this.getRule( tag, 'breakAfterOpen' ) ) - this.lineBreak( 1 ); - } - }, - - attribute : function( name, val ) { - if ( name == 'option' ) { - // Force simply ampersand in attributes. - if ( typeof val == 'string' ) - val = val.replace( /&/g, '&' ); - - this.write( '=', val ); - } - }, - - closeTag: function( tag ) { - if ( tag in bbcodeMap ) { - if ( this.getRule( tag, 'breakBeforeClose' ) ) - this.lineBreak( 1 ); - - tag != '*' && this.write( '[/', tag, ']' ); - - if ( this.getRule( tag, 'breakAfterClose' ) ) - this.lineBreak( 1 ); - } - }, - - text: function( text ) { - this.write( text ); - }, - - comment: function() {}, - - // Output line-break for formatting. - lineBreak: function() { - // Avoid line break when: - // 1) Previous tag already put one. - // 2) We're at output start. - if ( !this._.hasLineBreak && this._.output.length ) { - this.write( '\n' ); - this._.hasLineBreak = 1; - } - }, - - write: function() { - this._.hasLineBreak = 0; - var data = Array.prototype.join.call( arguments, '' ); - this._.output.push( data ); - }, - - reset: function() { - this._.output = []; - this._.hasLineBreak = 0; - }, - - getHtml: function( reset ) { - var bbcode = this._.output.join( '' ); - - if ( reset ) - this.reset(); - - return decodeHtml( bbcode ); - } - } - }); - - var writer = new BBCodeWriter(); - - CKEDITOR.plugins.add( 'bbcode', { - requires: 'entities', - - beforeInit: function( editor ) { - // Adapt some critical editor configuration for better support - // of BBCode environment. - var config = editor.config; - CKEDITOR.tools.extend( config, { - enterMode: CKEDITOR.ENTER_BR, - basicEntities: false, - entities: false, - fillEmptyBlocks: false - }, true ); - - editor.filter.disable(); - }, - - init: function( editor ) { - var config = editor.config; - - function BBCodeToHtml( code ) { - var fragment = CKEDITOR.htmlParser.fragment.fromBBCode( code ), - writer = new CKEDITOR.htmlParser.basicWriter(); - - fragment.writeHtml( writer, bbcodeFilter ); - return writer.getHtml( true ); - } - - var bbcodeFilter = new CKEDITOR.htmlParser.filter(); - bbcodeFilter.addRules({ - elements: { - blockquote: function( element ) { - var quoted = new CKEDITOR.htmlParser.element( 'div' ); - quoted.children = element.children; - element.children = [ quoted ]; - var citeText = element.attributes.cite; - if ( citeText ) { - var cite = new CKEDITOR.htmlParser.element( 'cite' ); - cite.add( new CKEDITOR.htmlParser.text( citeText.replace( /^"|"$/g, '' ) ) ); - delete element.attributes.cite; - element.children.unshift( cite ); - } - }, - span: function( element ) { - var bbcode; - if ( ( bbcode = element.attributes.bbcode ) ) { - if ( bbcode == 'img' ) { - element.name = 'img'; - element.attributes.src = element.children[ 0 ].value; - element.children = []; - } else if ( bbcode == 'email' ) { - element.name = 'a'; - element.attributes.href = 'mailto:' + element.children[ 0 ].value; - } - - delete element.attributes.bbcode; - } - }, - ol: function( element ) { - if ( element.attributes.listType ) { - if ( element.attributes.listType != 'decimal' ) - element.attributes.style = 'list-style-type:' + element.attributes.listType; - } else - element.name = 'ul'; - - delete element.attributes.listType; - }, - a: function( element ) { - if ( !element.attributes.href ) - element.attributes.href = element.children[ 0 ].value; - }, - smiley: function( element ) { - element.name = 'img'; - - var description = element.attributes.desc, - image = config.smiley_images[ CKEDITOR.tools.indexOf( config.smiley_descriptions, description ) ], - src = CKEDITOR.tools.htmlEncode( config.smiley_path + image ); - - element.attributes = { - src: src, - 'data-cke-saved-src': src, - title: description, - alt: description - }; - } - } - }); - - editor.dataProcessor.htmlFilter.addRules({ - elements: { - $: function( element ) { - var attributes = element.attributes, - style = CKEDITOR.tools.parseCssText( attributes.style, 1 ), - value; - - var tagName = element.name; - if ( tagName in convertMap ) - tagName = convertMap[ tagName ]; - else if ( tagName == 'span' ) { - if ( ( value = style.color ) ) { - tagName = 'color'; - value = CKEDITOR.tools.convertRgbToHex( value ); - } else if ( ( value = style[ 'font-size' ] ) ) { - var percentValue = value.match( /(\d+)%$/ ); - if ( percentValue ) { - value = percentValue[ 1 ]; - tagName = 'size'; - } - } - } else if ( tagName == 'ol' || tagName == 'ul' ) { - if ( ( value = style[ 'list-style-type' ] ) ) { - switch ( value ) { - case 'lower-alpha': - value = 'a'; - break; - case 'upper-alpha': - value = 'A'; - break; - } - } else if ( tagName == 'ol' ) - value = 1; - - tagName = 'list'; - } else if ( tagName == 'blockquote' ) { - try { - var cite = element.children[ 0 ], - quoted = element.children[ 1 ], - citeText = cite.name == 'cite' && cite.children[ 0 ].value; - - if ( citeText ) { - value = '"' + citeText + '"'; - element.children = quoted.children; - } - - } catch ( er ) {} - - tagName = 'quote'; - } else if ( tagName == 'a' ) { - if ( ( value = attributes.href ) ) { - if ( value.indexOf( 'mailto:' ) !== -1 ) { - tagName = 'email'; - // [email] should have a single text child with email address. - element.children = [ new CKEDITOR.htmlParser.text( value.replace( 'mailto:', '' ) ) ]; - value = ''; - } else { - var singleton = element.children.length == 1 && element.children[ 0 ]; - if ( singleton && singleton.type == CKEDITOR.NODE_TEXT && singleton.value == value ) - value = ''; - - tagName = 'url'; - } - } - } else if ( tagName == 'img' ) { - element.isEmpty = 0; - - // Translate smiley (image) to text emotion. - var src = attributes[ 'data-cke-saved-src' ] || attributes.src, - alt = attributes.alt; - - if ( src && src.indexOf( editor.config.smiley_path ) != -1 && alt ) - return new CKEDITOR.htmlParser.text( smileyMap[ alt ] ); - else - element.children = [ new CKEDITOR.htmlParser.text( src ) ]; - } - - element.name = tagName; - value && ( element.attributes.option = value ); - - return null; - }, - - // Remove any bogus br from the end of a pseudo block, - // e.g. <div>some text<br /><p>paragraph</p></div> - br: function( element ) { - var next = element.next; - if ( next && next.name in blockLikeTags ) - return false; - } - } - }, 1 ); - - editor.dataProcessor.writer = writer; - - function onSetData( evt ) { - var bbcode = evt.data.dataValue; - evt.data.dataValue = BBCodeToHtml( bbcode ); - } - - // Skip the first "setData" call from inline creator, to allow content of - // HTML to be loaded from the page element. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - editor.once( 'contentDom', function() { - editor.on( 'setData', onSetData ); - }); - else - editor.on( 'setData', onSetData ); - - }, - - afterInit: function( editor ) { - var filters; - if ( editor._.elementsPath ) { - // Eliminate irrelevant elements from displaying, e.g body and p. - if ( ( filters = editor._.elementsPath.filters ) ) { - filters.push( function( element ) { - var htmlName = element.getName(), - name = tagnameMap[ htmlName ] || false; - - // Specialized anchor presents as email. - if ( name == 'link' && element.getAttribute( 'href' ).indexOf( 'mailto:' ) === 0 ) - name = 'email'; - // Styled span could be either size or color. - else if ( htmlName == 'span' ) { - if ( element.getStyle( 'font-size' ) ) - name = 'size'; - else if ( element.getStyle( 'color' ) ) - name = 'color'; - } else if ( name == 'img' ) { - var src = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' ); - if ( src && src.indexOf( editor.config.smiley_path ) === 0 ) - name = 'smiley'; - } - - return name; - }); - } - } - } - }); - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidiltr.png b/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidiltr.png Binary files differdeleted file mode 100644 index a909c0103b4..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidiltr.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidirtl.png b/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidirtl.png Binary files differdeleted file mode 100644 index 7dbad48c123..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/icons/bidirtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidiltr.png b/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidiltr.png Binary files differdeleted file mode 100644 index c5998e00776..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidiltr.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidirtl.png b/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidirtl.png Binary files differdeleted file mode 100644 index 8aa2adc8700..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/icons/hidpi/bidirtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/lang/en.js b/addons/website/static/lib/ckeditor/plugins/bidi/lang/en.js deleted file mode 100644 index b0fbe8cf27a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'bidi', 'en', { - ltr: 'Text direction from left to right', - rtl: 'Text direction from right to left' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/bidi/plugin.js b/addons/website/static/lib/ckeditor/plugins/bidi/plugin.js deleted file mode 100644 index 601cda9f996..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/bidi/plugin.js +++ /dev/null @@ -1,308 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var guardElements = { table:1,ul:1,ol:1,blockquote:1,div:1 }, - directSelectionGuardElements = {}, - // All guard elements which can have a direction applied on them. - allGuardElements = {}; - CKEDITOR.tools.extend( directSelectionGuardElements, guardElements, { tr:1,p:1,div:1,li:1 } ); - CKEDITOR.tools.extend( allGuardElements, directSelectionGuardElements, { td:1 } ); - - function setToolbarStates( editor, path ) { - var useComputedState = editor.config.useComputedState, - selectedElement; - - useComputedState = useComputedState === undefined || useComputedState; - - // We can use computedState provided by the browser or traverse parents manually. - if ( !useComputedState ) - selectedElement = getElementForDirection( path.lastElement, editor.editable() ); - - selectedElement = selectedElement || path.block || path.blockLimit; - - // If we're having BODY here, user probably done CTRL+A, let's try to get the enclosed node, if any. - if ( selectedElement.equals( editor.editable() ) ) { - var enclosedNode = editor.getSelection().getRanges()[ 0 ].getEnclosedNode(); - enclosedNode && enclosedNode.type == CKEDITOR.NODE_ELEMENT && ( selectedElement = enclosedNode ); - } - - if ( !selectedElement ) - return; - - var selectionDir = useComputedState ? selectedElement.getComputedStyle( 'direction' ) : selectedElement.getStyle( 'direction' ) || selectedElement.getAttribute( 'dir' ); - - editor.getCommand( 'bidirtl' ).setState( selectionDir == 'rtl' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - editor.getCommand( 'bidiltr' ).setState( selectionDir == 'ltr' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - } - - function handleMixedDirContent( editor, path ) { - var directionNode = path.block || path.blockLimit || editor.editable(); - var pathDir = directionNode.getDirection( 1 ); - if ( pathDir != ( editor._.selDir || editor.lang.dir ) ) { - editor._.selDir = pathDir; - editor.fire( 'contentDirChanged', pathDir ); - } - } - - // Returns element with possibility of applying the direction. - // @param node - function getElementForDirection( node, root ) { - while ( node && !( node.getName() in allGuardElements || node.equals( root ) ) ) { - var parent = node.getParent(); - if ( !parent ) - break; - - node = parent; - } - - return node; - } - - function switchDir( element, dir, editor, database ) { - if ( element.isReadOnly() || element.equals( editor.editable() ) ) - return; - - // Mark this element as processed by switchDir. - CKEDITOR.dom.element.setMarker( database, element, 'bidi_processed', 1 ); - - // Check whether one of the ancestors has already been styled. - var parent = element, - editable = editor.editable(); - while ( ( parent = parent.getParent() ) && !parent.equals( editable ) ) { - if ( parent.getCustomData( 'bidi_processed' ) ) { - // Ancestor style must dominate. - element.removeStyle( 'direction' ); - element.removeAttribute( 'dir' ); - return; - } - } - - var useComputedState = ( 'useComputedState' in editor.config ) ? editor.config.useComputedState : 1; - - var elementDir = useComputedState ? element.getComputedStyle( 'direction' ) : element.getStyle( 'direction' ) || element.hasAttribute( 'dir' ); - - // Stop if direction is same as present. - if ( elementDir == dir ) - return; - - // Clear direction on this element. - element.removeStyle( 'direction' ); - - // Do the second check when computed state is ON, to check - // if we need to apply explicit direction on this element. - if ( useComputedState ) { - element.removeAttribute( 'dir' ); - if ( dir != element.getComputedStyle( 'direction' ) ) - element.setAttribute( 'dir', dir ); - } else - // Set new direction for this element. - element.setAttribute( 'dir', dir ); - - editor.forceNextSelectionCheck(); - - return; - } - - function getFullySelected( range, elements, enterMode ) { - var ancestor = range.getCommonAncestor( false, true ); - - range = range.clone(); - range.enlarge( enterMode == CKEDITOR.ENTER_BR ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS ); - - if ( range.checkBoundaryOfElement( ancestor, CKEDITOR.START ) && range.checkBoundaryOfElement( ancestor, CKEDITOR.END ) ) { - var parent; - while ( ancestor && ancestor.type == CKEDITOR.NODE_ELEMENT && ( parent = ancestor.getParent() ) && parent.getChildCount() == 1 && !( ancestor.getName() in elements ) ) - ancestor = parent; - - return ancestor.type == CKEDITOR.NODE_ELEMENT && ( ancestor.getName() in elements ) && ancestor; - } - } - - function bidiCommand( dir ) { - return { - // It applies to a "block-like" context. - context: 'p', - allowedContent: { - 'h1 h2 h3 h4 h5 h6 table ul ol blockquote div tr p div li td': { - propertiesOnly: true, - attributes: 'dir' - } - }, - requiredContent: 'p[dir]', - refresh: function( editor, path ) { - setToolbarStates( editor, path ); - handleMixedDirContent( editor, path ); - }, - exec: function( editor ) { - var selection = editor.getSelection(), - enterMode = editor.config.enterMode, - ranges = selection.getRanges(); - - if ( ranges && ranges.length ) { - var database = {}; - - // Creates bookmarks for selection, as we may split some blocks. - var bookmarks = selection.createBookmarks(); - - var rangeIterator = ranges.createIterator(), - range, - i = 0; - - while ( ( range = rangeIterator.getNextRange( 1 ) ) ) { - // Apply do directly selected elements from guardElements. - var selectedElement = range.getEnclosedNode(); - - // If this is not our element of interest, apply to fully selected elements from guardElements. - if ( !selectedElement || selectedElement && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements ) ) - selectedElement = getFullySelected( range, guardElements, enterMode ); - - selectedElement && switchDir( selectedElement, dir, editor, database ); - - var iterator, block; - - // Walker searching for guardElements. - var walker = new CKEDITOR.dom.walker( range ); - - var start = bookmarks[ i ].startNode, - end = bookmarks[ i++ ].endNode; - - walker.evaluator = function( node ) { - return !!( node.type == CKEDITOR.NODE_ELEMENT && node.getName() in guardElements && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) && node.getParent().type == CKEDITOR.NODE_ELEMENT && node.getParent().getName() == 'blockquote' ) - // Element must be fully included in the range as well. (#6485). - && node.getPosition( start ) & CKEDITOR.POSITION_FOLLOWING && ( ( node.getPosition( end ) & CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_CONTAINS ) == CKEDITOR.POSITION_PRECEDING ) ); - }; - - while ( ( block = walker.next() ) ) - switchDir( block, dir, editor, database ); - - iterator = range.createIterator(); - iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; - - while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) - switchDir( block, dir, editor, database ); - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - editor.forceNextSelectionCheck(); - // Restore selection position. - selection.selectBookmarks( bookmarks ); - - editor.focus(); - } - } - }; - } - - CKEDITOR.plugins.add( 'bidi', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'bidiltr,bidirtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - // All buttons use the same code to register. So, to avoid - // duplications, let's use this tool function. - function addButtonCommand( buttonName, buttonLabel, commandName, commandDef, order ) { - editor.addCommand( commandName, new CKEDITOR.command( editor, commandDef ) ); - - if ( editor.ui.addButton ) { - editor.ui.addButton( buttonName, { - label: buttonLabel, - command: commandName, - toolbar: 'bidi,' + order - }); - } - } - - var lang = editor.lang.bidi; - - if ( editor.ui.addToolbarGroup ) - editor.ui.addToolbarGroup( 'bidi', 'align', 'paragraph' ); - - addButtonCommand( 'BidiLtr', lang.ltr, 'bidiltr', bidiCommand( 'ltr' ), 10 ); - addButtonCommand( 'BidiRtl', lang.rtl, 'bidirtl', bidiCommand( 'rtl' ), 20 ); - - editor.on( 'contentDom', function() { - editor.document.on( 'dirChanged', function( evt ) { - editor.fire( 'dirChanged', { - node: evt.data, - dir: evt.data.getDirection( 1 ) - }); - }); - }); - - // Indicate that the current selection is in different direction than the UI. - editor.on( 'contentDirChanged', function( evt ) { - var func = ( editor.lang.dir != evt.data ? 'add' : 'remove' ) + 'Class'; - var toolbar = editor.ui.space( editor.config.toolbarLocation ); - if ( toolbar ) - toolbar[ func ]( 'cke_mixed_dir_content' ); - }); - } - }); - - // If the element direction changed, we need to switch the margins of - // the element and all its children, so it will get really reflected - // like a mirror. (#5910) - function isOffline( el ) { - var html = el.getDocument().getBody().getParent(); - while ( el ) { - if ( el.equals( html ) ) - return false; - el = el.getParent(); - } - return true; - } - - function dirChangeNotifier( org ) { - var isAttribute = org == elementProto.setAttribute, - isRemoveAttribute = org == elementProto.removeAttribute, - dirStyleRegexp = /\bdirection\s*:\s*(.*?)\s*(:?$|;)/; - - return function( name, val ) { - if ( !this.isReadOnly() ) { - var orgDir; - if ( ( name == ( isAttribute || isRemoveAttribute ? 'dir' : 'direction' ) || name == 'style' && ( isRemoveAttribute || dirStyleRegexp.test( val ) ) ) && !isOffline( this ) ) { - orgDir = this.getDirection( 1 ); - var retval = org.apply( this, arguments ); - if ( orgDir != this.getDirection( 1 ) ) { - this.getDocument().fire( 'dirChanged', this ); - return retval; - } - } - } - - return org.apply( this, arguments ); - }; - } - - var elementProto = CKEDITOR.dom.element.prototype, - methods = [ 'setStyle', 'removeStyle', 'setAttribute', 'removeAttribute' ]; - for ( var i = 0; i < methods.length; i++ ) - elementProto[ methods[ i ] ] = CKEDITOR.tools.override( elementProto[ methods[ i ] ], dirChangeNotifier ); -})(); - -/** - * Fired when the language direction of an element is changed. - * - * @event dirChanged - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {CKEDITOR.dom.node} data.node The element that is being changed. - * @param {String} data.dir The new direction. - */ - -/** - * Fired when the language direction in the specific cursor position is changed - * - * @event contentDirChanged - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {String} data The direction in the current position. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/blockquote/icons/blockquote.png b/addons/website/static/lib/ckeditor/plugins/blockquote/icons/blockquote.png Binary files differdeleted file mode 100644 index 95293e25d30..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/blockquote/icons/blockquote.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/blockquote/icons/hidpi/blockquote.png b/addons/website/static/lib/ckeditor/plugins/blockquote/icons/hidpi/blockquote.png Binary files differdeleted file mode 100644 index 50c23b9f210..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/blockquote/icons/hidpi/blockquote.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/blockquote/lang/en.js b/addons/website/static/lib/ckeditor/plugins/blockquote/lang/en.js deleted file mode 100644 index db4801cdeb9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/blockquote/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'blockquote', 'en', { - toolbar: 'Block Quote' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/blockquote/plugin.js b/addons/website/static/lib/ckeditor/plugins/blockquote/plugin.js deleted file mode 100755 index 26bb5000e27..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/blockquote/plugin.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - function noBlockLeft( bqBlock ) { - for ( var i = 0, length = bqBlock.getChildCount(), child; i < length && ( child = bqBlock.getChild( i ) ); i++ ) { - if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() ) - return false; - } - return true; - } - - var commandObject = { - exec: function( editor ) { - var state = editor.getCommand( 'blockquote' ).state, - selection = editor.getSelection(), - range = selection && selection.getRanges( true )[ 0 ]; - - if ( !range ) - return; - - var bookmarks = selection.createBookmarks(); - - // Kludge for #1592: if the bookmark nodes are in the beginning of - // blockquote, then move them to the nearest block element in the - // blockquote. - if ( CKEDITOR.env.ie ) { - var bookmarkStart = bookmarks[ 0 ].startNode, - bookmarkEnd = bookmarks[ 0 ].endNode, - cursor; - - if ( bookmarkStart && bookmarkStart.getParent().getName() == 'blockquote' ) { - cursor = bookmarkStart; - while ( ( cursor = cursor.getNext() ) ) { - if ( cursor.type == CKEDITOR.NODE_ELEMENT && cursor.isBlockBoundary() ) { - bookmarkStart.move( cursor, true ); - break; - } - } - } - - if ( bookmarkEnd && bookmarkEnd.getParent().getName() == 'blockquote' ) { - cursor = bookmarkEnd; - while ( ( cursor = cursor.getPrevious() ) ) { - if ( cursor.type == CKEDITOR.NODE_ELEMENT && cursor.isBlockBoundary() ) { - bookmarkEnd.move( cursor ); - break; - } - } - } - } - - var iterator = range.createIterator(), - block; - iterator.enlargeBr = editor.config.enterMode != CKEDITOR.ENTER_BR; - - if ( state == CKEDITOR.TRISTATE_OFF ) { - var paragraphs = []; - while ( ( block = iterator.getNextParagraph() ) ) - paragraphs.push( block ); - - // If no paragraphs, create one from the current selection position. - if ( paragraphs.length < 1 ) { - var para = editor.document.createElement( editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ), - firstBookmark = bookmarks.shift(); - range.insertNode( para ); - para.append( new CKEDITOR.dom.text( '\ufeff', editor.document ) ); - range.moveToBookmark( firstBookmark ); - range.selectNodeContents( para ); - range.collapse( true ); - firstBookmark = range.createBookmark(); - paragraphs.push( para ); - bookmarks.unshift( firstBookmark ); - } - - // Make sure all paragraphs have the same parent. - var commonParent = paragraphs[ 0 ].getParent(), - tmp = []; - for ( var i = 0; i < paragraphs.length; i++ ) { - block = paragraphs[ i ]; - commonParent = commonParent.getCommonAncestor( block.getParent() ); - } - - // The common parent must not be the following tags: table, tbody, tr, ol, ul. - var denyTags = { table:1,tbody:1,tr:1,ol:1,ul:1 }; - while ( denyTags[ commonParent.getName() ] ) - commonParent = commonParent.getParent(); - - // Reconstruct the block list to be processed such that all resulting blocks - // satisfy parentNode.equals( commonParent ). - var lastBlock = null; - while ( paragraphs.length > 0 ) { - block = paragraphs.shift(); - while ( !block.getParent().equals( commonParent ) ) - block = block.getParent(); - if ( !block.equals( lastBlock ) ) - tmp.push( block ); - lastBlock = block; - } - - // If any of the selected blocks is a blockquote, remove it to prevent - // nested blockquotes. - while ( tmp.length > 0 ) { - block = tmp.shift(); - if ( block.getName() == 'blockquote' ) { - var docFrag = new CKEDITOR.dom.documentFragment( editor.document ); - while ( block.getFirst() ) { - docFrag.append( block.getFirst().remove() ); - paragraphs.push( docFrag.getLast() ); - } - - docFrag.replace( block ); - } else - paragraphs.push( block ); - } - - // Now we have all the blocks to be included in a new blockquote node. - var bqBlock = editor.document.createElement( 'blockquote' ); - bqBlock.insertBefore( paragraphs[ 0 ] ); - while ( paragraphs.length > 0 ) { - block = paragraphs.shift(); - bqBlock.append( block ); - } - } else if ( state == CKEDITOR.TRISTATE_ON ) { - var moveOutNodes = [], - database = {}; - - while ( ( block = iterator.getNextParagraph() ) ) { - var bqParent = null, - bqChild = null; - while ( block.getParent() ) { - if ( block.getParent().getName() == 'blockquote' ) { - bqParent = block.getParent(); - bqChild = block; - break; - } - block = block.getParent(); - } - - // Remember the blocks that were recorded down in the moveOutNodes array - // to prevent duplicates. - if ( bqParent && bqChild && !bqChild.getCustomData( 'blockquote_moveout' ) ) { - moveOutNodes.push( bqChild ); - CKEDITOR.dom.element.setMarker( database, bqChild, 'blockquote_moveout', true ); - } - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - var movedNodes = [], - processedBlockquoteBlocks = []; - - database = {}; - while ( moveOutNodes.length > 0 ) { - var node = moveOutNodes.shift(); - bqBlock = node.getParent(); - - // If the node is located at the beginning or the end, just take it out - // without splitting. Otherwise, split the blockquote node and move the - // paragraph in between the two blockquote nodes. - if ( !node.getPrevious() ) - node.remove().insertBefore( bqBlock ); - else if ( !node.getNext() ) - node.remove().insertAfter( bqBlock ); - else { - node.breakParent( node.getParent() ); - processedBlockquoteBlocks.push( node.getNext() ); - } - - // Remember the blockquote node so we can clear it later (if it becomes empty). - if ( !bqBlock.getCustomData( 'blockquote_processed' ) ) { - processedBlockquoteBlocks.push( bqBlock ); - CKEDITOR.dom.element.setMarker( database, bqBlock, 'blockquote_processed', true ); - } - - movedNodes.push( node ); - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - // Clear blockquote nodes that have become empty. - for ( i = processedBlockquoteBlocks.length - 1; i >= 0; i-- ) { - bqBlock = processedBlockquoteBlocks[ i ]; - if ( noBlockLeft( bqBlock ) ) - bqBlock.remove(); - } - - if ( editor.config.enterMode == CKEDITOR.ENTER_BR ) { - var firstTime = true; - while ( movedNodes.length ) { - node = movedNodes.shift(); - - if ( node.getName() == 'div' ) { - docFrag = new CKEDITOR.dom.documentFragment( editor.document ); - var needBeginBr = firstTime && node.getPrevious() && !( node.getPrevious().type == CKEDITOR.NODE_ELEMENT && node.getPrevious().isBlockBoundary() ); - if ( needBeginBr ) - docFrag.append( editor.document.createElement( 'br' ) ); - - var needEndBr = node.getNext() && !( node.getNext().type == CKEDITOR.NODE_ELEMENT && node.getNext().isBlockBoundary() ); - while ( node.getFirst() ) - node.getFirst().remove().appendTo( docFrag ); - - if ( needEndBr ) - docFrag.append( editor.document.createElement( 'br' ) ); - - docFrag.replace( node ); - firstTime = false; - } - } - } - } - - selection.selectBookmarks( bookmarks ); - editor.focus(); - }, - - refresh: function( editor, path ) { - // Check if inside of blockquote. - var firstBlock = path.block || path.blockLimit; - this.setState( editor.elementPath( firstBlock ).contains( 'blockquote', 1 ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - }, - - context: 'blockquote', - - allowedContent: 'blockquote', - requiredContent: 'blockquote' - }; - - CKEDITOR.plugins.add( 'blockquote', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'blockquote', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - editor.addCommand( 'blockquote', commandObject ); - - editor.ui.addButton && editor.ui.addButton( 'Blockquote', { - label: editor.lang.blockquote.toolbar, - command: 'blockquote', - toolbar: 'blocks,10' - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/button/plugin.js b/addons/website/static/lib/ckeditor/plugins/button/plugin.js deleted file mode 100644 index 88e4d841209..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/button/plugin.js +++ /dev/null @@ -1,354 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var template = '<a id="{id}"' + - ' class="cke_button cke_button__{name} cke_button_{state} {cls}"' + - ( CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900 && !CKEDITOR.env.hc ? '' : '" href="javascript:void(\'{titleJs}\')"' ) + - ' title="{title}"' + - ' tabindex="-1"' + - ' hidefocus="true"' + - ' role="button"' + - ' aria-labelledby="{id}_label"' + - ' aria-haspopup="{hasArrow}"'; - - // Some browsers don't cancel key events in the keydown but in the - // keypress. - // TODO: Check if really needed for Gecko+Mac. - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - template += ' onkeypress="return false;"'; - - // With Firefox, we need to force the button to redraw, otherwise it - // will remain in the focus state. - if ( CKEDITOR.env.gecko ) - template += ' onblur="this.style.cssText = this.style.cssText;"'; - - template += ' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event);"' + - ' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' + - ' onmousedown="return CKEDITOR.tools.callFunction({mousedownFn},event);" ' + - ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // #188 - '="CKEDITOR.tools.callFunction({clickFn},this);return false;">' + - '<span class="cke_button_icon cke_button__{iconName}_icon" style="{style}"'; - - - template += '> </span>' + - '<span id="{id}_label" class="cke_button_label cke_button__{name}_label" aria-hidden="false">{label}</span>' + - '{arrowHtml}' + - '</a>'; - - var templateArrow = '<span class="cke_button_arrow">' + - // BLACK DOWN-POINTING TRIANGLE - ( CKEDITOR.env.hc ? '▼' : '' ) + - '</span>'; - - var btnArrowTpl = CKEDITOR.addTemplate( 'buttonArrow', templateArrow ), - btnTpl = CKEDITOR.addTemplate( 'button', template ); - - CKEDITOR.plugins.add( 'button', { - beforeInit: function( editor ) { - editor.ui.addHandler( CKEDITOR.UI_BUTTON, CKEDITOR.ui.button.handler ); - } - }); - - /** - * Button UI element. - * - * @readonly - * @property {String} [='button'] - * @member CKEDITOR - */ - CKEDITOR.UI_BUTTON = 'button'; - - /** - * Represents a button UI element. This class should not be called directly. To - * create new buttons use {@link CKEDITOR.ui#addButton} instead. - * - * @class - * @constructor Creates a button class instance. - * @param {Object} definition The button definition. - */ - CKEDITOR.ui.button = function( definition ) { - CKEDITOR.tools.extend( this, definition, - // Set defaults. - { - title: definition.label, - click: definition.click || - function( editor ) { - editor.execCommand( definition.command ); - } - }); - - this._ = {}; - }; - - /** - * Represents button handler object. - * - * @class - * @singleton - * @extends CKEDITOR.ui.handlerDefinition - */ - CKEDITOR.ui.button.handler = { - /** - * Transforms a button definition in a {@link CKEDITOR.ui.button} instance. - * - * @member CKEDITOR.ui.button.handler - * @param {Object} definition - * @returns {CKEDITOR.ui.button} - */ - create: function( definition ) { - return new CKEDITOR.ui.button( definition ); - } - }; - - /** @class CKEDITOR.ui.button */ - CKEDITOR.ui.button.prototype = { - /** - * Renders the button. - * - * @param {CKEDITOR.editor} editor The editor instance which this button is - * to be used by. - * @param {Array} output The output array to which append the HTML relative - * to this button. - */ - render: function( editor, output ) { - var env = CKEDITOR.env, - id = this._.id = CKEDITOR.tools.getNextId(), - stateName = '', - command = this.command, - // Get the command name. - clickFn; - - this._.editor = editor; - - var instance = { - id: id, - button: this, - editor: editor, - focus: function() { - var element = CKEDITOR.document.getById( id ); - element.focus(); - }, - execute: function() { - this.button.click( editor ); - }, - attach: function( editor ) { - this.button.attach( editor ); - } - }; - - var keydownFn = CKEDITOR.tools.addFunction( function( ev ) { - if ( instance.onkey ) { - ev = new CKEDITOR.dom.event( ev ); - return ( instance.onkey( instance, ev.getKeystroke() ) !== false ); - } - }); - - var focusFn = CKEDITOR.tools.addFunction( function( ev ) { - var retVal; - - if ( instance.onfocus ) - retVal = ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false ); - - // FF2: prevent focus event been bubbled up to editor container, which caused unexpected editor focus. - if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) - ev.preventBubble(); - return retVal; - }); - - var selLocked = 0; - - var mousedownFn = CKEDITOR.tools.addFunction( function() { - // Opera: lock to prevent loosing editable text selection when clicking on button. - if ( CKEDITOR.env.opera ) { - var edt = editor.editable(); - if ( edt.isInline() && edt.hasFocus ) { - editor.lockSelection(); - selLocked = 1; - } - } - }); - - instance.clickFn = clickFn = CKEDITOR.tools.addFunction( function() { - - // Restore locked selection in Opera. - if ( selLocked ) { - editor.unlockSelection( 1 ); - selLocked = 0; - } - - instance.execute(); - }); - - - // Indicate a mode sensitive button. - if ( this.modes ) { - var modeStates = {}; - - function updateState() { - // "this" is a CKEDITOR.ui.button instance. - - var mode = editor.mode; - - if ( mode ) { - // Restore saved button state. - var state = this.modes[ mode ] ? modeStates[ mode ] != undefined ? modeStates[ mode ] : CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; - - this.setState( editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state ); - } - } - - editor.on( 'beforeModeUnload', function() { - if ( editor.mode && this._.state != CKEDITOR.TRISTATE_DISABLED ) - modeStates[ editor.mode ] = this._.state; - }, this ); - - editor.on( 'mode', updateState, this ); - - // If this button is sensitive to readOnly state, update it accordingly. - !this.readOnly && editor.on( 'readOnly', updateState, this ); - } else if ( command ) { - // Get the command instance. - command = editor.getCommand( command ); - - if ( command ) { - command.on( 'state', function() { - this.setState( command.state ); - }, this ); - - stateName += ( command.state == CKEDITOR.TRISTATE_ON ? 'on' : command.state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off' ); - } - } - - // For button that has text-direction awareness on selection path. - if ( this.directional ) { - editor.on( 'contentDirChanged', function( evt ) { - var el = CKEDITOR.document.getById( this._.id ), - icon = el.getFirst(); - - var pathDir = evt.data; - - // Make a minor direction change to become style-able for the skin icon. - if ( pathDir != editor.lang.dir ) - el.addClass( 'cke_' + pathDir ); - else - el.removeClass( 'cke_ltr' ).removeClass( 'cke_rtl' ); - - // Inline style update for the plugin icon. - icon.setAttribute( 'style', CKEDITOR.skin.getIconStyle( iconName, pathDir == 'rtl', this.icon, this.iconOffset ) ); - }, this ); - } - - if ( !command ) - stateName += 'off'; - - var name = this.name || this.command, - iconName = name; - - // Check if we're pointing to an icon defined by another command. (#9555) - if ( this.icon && !( /\./ ).test( this.icon ) ) { - iconName = this.icon; - this.icon = null; - } - - var params = { - id: id, - name: name, - iconName: iconName, - label: this.label, - cls: this.className || '', - state: stateName, - title: this.title, - titleJs: env.gecko && env.version >= 10900 && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ), - hasArrow: this.hasArrow ? 'true' : 'false', - keydownFn: keydownFn, - mousedownFn: mousedownFn, - focusFn: focusFn, - clickFn: clickFn, - style: CKEDITOR.skin.getIconStyle( iconName, ( editor.lang.dir == 'rtl' ), this.icon, this.iconOffset ), - arrowHtml: this.hasArrow ? btnArrowTpl.output() : '' - }; - - btnTpl.output( params, output ); - - if ( this.onRender ) - this.onRender(); - - return instance; - }, - - /** - * @todo - */ - setState: function( state ) { - if ( this._.state == state ) - return false; - - this._.state = state; - - var element = CKEDITOR.document.getById( this._.id ); - - if ( element ) { - element.setState( state, 'cke_button' ); - - state == CKEDITOR.TRISTATE_DISABLED ? - element.setAttribute( 'aria-disabled', true ) : - element.removeAttribute( 'aria-disabled' ); - - state == CKEDITOR.TRISTATE_ON ? - element.setAttribute( 'aria-pressed', true ) : - element.removeAttribute( 'aria-pressed' ); - - return true; - } else - return false; - }, - - /** - * Returns this button's {@link CKEDITOR.feature} instance. - * - * It may be this button instance if it has at least one of - * `allowedContent` and `requiredContent` properties. Otherwise, - * if command is bound to this button by `command` property, then - * that command will be returned. - * - * This method implements {@link CKEDITOR.feature#toFeature} interface method. - * - * @since 4.1 - * @param {CKEDITOR.editor} Editor instance. - * @returns {CKEDITOR.feature} The feature. - */ - toFeature: function( editor ) { - if ( this._.feature ) - return this._.feature; - - var feature = this; - - // If button isn't a feature, return command if is bound. - if ( !this.allowedContent && !this.requiredContent && this.command ) - feature = editor.getCommand( this.command ) || feature; - - return this._.feature = feature; - } - }; - - /** - * Adds a button definition to the UI elements list. - * - * editorInstance.ui.addButton( 'MyBold', { - * label: 'My Bold', - * command: 'bold', - * toolbar: 'basicstyles,1' - * } ); - * - * @member CKEDITOR.ui - * @param {String} name The button name. - * @param {Object} definition The button definition. - */ - CKEDITOR.ui.prototype.addButton = function( name, definition ) { - this.add( name, CKEDITOR.UI_BUTTON, definition ); - }; - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/dev/clipboard.html b/addons/website/static/lib/ckeditor/plugins/clipboard/dev/clipboard.html deleted file mode 100644 index 705dc472b72..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/dev/clipboard.html +++ /dev/null @@ -1,194 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license ---> -<html> -<head> - <meta charset="utf-8"> - <title>Clipboard playground – CKEditor Sample</title> - <script src="../../../ckeditor.js"></script> - <link href="../../../samples/sample.css" rel="stylesheet"> - <style> -body { - margin: 0; -} - -#editables, #console -{ - width: 48%; -} -#editable { - padding: 5px 10px; -} - -#console { - position: fixed; - top: 10px; - right: 30px; - height: 500px; - border: solid 3px #555; - overflow: auto; -} -#console > p { - border-bottom: solid 1px #555; - margin: 0; - padding: 0 5px; - background: rgba(0, 0, 0, 0.25); - -webkit-transition: background-color 1s; - -moz-transition: background-color 1s; - -o-transition: background-color 1s; - -ms-transition: background-color 1s; - transition: background-color 1s; -} -#console > p.old { - background: rgba(0, 0, 0, 0); -} -#console time, #console .prompt { - padding: 0 5px; - display: inline-block; -} -#console time { - background: #999; - background: rgba(0, 0, 0, 0.5 ); - color: #FFF; - margin-left: -5px; -} -#console .prompt { - background: #DDD; - background: rgba(0, 0, 0, 0.1 ); - min-width: 200px; -} -.someClass { - color: blue; -} -.specChar { - color: #777; - background-color: #EEE; - background-color: rgba(0, 0, 0, 0.1); - font-size: 0.8em; - border-radius: 2px; - padding: 1px; -} - </style> -</head> -<body> - <h1 class="samples"> - CKEditor Sample — clipboard plugin playground - </h1> - <div id="editables"> - <p> - <label for="editor1"> - Editor 1:</label> - <textarea cols="80" id="editor1" name="editor1" rows="10"><p>This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.</p></textarea> - </p> - <p> - <label for="editor2"> - Editor 2:</label> - <textarea cols="80" id="editor2" name="editor2" rows="10"><p>This is more <strong class="MsoNormal">sample text</strong>.</p></textarea> - </p> - <p> - <label for="editor3"> - Editor 3:</label> - <textarea cols="80" id="editor3" name="editor3" rows="10"><p>This editor <strong>forces pasting in text mode</strong> by listening for "beforePaste" event.</p></textarea> - </p> - <p> - <label for="editor4"> - Editor 4:</label> - <textarea cols="80" id="editor4" name="editor4" rows="10"><p>This editor <strong>forces pasting in text mode</strong> by "forcePasteAsPlainText" config option.</p></textarea> - </p> - <p> - <label for="editor5"> - Editor 5:</label> - <textarea cols="80" id="editor5" name="editor5" rows="10">Editor with autoParagraphing set to off.</textarea> - </p> - <div id="editor6" contenteditable="true" style="font-family: Georgia; font-size: 14px"> - <h1>Editor 6</h1> - <p>Content content content.</p> - <p class="someClass">Styled by <code>.someClass</code>.</p> - </div> - </div> - <div id="console"> - </div> - <script> -( function() -{ - 'use strict'; - - var log = window.__log = function( title, msg ) { - var msgEl = new CKEDITOR.dom.element( 'p' ), - consoleEl = CKEDITOR.document.getById( 'console' ), - time = new Date().toString().match( /\d\d:\d\d:\d\d/ )[ 0 ], - format = function( tpl ) { - return tpl.replace( /{time}/g, time ).replace( '{title}', title ).replace( '{msg}', msg || '' ); - }; - - window.console && console.log && console.log( format( '[{time}] {title}: {msg}' ) ); - - msg = ( msg || '' ).replace( /\r/g, '{\\r}' ).replace( /\n/g, '{\\n}' ).replace( /\t/g, '{\\t}' ); - msg = CKEDITOR.tools.htmlEncode( msg ); - msg = msg.replace( /\{(\\\w)\}/g, '<code class="specChar">$1</code>' ); - - msgEl.setHtml( format( '<time datetime="{time}">{time}</time><span class="prompt">{title}</span> {msg}' ) ); - consoleEl.append( msgEl ); - consoleEl.$.scrollTop = consoleEl.$.scrollHeight; - setTimeout( function() { msgEl.addClass( 'old' ); }, 250 ); - }; - - var observe = function( editor, num ) { - var p = 'EDITOR ' + num + ' > '; - - editor.on( 'paste', function( event ) { - log( p + 'paste(prior:-1)', event.data.type + ' - "' + event.data.dataValue + '"' ); - }, null, null, -1 ); - editor.on( 'paste', function( event ) { - log( p + 'paste(prior:10)', event.data.type + ' - "' + event.data.dataValue + '"' ); - } ); - editor.on( 'paste', function( event ) { - log( p + 'paste(prior:999)', event.data.type + ' - "' + event.data.dataValue + '"' ); - }, null, null, 999 ); - editor.on( 'beforePaste', function( event ) { - log( p + 'beforePaste', event.data.type ); - } ); - editor.on( 'beforePaste', function( event ) { - log( p + 'beforePaste(prior:999)', event.data.type ); - }, null, null, 999 ); - editor.on( 'afterPaste', function( event ) { - log( p + 'afterPaste' ); - } ); - editor.on( 'copy', function( event ) { - log( p + 'copy' ); - } ); - editor.on( 'cut', function( event ) { - log( p + 'cut' ); - } ); - }; - - CKEDITOR.disableAutoInline = true; - var config = { - height: 120, - toolbar: [ [ 'Source' ] ], - allowedContent: true - }, - editor1 = CKEDITOR.replace( 'editor1', config ), - editor2 = CKEDITOR.replace( 'editor2', config ), - editor3 = CKEDITOR.replace( 'editor3', config ), - editor4 = CKEDITOR.replace( 'editor4', CKEDITOR.tools.extend( { forcePasteAsPlainText: true }, config ) ), - editor5 = CKEDITOR.replace( 'editor5', CKEDITOR.tools.extend( { autoParagraph: false }, config ) ), - editor6 = CKEDITOR.inline( document.getElementById( 'editor6' ), config ); - - editor3.on( 'beforePaste', function( evt ) { - evt.data.type = 'text'; - } ); - - observe( editor1, 1 ); - observe( editor2, 2 ); - observe( editor3, 3 ); - observe( editor4, 4 ); - observe( editor5, 5 ); - observe( editor6, 6 ); - -})(); - </script> -</body> -</html> diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/dialogs/paste.js b/addons/website/static/lib/ckeditor/plugins/clipboard/dialogs/paste.js deleted file mode 100644 index 3cf011ba0ea..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/dialogs/paste.js +++ /dev/null @@ -1,228 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'paste', function( editor ) { - var lang = editor.lang.clipboard; - - function onPasteFrameLoad( win ) { - var doc = new CKEDITOR.dom.document( win.document ), - body = doc.getBody(), - script = doc.getById( 'cke_actscrpt' ); - - script && script.remove(); - - body.setAttribute( 'contenteditable', true ); - - // IE before version 8 will leave cursor blinking inside the document after - // editor blurred unless we clean up the selection. (#4716) - if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) { - doc.getWindow().on( 'blur', function() { - doc.$.selection.empty(); - }); - } - - doc.on( 'keydown', function( e ) { - var domEvent = e.data, - key = domEvent.getKeystroke(), - processed; - - switch ( key ) { - case 27: - this.hide(); - processed = 1; - break; - - case 9: - case CKEDITOR.SHIFT + 9: - this.changeFocus( 1 ); - processed = 1; - } - - processed && domEvent.preventDefault(); - }, this ); - - editor.fire( 'ariaWidget', new CKEDITOR.dom.element( win.frameElement ) ); - - // Handle pending focus. - if ( doc.getWindow().getFrame().removeCustomData( 'pendingFocus' ) ) - body.focus(); - } - - // If pasteDialogCommit wasn't canceled by e.g. editor.getClipboardData - // then fire paste event. - // Do not use editor#paste, because it would start from beforePaste event. - editor.on( 'pasteDialogCommit', function( evt ) { - if ( evt.data ) - editor.fire( 'paste', { type: 'auto', dataValue: evt.data } ); - }, null, null, 1000 ); - - return { - title: lang.title, - - minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350, - minHeight: CKEDITOR.env.quirks ? 250 : 245, - onShow: function() { - // FIREFOX BUG: Force the browser to render the dialog to make the to-be- - // inserted iframe editable. (#3366) - this.parts.dialog.$.offsetHeight; - - this.setupContent(); - - // Set dialog title to the custom value (set e.g. in editor.openDialog callback) and reset this value. - // If custom title not set, use default one. - this.parts.title.setHtml( this.customTitle || lang.title ); - this.customTitle = null; - }, - - onLoad: function() { - if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' ) - this.parts.contents.setStyle( 'overflow', 'hidden' ); - }, - - onOk: function() { - this.commitContent(); - }, - - contents: [ - { - id: 'general', - label: editor.lang.common.generalTab, - elements: [ - { - type: 'html', - id: 'securityMsg', - html: '<div style="white-space:normal;width:340px">' + lang.securityMsg + '</div>' - }, - { - type: 'html', - id: 'pasteMsg', - html: '<div style="white-space:normal;width:340px">' + lang.pasteMsg + '</div>' - }, - { - type: 'html', - id: 'editing_area', - style: 'width:100%;height:100%', - html: '', - focus: function() { - var iframe = this.getInputElement(), - doc = iframe.getFrameDocument(), - body = doc.getBody(); - - // Frame content may not loaded at the moment. - if ( !body || body.isReadOnly() ) - iframe.setCustomData( 'pendingFocus', 1 ); - else - body.focus(); - }, - setup: function() { - var dialog = this.getDialog(); - var htmlToLoad = '<html dir="' + editor.config.contentsLangDirection + '"' + - ' lang="' + ( editor.config.contentsLanguage || editor.langCode ) + '">' + - '<head><style>body{margin:3px;height:95%}</style></head><body>' + - '<script id="cke_actscrpt" type="text/javascript">' + - 'window.parent.CKEDITOR.tools.callFunction(' + CKEDITOR.tools.addFunction( onPasteFrameLoad, dialog ) + ',this);' + - '</script></body>' + - '</html>'; - - var src = - CKEDITOR.env.air ? - 'javascript:void(0)' : - CKEDITOR.env.ie ? - 'javascript:void((function(){' + encodeURIComponent( - 'document.open();' + - '(' + CKEDITOR.tools.fixDomain + ')();' + - 'document.close();' - ) + '})())"' - : ''; - - var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' + - ' class="cke_pasteframe"' + - ' frameborder="0" ' + - ' allowTransparency="true"' + - ' src="' + src + '"' + - ' role="region"' + - ' aria-label="' + lang.pasteArea + '"' + - ' aria-describedby="' + dialog.getContentElement( 'general', 'pasteMsg' ).domId + '"' + - ' aria-multiple="true"' + - '></iframe>' ); - - iframe.on( 'load', function( e ) { - e.removeListener(); - - var doc = iframe.getFrameDocument(); - doc.write( htmlToLoad ); - - editor.focusManager.add( doc.getBody() ); - - if ( CKEDITOR.env.air ) - onPasteFrameLoad.call( this, doc.getWindow().$ ); - }, dialog ); - - iframe.setCustomData( 'dialog', dialog ); - - var container = this.getElement(); - container.setHtml( '' ); - container.append( iframe ); - - // IE need a redirect on focus to make - // the cursor blinking inside iframe. (#5461) - if ( CKEDITOR.env.ie ) { - var focusGrabber = CKEDITOR.dom.element.createFromHtml( '<span tabindex="-1" style="position:absolute" role="presentation"></span>' ); - focusGrabber.on( 'focus', function() { - // Since fixDomain is called in src attribute, - // IE needs some slight delay to correctly move focus. - setTimeout( function() { - iframe.$.contentWindow.focus(); - } ); - } ); - container.append( focusGrabber ); - - // Override focus handler on field. - this.focus = function() { - focusGrabber.focus(); - this.fire( 'focus' ); - }; - } - - this.getInputElement = function() { - return iframe; - }; - - // Force container to scale in IE. - if ( CKEDITOR.env.ie ) { - container.setStyle( 'display', 'block' ); - container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' ); - } - }, - commit: function( data ) { - var editor = this.getDialog().getParentEditor(), - body = this.getInputElement().getFrameDocument().getBody(), - bogus = body.getBogus(), - html; - bogus && bogus.remove(); - - // Saving the contents so changes until paste is complete will not take place (#7500) - html = body.getHtml(); - - // Opera needs some time to think about what has happened and what it should do now. - setTimeout( function() { - editor.fire( 'pasteDialogCommit', html ); - }, 0 ); - } - } - ] - } - ] - }; -}); - -/** - * Internal event to pass paste dialog's data to the listeners. - * - * @private - * @event pasteDialogCommit - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy-rtl.png Binary files differdeleted file mode 100644 index ef724460c1d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy.png Binary files differdeleted file mode 100644 index ef724460c1d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/copy.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut-rtl.png Binary files differdeleted file mode 100644 index 0b719653662..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut.png Binary files differdeleted file mode 100644 index 0b719653662..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/cut.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy-rtl.png Binary files differdeleted file mode 100644 index 29026cc0aa5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy.png Binary files differdeleted file mode 100644 index 29026cc0aa5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/copy.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut-rtl.png Binary files differdeleted file mode 100644 index bfec0cfb9e9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut.png Binary files differdeleted file mode 100644 index bfec0cfb9e9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/cut.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste-rtl.png Binary files differdeleted file mode 100644 index f18dac3749b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste.png Binary files differdeleted file mode 100644 index f18dac3749b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/hidpi/paste.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste-rtl.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste-rtl.png Binary files differdeleted file mode 100644 index b2bfef2037e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste.png b/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste.png Binary files differdeleted file mode 100644 index b2bfef2037e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/icons/paste.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/lang/en.js b/addons/website/static/lib/ckeditor/plugins/clipboard/lang/en.js deleted file mode 100644 index 61de6044d4c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/lang/en.js +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'clipboard', 'en', { - copy: 'Copy', - copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).', - cut: 'Cut', - cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', - paste: 'Paste', - pasteArea: 'Paste Area', - pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', - securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', - title: 'Paste' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/clipboard/plugin.js b/addons/website/static/lib/ckeditor/plugins/clipboard/plugin.js deleted file mode 100644 index 8f063a170a2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/clipboard/plugin.js +++ /dev/null @@ -1,1238 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @ignore - * File overview: Clipboard support. - */ - -// -// EXECUTION FLOWS: -// -- CTRL+C -// * browser's default behaviour -// -- CTRL+V -// * listen onKey (onkeydown) -// * simulate 'beforepaste' for non-IEs on editable -// * simulate 'paste' for Fx2/Opera on editable -// * listen 'onpaste' on editable ('onbeforepaste' for IE) -// * fire 'beforePaste' on editor -// * !canceled && getClipboardDataByPastebin -// * fire 'paste' on editor -// * !canceled && fire 'afterPaste' on editor -// -- CTRL+X -// * listen onKey (onkeydown) -// * fire 'saveSnapshot' on editor -// * browser's default behaviour -// * deferred second 'saveSnapshot' event -// -- Copy command -// * tryToCutCopy -// * execCommand -// * !success && alert -// -- Cut command -// * fixCut -// * tryToCutCopy -// * execCommand -// * !success && alert -// -- Paste command -// * fire 'paste' on editable ('beforepaste' for IE) -// * !canceled && execCommand 'paste' -// * !success && fire 'pasteDialog' on editor -// -- Paste from native context menu & menubar -// (Fx & Webkits are handled in 'paste' default listner. -// Opera cannot be handled at all because it doesn't fire any events -// Special treatment is needed for IE, for which is this part of doc) -// * listen 'onpaste' -// * cancel native event -// * fire 'beforePaste' on editor -// * !canceled && getClipboardDataByPastebin -// * execIECommand( 'paste' ) -> this fires another 'paste' event, so cancel it -// * fire 'paste' on editor -// * !canceled && fire 'afterPaste' on editor -// -// -// PASTE EVENT - PREPROCESSING: -// -- Possible dataValue types: auto, text, html. -// -- Possible dataValue contents: -// * text (possible \n\r) -// * htmlified text (text + br,div,p - no presentional markup & attrs - depends on browser) -// * html -// -- Possible flags: -// * htmlified - if true then content is a HTML even if no markup inside. This flag is set -// for content from editable pastebins, because they 'htmlify' pasted content. -// -// -- Type: auto: -// * content: htmlified text -> filter, unify text markup (brs, ps, divs), set type: text -// * content: html -> filter, set type: html -// -- Type: text: -// * content: htmlified text -> filter, unify text markup -// * content: html -> filter, strip presentional markup, unify text markup -// -- Type: html: -// * content: htmlified text -> filter, unify text markup -// * content: html -> filter -// -// -- Phases: -// * filtering (priorities 3-5) - e.g. pastefromword filters -// * content type sniffing (priority 6) -// * markup transformations for text (priority 6) -// - -'use strict'; - -(function() { - // Register the plugin. - CKEDITOR.plugins.add( 'clipboard', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'copy,copy-rtl,cut,cut-rtl,paste,paste-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var textificationFilter; - - initClipboard( editor ); - - CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) ); - - editor.on( 'paste', function( evt ) { - var data = evt.data.dataValue, - blockElements = CKEDITOR.dtd.$block; - - // Filter webkit garbage. - if ( data.indexOf( 'Apple-' ) > -1 ) { - // Replace special webkit's with simple space, because webkit - // produces them even for normal spaces. - data = data.replace( /<span class="Apple-converted-space"> <\/span>/gi, ' ' ); - - // Strip <span> around white-spaces when not in forced 'html' content type. - // This spans are created only when pasting plain text into Webkit, - // but for safety reasons remove them always. - if ( evt.data.type != 'html' ) - data = data.replace( /<span class="Apple-tab-span"[^>]*>([^<]*)<\/span>/gi, function( all, spaces ) { - // Replace tabs with 4 spaces like Fx does. - return spaces.replace( /\t/g, ' ' ); - }); - - // This br is produced only when copying & pasting HTML content. - if ( data.indexOf( '<br class="Apple-interchange-newline">' ) > -1 ) { - evt.data.startsWithEOL = 1; - evt.data.preSniffing = 'html'; // Mark as not text. - data = data.replace( /<br class="Apple-interchange-newline">/, '' ); - } - - // Remove all other classes. - data = data.replace( /(<[^>]+) class="Apple-[^"]*"/gi, '$1' ); - } - - // Strip editable that was copied from inside. (#9534) - if ( data.match( /^<[^<]+cke_(editable|contents)/i ) ) { - var tmp, - editable_wrapper, - wrapper = new CKEDITOR.dom.element( 'div' ); - - wrapper.setHtml( data ); - // Verify for sure and check for nested editor UI parts. (#9675) - while ( wrapper.getChildCount() == 1 && - ( tmp = wrapper.getFirst() ) && - tmp.type == CKEDITOR.NODE_ELEMENT && // Make sure first-child is element. - ( tmp.hasClass( 'cke_editable' ) || tmp.hasClass( 'cke_contents' ) ) ) { - wrapper = editable_wrapper = tmp; - } - - // If editable wrapper was found strip it and bogus <br> (added on FF). - if ( editable_wrapper ) - data = editable_wrapper.getHtml().replace( /<br>$/i, '' ); - } - - if ( CKEDITOR.env.ie ) { - // <p> -> <p> (br.cke-pasted-remove will be removed later) - data = data.replace( /^ (?: |\r\n)?<(\w+)/g, function( match, elementName ) { - if ( elementName.toLowerCase() in blockElements ) { - evt.data.preSniffing = 'html'; // Mark as not a text. - return '<' + elementName; - } - return match; - }); - } else if ( CKEDITOR.env.webkit ) { - // </p><div><br></div> -> </p><br> - // We don't mark br, because this situation can happen for htmlified text too. - data = data.replace( /<\/(\w+)><div><br><\/div>$/, function( match, elementName ) { - if ( elementName in blockElements ) { - evt.data.endsWithEOL = 1; - return '</' + elementName + '>'; - } - return match; - }); - } else if ( CKEDITOR.env.gecko ) { - // Firefox adds bogus <br> when user pasted text followed by space(s). - data = data.replace( /(\s)<br>$/, '$1' ); - } - - evt.data.dataValue = data; - }, null, null, 3 ); - - editor.on( 'paste', function( evt ) { - var dataObj = evt.data, - type = dataObj.type, - data = dataObj.dataValue, - trueType, - // Default is 'html'. - defaultType = editor.config.clipboard_defaultContentType || 'html'; - - // If forced type is 'html' we don't need to know true data type. - if ( type == 'html' || dataObj.preSniffing == 'html' ) - trueType = 'html'; - else - trueType = recogniseContentType( data ); - - // Unify text markup. - if ( trueType == 'htmlifiedtext' ) - data = htmlifiedTextHtmlification( editor.config, data ); - // Strip presentional markup & unify text markup. - else if ( type == 'text' && trueType == 'html' ) { - // Init filter only if needed and cache it. - data = htmlTextification( editor.config, data, textificationFilter || ( textificationFilter = getTextificationFilter( editor ) ) ); - } - - if ( dataObj.startsWithEOL ) - data = '<br data-cke-eol="1">' + data; - if ( dataObj.endsWithEOL ) - data += '<br data-cke-eol="1">'; - - if ( type == 'auto' ) - type = ( trueType == 'html' || defaultType == 'html' ) ? 'html' : 'text'; - - dataObj.type = type; - dataObj.dataValue = data; - delete dataObj.preSniffing; - delete dataObj.startsWithEOL; - delete dataObj.endsWithEOL; - }, null, null, 6 ); - - // Inserts processed data into the editor at the end of the - // events chain. - editor.on( 'paste', function( evt ) { - var data = evt.data; - - editor.insertHtml( data.dataValue, data.type ); - - // Deferr 'afterPaste' so all other listeners for 'paste' will be fired first. - setTimeout( function() { - editor.fire( 'afterPaste' ); - }, 0 ); - }, null, null, 1000 ); - - editor.on( 'pasteDialog', function( evt ) { - // TODO it's possible that this setTimeout is not needed any more, - // because of changes introduced in the same commit as this comment. - // Editor.getClipboardData adds listner to the dialog's events which are - // fired after a while (not like 'showDialog'). - setTimeout( function() { - // Open default paste dialog. - editor.openDialog( 'paste', evt.data ); - }, 0 ); - }); - } - }); - - function initClipboard( editor ) { - var preventBeforePasteEvent = 0, - preventPasteEvent = 0, - inReadOnly = 0, - // Safari doesn't like 'beforepaste' event - it sometimes doesn't - // properly handles ctrl+c. Probably some race-condition between events. - // Chrome and Firefox works well with both events, so better to use 'paste' - // which will handle pasting from e.g. browsers' menu bars. - // IE7/8 doesn't like 'paste' event for which it's throwing random errors. - mainPasteEvent = CKEDITOR.env.ie ? 'beforepaste' : 'paste'; - - addListeners(); - addButtonsCommands(); - - /** - * Gets clipboard data by directly accessing the clipboard (IE only) or opening paste dialog. - * - * editor.getClipboardData( { title: 'Get my data' }, function( data ) { - * if ( data ) - * alert( data.type + ' ' + data.dataValue ); - * } ); - * - * @member CKEDITOR.editor - * @param {Object} options - * @param {String} [options.title] Title of paste dialog. - * @param {Function} callback Function that will be executed with `data.type` and `data.dataValue` - * or `null` if none of the capturing method succeeded. - */ - editor.getClipboardData = function( options, callback ) { - var beforePasteNotCanceled = false, - dataType = 'auto', - dialogCommited = false; - - // Options are optional - args shift. - if ( !callback ) { - callback = options; - options = null; - } - - // Listen with maximum priority to handle content before everyone else. - // This callback will handle paste event that will be fired if direct - // access to the clipboard succeed in IE. - editor.on( 'paste', onPaste, null, null, 0 ); - - // Listen at the end of listeners chain to see if event wasn't canceled - // and to retrieve modified data.type. - editor.on( 'beforePaste', onBeforePaste, null, null, 1000 ); - - // getClipboardDataDirectly() will fire 'beforePaste' synchronously, so we can - // check if it was canceled and if any listener modified data.type. - - // If command didn't succeed (only IE allows to access clipboard and only if - // user agrees) open and handle paste dialog. - if ( getClipboardDataDirectly() === false ) { - // Direct access to the clipboard wasn't successful so remove listener. - editor.removeListener( 'paste', onPaste ); - - // If beforePaste was canceled do not open dialog. - // Add listeners only if dialog really opened. 'pasteDialog' can be canceled. - if ( beforePasteNotCanceled && editor.fire( 'pasteDialog', onDialogOpen ) ) { - editor.on( 'pasteDialogCommit', onDialogCommit ); - - // 'dialogHide' will be fired after 'pasteDialogCommit'. - editor.on( 'dialogHide', function( evt ) { - evt.removeListener(); - evt.data.removeListener( 'pasteDialogCommit', onDialogCommit ); - - // Because Opera has to wait a while in pasteDialog we have to wait here. - setTimeout( function() { - // Notify even if user canceled dialog (clicked 'cancel', ESC, etc). - if ( !dialogCommited ) - callback( null ); - }, 10 ); - }); - } else - callback( null ); - } - - function onPaste( evt ) { - evt.removeListener(); - evt.cancel(); - callback( evt.data ); - } - - function onBeforePaste( evt ) { - evt.removeListener(); - beforePasteNotCanceled = true; - dataType = evt.data.type; - } - - function onDialogCommit( evt ) { - evt.removeListener(); - // Cancel pasteDialogCommit so paste dialog won't automatically fire - // 'paste' evt by itself. - evt.cancel(); - dialogCommited = true; - callback( { type: dataType, dataValue: evt.data } ); - } - - function onDialogOpen() { - this.customTitle = ( options && options.title ); - } - }; - - function addButtonsCommands() { - addButtonCommand( 'Cut', 'cut', createCutCopyCmd( 'cut' ), 10, 1 ); - addButtonCommand( 'Copy', 'copy', createCutCopyCmd( 'copy' ), 20, 4 ); - addButtonCommand( 'Paste', 'paste', createPasteCmd(), 30, 8 ); - - function addButtonCommand( buttonName, commandName, command, toolbarOrder, ctxMenuOrder ) { - var lang = editor.lang.clipboard[ commandName ]; - - editor.addCommand( commandName, command ); - editor.ui.addButton && editor.ui.addButton( buttonName, { - label: lang, - command: commandName, - toolbar: 'clipboard,' + toolbarOrder - }); - - // If the "menu" plugin is loaded, register the menu item. - if ( editor.addMenuItems ) { - editor.addMenuItem( commandName, { - label: lang, - command: commandName, - group: 'clipboard', - order: ctxMenuOrder - }); - } - } - } - - function addListeners() { - editor.on( 'key', onKey ); - editor.on( 'contentDom', addListenersToEditable ); - - // For improved performance, we're checking the readOnly state on selectionChange instead of hooking a key event for that. - editor.on( 'selectionChange', function( evt ) { - inReadOnly = evt.data.selection.getRanges()[ 0 ].checkReadOnly(); - setToolbarStates(); - }); - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - inReadOnly = selection.getRanges()[ 0 ].checkReadOnly(); - return { - cut: stateFromNamedCommand( 'Cut' ), - copy: stateFromNamedCommand( 'Copy' ), - paste: stateFromNamedCommand( 'Paste' ) - }; - }); - } - } - - // Add events listeners to editable. - function addListenersToEditable() { - var editable = editor.editable(); - - // We'll be catching all pasted content in one line, regardless of whether - // it's introduced by a document command execution (e.g. toolbar buttons) or - // user paste behaviors (e.g. CTRL+V). - editable.on( mainPasteEvent, function( evt ) { - if ( CKEDITOR.env.ie && preventBeforePasteEvent ) - return; - - // If you've just asked yourself why preventPasteEventNow() is not here, but - // in listener for CTRL+V and exec method of 'paste' command - // you've asked the same question we did. - // - // THE ANSWER: - // - // First thing to notice - this answer makes sense only for IE, - // because other browsers don't listen for 'paste' event. - // - // What would happen if we move preventPasteEventNow() here? - // For: - // * CTRL+V - IE fires 'beforepaste', so we prevent 'paste' and pasteDataFromClipboard(). OK. - // * editor.execCommand( 'paste' ) - we fire 'beforepaste', so we prevent - // 'paste' and pasteDataFromClipboard() and doc.execCommand( 'Paste' ). OK. - // * native context menu - IE fires 'beforepaste', so we prevent 'paste', but unfortunately - // on IE we fail with pasteDataFromClipboard() here, because of... we don't know why, but - // we just fail, so... we paste nothing. FAIL. - // * native menu bar - the same as for native context menu. - // - // But don't you know any way to distinguish first two cases from last two? - // Only one - special flag set in CTRL+V handler and exec method of 'paste' - // command. And that's what we did using preventPasteEventNow(). - - pasteDataFromClipboard( evt ); - }); - - // It's not possible to clearly handle all four paste methods (ctrl+v, native menu bar - // native context menu, editor's command) in one 'paste/beforepaste' event in IE. - // - // For ctrl+v & editor's command it's easy to handle pasting in 'beforepaste' listener, - // so we do this. For another two methods it's better to use 'paste' event. - // - // 'paste' is always being fired after 'beforepaste' (except of weird one on opening native - // context menu), so for two methods handled in 'beforepaste' we're canceling 'paste' - // using preventPasteEvent state. - // - // 'paste' event in IE is being fired before getClipboardDataByPastebin executes its callback. - // - // QUESTION: Why didn't you handle all 4 paste methods in handler for 'paste'? - // Wouldn't this just be simpler? - // ANSWER: Then we would have to evt.data.preventDefault() only for native - // context menu and menu bar pastes. The same with execIECommand(). - // That would force us to mark CTRL+V and editor's paste command with - // special flag, other than preventPasteEvent. But we still would have to - // have preventPasteEvent for the second event fired by execIECommand. - // Code would be longer and not cleaner. - CKEDITOR.env.ie && editable.on( 'paste', function( evt ) { - if ( preventPasteEvent ) - return; - // Cancel next 'paste' event fired by execIECommand( 'paste' ) - // at the end of this callback. - preventPasteEventNow(); - - // Prevent native paste. - evt.data.preventDefault(); - - pasteDataFromClipboard( evt ); - - // Force IE to paste content into pastebin so pasteDataFromClipboard will work. - if ( !execIECommand( 'paste' ) ) - editor.openDialog( 'paste' ); - }); - - // [IE] Dismiss the (wrong) 'beforepaste' event fired on context/toolbar menu open. (#7953) - if ( CKEDITOR.env.ie ) { - editable.on( 'contextmenu', preventBeforePasteEventNow, null, null, 0 ); - - editable.on( 'beforepaste', function( evt ) { - if ( evt.data && !evt.data.$.ctrlKey ) - preventBeforePasteEventNow(); - }, null, null, 0 ); - - } - - editable.on( 'beforecut', function() { - !preventBeforePasteEvent && fixCut( editor ); - }); - - var mouseupTimeout; - - // Use editor.document instead of editable in non-IEs for observing mouseup - // since editable won't fire the event if selection process started within - // iframe and ended out of the editor (#9851). - editable.attachListener( CKEDITOR.env.ie ? editable : editor.document.getDocumentElement(), 'mouseup', function() { - mouseupTimeout = setTimeout( function() { - setToolbarStates(); - }, 0 ); - }); - - // Make sure that deferred mouseup callback isn't executed after editor instance - // had been destroyed. This may happen when editor.destroy() is called in parallel - // with mouseup event (i.e. a button with onclick callback) (#10219). - editor.on( 'destroy', function() { - clearTimeout( mouseupTimeout ); - }); - - editable.on( 'keyup', setToolbarStates ); - } - - // Create object representing Cut or Copy commands. - function createCutCopyCmd( type ) { - return { - type: type, - canUndo: type == 'cut', // We can't undo copy to clipboard. - startDisabled: true, - exec: function( data ) { - // Attempts to execute the Cut and Copy operations. - function tryToCutCopy( type ) { - if ( CKEDITOR.env.ie ) - return execIECommand( type ); - - // non-IEs part - try { - // Other browsers throw an error if the command is disabled. - return editor.document.$.execCommand( type, false, null ); - } catch ( e ) { - return false; - } - } - - this.type == 'cut' && fixCut(); - - var success = tryToCutCopy( this.type ); - - if ( !success ) - alert( editor.lang.clipboard[ this.type + 'Error' ] ); // Show cutError or copyError. - - return success; - } - }; - } - - function createPasteCmd() { - return { - // Snapshots are done manually by editable.insertXXX methods. - canUndo: false, - async: true, - - exec: function( editor, data ) { - var fire = function( data, withBeforePaste ) { - data && firePasteEvents( data.type, data.dataValue, !!withBeforePaste ); - - editor.fire( 'afterCommandExec', { - name: 'paste', - command: cmd, - returnValue: !!data - }); - }, - cmd = this; - - // Check data precisely - don't open dialog on empty string. - if ( typeof data == 'string' ) - fire( { type: 'auto', dataValue: data }, 1 ); - else - editor.getClipboardData( fire ); - } - }; - } - - function preventPasteEventNow() { - preventPasteEvent = 1; - // For safety reason we should wait longer than 0/1ms. - // We don't know how long execution of quite complex getClipboardData will take - // and in for example 'paste' listner execCommand() (which fires 'paste') is called - // after getClipboardData finishes. - // Luckily, it's impossible to immediately fire another 'paste' event we want to handle, - // because we only handle there native context menu and menu bar. - setTimeout( function() { - preventPasteEvent = 0; - }, 100 ); - } - - function preventBeforePasteEventNow() { - preventBeforePasteEvent = 1; - setTimeout( function() { - preventBeforePasteEvent = 0; - }, 10 ); - } - - // Tries to execute any of the paste, cut or copy commands in IE. Returns a - // boolean indicating that the operation succeeded. - // @param {String} command *LOWER CASED* name of command ('paste', 'cut', 'copy'). - function execIECommand( command ) { - var doc = editor.document, - body = doc.getBody(), - enabled = false, - onExec = function() { - enabled = true; - }; - - // The following seems to be the only reliable way to detect that - // clipboard commands are enabled in IE. It will fire the - // onpaste/oncut/oncopy events only if the security settings allowed - // the command to execute. - body.on( command, onExec ); - - // IE6/7: document.execCommand has problem to paste into positioned element. - ( CKEDITOR.env.version > 7 ? doc.$ : doc.$.selection.createRange() )[ 'execCommand' ]( command ); - - body.removeListener( command, onExec ); - - return enabled; - } - - function firePasteEvents( type, data, withBeforePaste ) { - var eventData = { type: type }; - - if ( withBeforePaste ) { - // Fire 'beforePaste' event so clipboard flavor get customized - // by other plugins. - if ( !editor.fire( 'beforePaste', eventData ) ) - return false; // Event canceled - } - - // The very last guard to make sure the paste has successfully happened. - // This check should be done after firing 'beforePaste' because for native paste - // 'beforePaste' is by default fired even for empty clipboard. - if ( !data ) - return false; - - // Reuse eventData.type because the default one could be changed by beforePaste listeners. - eventData.dataValue = data; - - return editor.fire( 'paste', eventData ); - } - - // Cutting off control type element in IE standards breaks the selection entirely. (#4881) - function fixCut() { - if ( !CKEDITOR.env.ie || CKEDITOR.env.quirks ) - return; - - var sel = editor.getSelection(), - control, range, dummy; - - if ( ( sel.getType() == CKEDITOR.SELECTION_ELEMENT ) && ( control = sel.getSelectedElement() ) ) { - range = sel.getRanges()[ 0 ]; - dummy = editor.document.createText( '' ); - dummy.insertBefore( control ); - range.setStartBefore( dummy ); - range.setEndAfter( control ); - sel.selectRanges( [ range ] ); - - // Clear up the fix if the paste wasn't succeeded. - setTimeout( function() { - // Element still online? - if ( control.getParent() ) { - dummy.remove(); - sel.selectElement( control ); - } - }, 0 ); - } - } - - // Allow to peek clipboard content by redirecting the - // pasting content into a temporary bin and grab the content of it. - function getClipboardDataByPastebin( evt, callback ) { - var doc = editor.document, - editable = editor.editable(), - cancel = function( evt ) { - evt.cancel(); - }, - ff3x = CKEDITOR.env.gecko && CKEDITOR.env.version <= 10902, - blurListener; - - // Avoid recursions on 'paste' event or consequent paste too fast. (#5730) - if ( doc.getById( 'cke_pastebin' ) ) - return; - - var sel = editor.getSelection(); - var bms = sel.createBookmarks(); - - // Create container to paste into. - // For rich content we prefer to use "body" since it holds - // the least possibility to be splitted by pasted content, while this may - // breaks the text selection on a frame-less editable, "div" would be - // the best one in that case. - // In another case on old IEs moving the selection into a "body" paste bin causes error panic. - // Body can't be also used for Opera which fills it with <br> - // what is indistinguishable from pasted <br> (copying <br> in Opera isn't possible, - // but it can be copied from other browser). - var pastebin = new CKEDITOR.dom.element( - ( CKEDITOR.env.webkit || editable.is( 'body' ) ) && !( CKEDITOR.env.ie || CKEDITOR.env.opera ) ? 'body' : 'div', doc ); - - pastebin.setAttribute( 'id', 'cke_pastebin' ); - - // Append bogus to prevent Opera from doing this. (#9522) - if ( CKEDITOR.env.opera ) - pastebin.appendBogus(); - - var containerOffset = 0, - offsetParent, - win = doc.getWindow(); - - // Seems to be the only way to avoid page scroll in Fx 3.x. - if ( ff3x ) { - pastebin.insertAfter( bms[ 0 ].startNode ); - pastebin.setStyle( 'display', 'inline' ); - } else { - if ( CKEDITOR.env.webkit ) { - // It's better to paste close to the real paste destination, so inherited styles - // (which Webkits will try to compensate by styling span) differs less from the destination's one. - editable.append( pastebin ); - // Style pastebin like .cke_editable, to minimize differences between origin and destination. (#9754) - pastebin.addClass( 'cke_editable' ); - - // Compensate position of offsetParent. - if ( !editable.is( 'body' ) ) { - // We're not able to get offsetParent from pastebin (body element), so check whether - // its parent (editable) is positioned. - if ( editable.getComputedStyle( 'position' ) != 'static' ) - offsetParent = editable; - // And if not - safely get offsetParent from editable. - else - offsetParent = CKEDITOR.dom.element.get( editable.$.offsetParent ); - - containerOffset = offsetParent.getDocumentPosition().y; - } - } else { - // Opera and IE doesn't allow to append to html element. - editable.getAscendant( CKEDITOR.env.ie || CKEDITOR.env.opera ? 'body' : 'html', 1 ).append( pastebin ); - } - - pastebin.setStyles({ - position: 'absolute', - // Position the bin at the top (+10 for safety) of viewport to avoid any subsequent document scroll. - top: ( win.getScrollPosition().y - containerOffset + 10 ) + 'px', - width: '1px', - // Caret has to fit in that height, otherwise browsers like Chrome & Opera will scroll window to show it. - // Set height equal to viewport's height - 20px (safety gaps), minimum 1px. - height: Math.max( 1, win.getViewPaneSize().height - 20 ) + 'px', - overflow: 'hidden', - // Reset styles that can mess up pastebin position. - margin: 0, - padding: 0 - }); - } - - // Check if the paste bin now establishes new editing host. - var isEditingHost = pastebin.getParent().isReadOnly(); - - if ( isEditingHost ) { - // Hide the paste bin. - pastebin.setOpacity( 0 ); - // And make it editable. - pastebin.setAttribute( 'contenteditable', true ); - } - // Transparency is not enough since positioned non-editing host always shows - // resize handler, pull it off the screen instead. - else - pastebin.setStyle( editor.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-1000px' ); - - editor.on( 'selectionChange', cancel, null, null, 0 ); - - // Webkit fill fire blur on editable when moving selection to - // pastebin (if body is used). Cancel it because it causes incorrect - // selection lock in case of inline editor. - if ( CKEDITOR.env.webkit ) - blurListener = editable.once( 'blur', cancel, null, null, -100 ); - - // Temporarily move selection to the pastebin. - isEditingHost && pastebin.focus(); - var range = new CKEDITOR.dom.range( pastebin ); - range.selectNodeContents( pastebin ); - var selPastebin = range.select(); - - // If non-native paste is executed, IE will open security alert and blur editable. - // Editable will then lock selection inside itself and after accepting security alert - // this selection will be restored. We overwrite stored selection, so it's restored - // in pastebin. (#9552) - if ( CKEDITOR.env.ie ) { - blurListener = editable.once( 'blur', function( evt ) { - editor.lockSelection( selPastebin ); - } ); - } - - var scrollTop = CKEDITOR.document.getWindow().getScrollPosition().y; - - // Wait a while and grab the pasted contents. - setTimeout( function() { - // Restore main window's scroll position which could have been changed - // by browser in cases described in #9771. - if ( CKEDITOR.env.webkit || CKEDITOR.env.opera ) - CKEDITOR.document[ CKEDITOR.env.webkit ? 'getBody' : 'getDocumentElement' ]().$.scrollTop = scrollTop; - - // Blur will be fired only on non-native paste. In other case manually remove listener. - blurListener && blurListener.removeListener(); - - // Restore properly the document focus. (#8849) - if ( CKEDITOR.env.ie ) - editable.focus(); - - // IE7: selection must go before removing pastebin. (#8691) - sel.selectBookmarks( bms ); - pastebin.remove(); - - // Grab the HTML contents. - // We need to look for a apple style wrapper on webkit it also adds - // a div wrapper if you copy/paste the body of the editor. - // Remove hidden div and restore selection. - var bogusSpan; - if ( CKEDITOR.env.webkit && ( bogusSpan = pastebin.getFirst() ) && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) ) - pastebin = bogusSpan; - - editor.removeListener( 'selectionChange', cancel ); - callback( pastebin.getHtml() ); - }, 0 ); - } - - // Try to get content directly from clipboard, without native event - // being fired before. In other words - synthetically get clipboard data - // if it's possible. - // mainPasteEvent will be fired, so if forced native paste: - // * worked, getClipboardDataByPastebin will grab it, - // * didn't work, pastebin will be empty and editor#paste won't be fired. - function getClipboardDataDirectly() { - if ( CKEDITOR.env.ie ) { - // Prevent IE from pasting at the begining of the document. - editor.focus(); - - // Command will be handled by 'beforepaste', but as - // execIECommand( 'paste' ) will fire also 'paste' event - // we're canceling it. - preventPasteEventNow(); - - // #9247: Lock focus to prevent IE from hiding toolbar for inline editor. - var focusManager = editor.focusManager; - focusManager.lock(); - - if ( editor.editable().fire( mainPasteEvent ) && !execIECommand( 'paste' ) ) { - focusManager.unlock(); - return false; - } - focusManager.unlock(); - } else { - try { - if ( editor.editable().fire( mainPasteEvent ) && !editor.document.$.execCommand( 'Paste', false, null ) ) { - throw 0; - } - } catch ( e ) { - return false; - } - } - - return true; - } - - // Listens for some clipboard related keystrokes, so they get customized. - // Needs to be bind to keydown event. - function onKey( event ) { - if ( editor.mode != 'wysiwyg' ) - return; - - switch ( event.data.keyCode ) { - // Paste - case CKEDITOR.CTRL + 86: // CTRL+V - case CKEDITOR.SHIFT + 45: // SHIFT+INS - var editable = editor.editable(); - - // Cancel 'paste' event because ctrl+v is for IE handled - // by 'beforepaste'. - preventPasteEventNow(); - - // Simulate 'beforepaste' event for all none-IEs. - !CKEDITOR.env.ie && editable.fire( 'beforepaste' ); - - // Simulate 'paste' event for Opera/Firefox2. - if ( CKEDITOR.env.opera || CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) - editable.fire( 'paste' ); - return; - - // Cut - case CKEDITOR.CTRL + 88: // CTRL+X - case CKEDITOR.SHIFT + 46: // SHIFT+DEL - // Save Undo snapshot. - editor.fire( 'saveSnapshot' ); // Save before cut - setTimeout( function() { - editor.fire( 'saveSnapshot' ); // Save after cut - }, 0 ); - } - } - - function pasteDataFromClipboard( evt ) { - // Default type is 'auto', but can be changed by beforePaste listeners. - var eventData = { type: 'auto' }; - // Fire 'beforePaste' event so clipboard flavor get customized by other plugins. - // If 'beforePaste' is canceled continue executing getClipboardDataByPastebin and then do nothing - // (do not fire 'paste', 'afterPaste' events). This way we can grab all - synthetically - // and natively pasted content and prevent its insertion into editor - // after canceling 'beforePaste' event. - var beforePasteNotCanceled = editor.fire( 'beforePaste', eventData ); - - getClipboardDataByPastebin( evt, function( data ) { - // Clean up. - data = data.replace( /<span[^>]+data-cke-bookmark[^<]*?<\/span>/ig, '' ); - - // Fire remaining events (without beforePaste) - beforePasteNotCanceled && firePasteEvents( eventData.type, data, 0, 1 ); - }); - } - - function setToolbarStates() { - if ( editor.mode != 'wysiwyg' ) - return; - - var pasteState = stateFromNamedCommand( 'Paste' ); - - editor.getCommand( 'cut' ).setState( stateFromNamedCommand( 'Cut' ) ); - editor.getCommand( 'copy' ).setState( stateFromNamedCommand( 'Copy' ) ); - editor.getCommand( 'paste' ).setState( pasteState ); - editor.fire( 'pasteState', pasteState ); - } - - function stateFromNamedCommand( command ) { - var retval; - - if ( inReadOnly && command in { Paste:1,Cut:1 } ) - return CKEDITOR.TRISTATE_DISABLED; - - if ( command == 'Paste' ) { - // IE Bug: queryCommandEnabled('paste') fires also 'beforepaste(copy/cut)', - // guard to distinguish from the ordinary sources (either - // keyboard paste or execCommand) (#4874). - CKEDITOR.env.ie && ( preventBeforePasteEvent = 1 ); - try { - // Always return true for Webkit (which always returns false) - retval = editor.document.$.queryCommandEnabled( command ) || CKEDITOR.env.webkit; - } catch ( er ) {} - preventBeforePasteEvent = 0; - } - // Cut, Copy - check if the selection is not empty - else { - var sel = editor.getSelection(), - ranges = sel.getRanges(); - retval = sel.getType() != CKEDITOR.SELECTION_NONE && !( ranges.length == 1 && ranges[ 0 ].collapsed ); - } - - return retval ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; - } - } - - // Returns: - // * 'htmlifiedtext' if content looks like transformed by browser from plain text. - // See clipboard/paste.html TCs for more info. - // * 'html' if it is not 'htmlifiedtext'. - function recogniseContentType( data ) { - if ( CKEDITOR.env.webkit ) { - // Plain text or ( <div><br></div> and text inside <div> ). - if ( !data.match( /^[^<]*$/g ) && !data.match( /^(<div><br( ?\/)?><\/div>|<div>[^<]*<\/div>)*$/gi ) ) - return 'html'; - } else if ( CKEDITOR.env.ie ) { - // Text and <br> or ( text and <br> in <p> - paragraphs can be separated by new \r\n ). - if ( !data.match( /^([^<]|<br( ?\/)?>)*$/gi ) && !data.match( /^(<p>([^<]|<br( ?\/)?>)*<\/p>|(\r\n))*$/gi ) ) - return 'html'; - } else if ( CKEDITOR.env.gecko || CKEDITOR.env.opera ) { - // Text or <br>. - if ( !data.match( /^([^<]|<br( ?\/)?>)*$/gi ) ) - return 'html'; - } else - return 'html'; - - return 'htmlifiedtext'; - } - - // This function transforms what browsers produce when - // pasting plain text into editable element (see clipboard/paste.html TCs - // for more info) into correct HTML (similar to that produced by text2Html). - function htmlifiedTextHtmlification( config, data ) { - function repeatParagraphs( repeats ) { - // Repeat blocks floor((n+1)/2) times. - // Even number of repeats - add <br> at the beginning of last <p>. - return CKEDITOR.tools.repeat( '</p><p>', ~~ ( repeats / 2 ) ) + ( repeats % 2 == 1 ? '<br>' : '' ); - } - - // Replace adjacent white-spaces (EOLs too - Fx sometimes keeps them) with one space. - data = data.replace( /\s+/g, ' ' ) - // Remove spaces from between tags. - .replace( /> +</g, '><' ) - // Normalize XHTML syntax and upper cased <br> tags. - .replace( /<br ?\/>/gi, '<br>' ); - - // IE - lower cased tags. - data = data.replace( /<\/?[A-Z]+>/g, function( match ) { - return match.toLowerCase(); - }); - - // Don't touch single lines (no <br|p|div>) - nothing to do here. - if ( data.match( /^[^<]$/ ) ) - return data; - - // Webkit. - if ( CKEDITOR.env.webkit && data.indexOf( '<div>' ) > -1 ) { - // One line break at the beginning - insert <br> - data = data.replace( /^(<div>(<br>|)<\/div>)(?!$|(<div>(<br>|)<\/div>))/g, '<br>' ) - // Two or more - reduce number of new lines by one. - .replace( /^(<div>(<br>|)<\/div>){2}(?!$)/g, '<div></div>' ); - - // Two line breaks create one paragraph in Webkit. - if ( data.match( /<div>(<br>|)<\/div>/ ) ) { - data = '<p>' + data.replace( /(<div>(<br>|)<\/div>)+/g, function( match ) { - return repeatParagraphs( match.split( '</div><div>' ).length + 1 ); - }) + '</p>'; - } - - // One line break create br. - data = data.replace( /<\/div><div>/g, '<br>' ); - - // Remove remaining divs. - data = data.replace( /<\/?div>/g, '' ); - } - - // Opera and Firefox and enterMode != BR. - if ( ( CKEDITOR.env.gecko || CKEDITOR.env.opera ) && config.enterMode != CKEDITOR.ENTER_BR ) { - // Remove bogus <br> - Fx generates two <brs> for one line break. - // For two line breaks it still produces two <brs>, but it's better to ignore this case than the first one. - if ( CKEDITOR.env.gecko ) - data = data.replace( /^<br><br>$/, '<br>' ); - - // This line satisfy edge case when for Opera we have two line breaks - //data = data.replace( /) - - if ( data.indexOf( '<br><br>' ) > -1 ) { - // Two line breaks create one paragraph, three - 2, four - 3, etc. - data = '<p>' + data.replace( /(<br>){2,}/g, function( match ) { - return repeatParagraphs( match.length / 4 ); - }) + '</p>'; - } - } - - return switchEnterMode( config, data ); - } - - // Filter can be editor dependent. - function getTextificationFilter( editor ) { - var filter = new CKEDITOR.htmlParser.filter(); - - // Elements which creates vertical breaks (have vert margins) - took from HTML5 spec. - // http://dev.w3.org/html5/markup/Overview.html#toc - var replaceWithParaIf = { blockquote:1,dl:1,fieldset:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,ol:1,p:1,table:1,ul:1 }, - - // All names except of <br>. - stripInlineIf = CKEDITOR.tools.extend({ br: 0 }, CKEDITOR.dtd.$inline ), - - // What's finally allowed (cke:br will be removed later). - allowedIf = { p:1,br:1,'cke:br':1 }, - - knownIf = CKEDITOR.dtd, - - // All names that will be removed (with content). - removeIf = CKEDITOR.tools.extend( { area:1,basefont:1,embed:1,iframe:1,map:1,object:1,param:1 }, CKEDITOR.dtd.$nonBodyContent, CKEDITOR.dtd.$cdata ); - - var flattenTableCell = function( element ) { - delete element.name; - element.add( new CKEDITOR.htmlParser.text( ' ' ) ); - }, - // Squash adjacent headers into one. <h1>A</h1><h2>B</h2> -> <h1>A<br>B</h1><h2></h2> - // Empty ones will be removed later. - squashHeader = function( element ) { - var next = element, - br, el; - - while ( ( next = next.next ) && next.name && next.name.match( /^h\d$/ ) ) { - // TODO shitty code - waitin' for htmlParse.element fix. - br = new CKEDITOR.htmlParser.element( 'cke:br' ); - br.isEmpty = true; - element.add( br ); - while ( ( el = next.children.shift() ) ) - element.add( el ); - } - }; - - filter.addRules( { - elements: { - h1: squashHeader, - h2: squashHeader, - h3: squashHeader, - h4: squashHeader, - h5: squashHeader, - h6: squashHeader, - - img: function( element ) { - var alt = CKEDITOR.tools.trim( element.attributes.alt || '' ), - txt = ' '; - - // Replace image with its alt if it doesn't look like an url or is empty. - if ( alt && !alt.match( /(^http|\.(jpe?g|gif|png))/i ) ) - txt = ' [' + alt + '] '; - - return new CKEDITOR.htmlParser.text( txt ); - }, - - td: flattenTableCell, - th: flattenTableCell, - - $: function( element ) { - var initialName = element.name, - br; - - // Remove entirely. - if ( removeIf[ initialName ] ) - return false; - - // Remove all attributes. - element.attributes = []; - - // Pass brs. - if ( initialName == 'br' ) - return element; - - // Elements that we want to replace with paragraphs. - if ( replaceWithParaIf[ initialName ] ) - element.name = 'p'; - - // Elements that we want to strip (tags only, without the content). - else if ( stripInlineIf[ initialName ] ) - delete element.name; - - // Surround other known element with <brs> and strip tags. - else if ( knownIf[ initialName ] ) { - // TODO shitty code - waitin' for htmlParse.element fix. - br = new CKEDITOR.htmlParser.element( 'cke:br' ); - br.isEmpty = true; - - // Replace hrs (maybe sth else too?) with only one br. - if ( CKEDITOR.dtd.$empty[ initialName ] ) - return br; - - element.add( br, 0 ); - br = br.clone(); - br.isEmpty = true; - element.add( br ); - delete element.name; - } - - // Final cleanup - if we can still find some not allowed elements then strip their names. - if ( !allowedIf[ element.name ] ) - delete element.name; - - return element; - } - } - }, { - // Apply this filter to every element. - applyToAll: true - } ); - - return filter; - } - - function htmlTextification( config, data, filter ) { - var fragment = new CKEDITOR.htmlParser.fragment.fromHtml( data ), - writer = new CKEDITOR.htmlParser.basicWriter(); - - fragment.writeHtml( writer, filter ); - data = writer.getHtml(); - - // Cleanup cke:brs. - data = data.replace( /\s*(<\/?[a-z:]+ ?\/?>)\s*/g, '$1' ) // Remove spaces around tags. - .replace( /(<cke:br \/>){2,}/g, '<cke:br />' ) // Join multiple adjacent cke:brs - .replace( /(<cke:br \/>)(<\/?p>|<br \/>)/g, '$2' ) // Strip cke:brs adjacent to original brs or ps. - .replace( /(<\/?p>|<br \/>)(<cke:br \/>)/g, '$1' ) - .replace( /<(cke:)?br( \/)?>/g, '<br>' ) // Finally - rename cke:brs to brs and fix <br /> to <br>. - .replace( /<p><\/p>/g, '' ); // Remove empty paragraphs. - - // Fix nested ps. E.g.: - // <p>A<p>B<p>C</p>D<p>E</p>F</p>G - // <p>A</p><p>B</p><p>C</p><p>D</p><p>E</p><p>F</p>G - var nested = 0; - data = data.replace( /<\/?p>/g, function( match ) { - if ( match == '<p>' ) { - if ( ++nested > 1 ) - return '</p><p>'; - } else { - if ( --nested > 0 ) - return '</p><p>'; - } - - return match; - }).replace( /<p><\/p>/g, '' ); // Step before: </p></p> -> </p><p></p><p>. Fix this here. - - return switchEnterMode( config, data ); - } - - function switchEnterMode( config, data ) { - if ( config.enterMode == CKEDITOR.ENTER_BR ) { - data = data.replace( /(<\/p><p>)+/g, function( match ) { - return CKEDITOR.tools.repeat( '<br>', match.length / 7 * 2 ); - }).replace( /<\/?p>/g, '' ); - } else if ( config.enterMode == CKEDITOR.ENTER_DIV ) { - data = data.replace( /<(\/)?p>/g, '<$1div>' ); - } - - return data; - } -})(); - -/** - * The default content type is used when pasted data cannot be clearly recognized as HTML or text. - * - * For example: `'foo'` may come from a plain text editor or a website. It isn't possible to recognize content - * type in this case, so default will be used. However, it's clear that `'<b>example</b> text'` is an HTML - * and its origin is webpage, email or other rich text editor. - * - * **Note:** If content type is text, then styles of context of paste are preserved. - * - * CKEDITOR.config.clipboard_defaultContentType = 'text'; - * - * @since 4.0 - * @cfg {'html'/'text'} [clipboard_defaultContentType='html'] - * @member CKEDITOR.config - */ - -/** - * Fired when a clipboard operation is about to be taken into the editor. - * Listeners can manipulate the data to be pasted before having it effectively - * inserted into the document. - * - * @since 3.1 - * @event paste - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {String} data.type Type of data in `data.dataValue`. Usually `html` or `text`, but for listeners - * with priority less than 6 it may be also `auto`, what means that content type hasn't been recognised yet - * (this will be done by content type sniffer that listens with priority 6). - * @param {String} data.dataValue HTML to be pasted. - */ - -/** - * Internal event to open the Paste dialog. - * - * @private - * @event pasteDialog - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {Function} [data] Callback that will be passed to {@link CKEDITOR.editor#openDialog}. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/bgcolor.png b/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/bgcolor.png Binary files differdeleted file mode 100644 index a313938d8bc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/bgcolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/bgcolor.png b/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/bgcolor.png Binary files differdeleted file mode 100644 index 54b3e18c460..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/bgcolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/textcolor.png b/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/textcolor.png Binary files differdeleted file mode 100644 index 8fc56bcbd21..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/hidpi/textcolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/textcolor.png b/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/textcolor.png Binary files differdeleted file mode 100644 index 0d8e45907bc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/icons/textcolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/lang/en.js b/addons/website/static/lib/ckeditor/plugins/colorbutton/lang/en.js deleted file mode 100644 index 0131673e6c1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/lang/en.js +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'colorbutton', 'en', { - auto: 'Automatic', - bgColorTitle: 'Background Color', - colors: { - '000': 'Black', - '800000': 'Maroon', - '8B4513': 'Saddle Brown', - '2F4F4F': 'Dark Slate Gray', - '008080': 'Teal', - '000080': 'Navy', - '4B0082': 'Indigo', - '696969': 'Dark Gray', - B22222: 'Fire Brick', - A52A2A: 'Brown', - DAA520: 'Golden Rod', - '006400': 'Dark Green', - '40E0D0': 'Turquoise', - '0000CD': 'Medium Blue', - '800080': 'Purple', - '808080': 'Gray', - F00: 'Red', - FF8C00: 'Dark Orange', - FFD700: 'Gold', - '008000': 'Green', - '0FF': 'Cyan', - '00F': 'Blue', - EE82EE: 'Violet', - A9A9A9: 'Dim Gray', - FFA07A: 'Light Salmon', - FFA500: 'Orange', - FFFF00: 'Yellow', - '00FF00': 'Lime', - AFEEEE: 'Pale Turquoise', - ADD8E6: 'Light Blue', - DDA0DD: 'Plum', - D3D3D3: 'Light Grey', - FFF0F5: 'Lavender Blush', - FAEBD7: 'Antique White', - FFFFE0: 'Light Yellow', - F0FFF0: 'Honeydew', - F0FFFF: 'Azure', - F0F8FF: 'Alice Blue', - E6E6FA: 'Lavender', - FFF: 'White' - }, - more: 'More Colors...', - panelTitle: 'Colors', - textColorTitle: 'Text Color' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/colorbutton/plugin.js b/addons/website/static/lib/ckeditor/plugins/colorbutton/plugin.js deleted file mode 100644 index 2316232f23d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colorbutton/plugin.js +++ /dev/null @@ -1,278 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "colorbutton" plugin that makes it possible to assign - * text and background colors to editor contents. - * - */ -CKEDITOR.plugins.add( 'colorbutton', { - requires: 'panelbutton,floatpanel', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'bgcolor,textcolor', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var config = editor.config, - lang = editor.lang.colorbutton; - - var clickFn; - - if ( !CKEDITOR.env.hc ) { - addButton( 'TextColor', 'fore', lang.textColorTitle, 10 ); - addButton( 'BGColor', 'back', lang.bgColorTitle, 20 ); - } - - function addButton( name, type, title, order ) { - var style = new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ] ), - colorBoxId = CKEDITOR.tools.getNextId() + '_colorBox'; - - editor.ui.add( name, CKEDITOR.UI_PANELBUTTON, { - label: title, - title: title, - modes: { wysiwyg:1 }, - editorFocus: 1, - toolbar: 'colors,' + order, - allowedContent: style, - requiredContent: style, - - panel: { - css: CKEDITOR.skin.getPath( 'editor' ), - attributes: { role: 'listbox', 'aria-label': lang.panelTitle } - }, - - onBlock: function( panel, block ) { - block.autoSize = true; - block.element.addClass( 'cke_colorblock' ); - block.element.setHtml( renderColors( panel, type, colorBoxId ) ); - // The block should not have scrollbars (#5933, #6056) - block.element.getDocument().getBody().setStyle( 'overflow', 'hidden' ); - - CKEDITOR.ui.fire( 'ready', this ); - - var keys = block.keys; - var rtl = editor.lang.dir == 'rtl'; - keys[ rtl ? 37 : 39 ] = 'next'; // ARROW-RIGHT - keys[ 40 ] = 'next'; // ARROW-DOWN - keys[ 9 ] = 'next'; // TAB - keys[ rtl ? 39 : 37 ] = 'prev'; // ARROW-LEFT - keys[ 38 ] = 'prev'; // ARROW-UP - keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB - keys[ 32 ] = 'click'; // SPACE - }, - - // The automatic colorbox should represent the real color (#6010) - onOpen: function() { - - var selection = editor.getSelection(), - block = selection && selection.getStartElement(), - path = editor.elementPath( block ), - color; - - // Find the closest block element. - block = path.block || path.blockLimit || editor.document.getBody(); - - // The background color might be transparent. In that case, look up the color in the DOM tree. - do { - color = block && block.getComputedStyle( type == 'back' ? 'background-color' : 'color' ) || 'transparent'; - } - while ( type == 'back' && color == 'transparent' && block && ( block = block.getParent() ) ); - - // The box should never be transparent. - if ( !color || color == 'transparent' ) - color = '#ffffff'; - - this._.panel._.iframe.getFrameDocument().getById( colorBoxId ).setStyle( 'background-color', color ); - - return color; - } - }); - } - - - function renderColors( panel, type, colorBoxId ) { - var output = [], - colors = config.colorButton_colors.split( ',' ); - - var clickFn = CKEDITOR.tools.addFunction( function( color, type ) { - if ( color == '?' ) { - var applyColorStyle = arguments.callee; - - function onColorDialogClose( evt ) { - this.removeListener( 'ok', onColorDialogClose ); - this.removeListener( 'cancel', onColorDialogClose ); - - evt.name == 'ok' && applyColorStyle( this.getContentElement( 'picker', 'selectedColor' ).getValue(), type ); - } - - editor.openDialog( 'colordialog', function() { - this.on( 'ok', onColorDialogClose ); - this.on( 'cancel', onColorDialogClose ); - }); - - return; - } - - editor.focus(); - - panel.hide(); - - editor.fire( 'saveSnapshot' ); - - // Clean up any conflicting style within the range. - editor.removeStyle( new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ], { color: 'inherit' } ) ); - - if ( color ) { - var colorStyle = config[ 'colorButton_' + type + 'Style' ]; - - colorStyle.childRule = type == 'back' ? - function( element ) { - // It's better to apply background color as the innermost style. (#3599) - // Except for "unstylable elements". (#6103) - return isUnstylable( element ); - } : function( element ) { - // Fore color style must be applied inside links instead of around it. (#4772,#6908) - return !( element.is( 'a' ) || element.getElementsByTag( 'a' ).count() ) || isUnstylable( element ); - }; - - editor.applyStyle( new CKEDITOR.style( colorStyle, { color: color } ) ); - } - - editor.fire( 'saveSnapshot' ); - }); - - // Render the "Automatic" button. - output.push( '<a class="cke_colorauto" _cke_focus=1 hidefocus=true' + - ' title="', lang.auto, '"' + - ' onclick="CKEDITOR.tools.callFunction(', clickFn, ',null,\'', type, '\');return false;"' + - ' href="javascript:void(\'', lang.auto, '\')"' + - ' role="option">' + - '<table role="presentation" cellspacing=0 cellpadding=0 width="100%">' + - '<tr>' + - '<td>' + - '<span class="cke_colorbox" id="', colorBoxId, '"></span>' + - '</td>' + - '<td colspan=7 align=center>', lang.auto, '</td>' + - '</tr>' + - '</table>' + - '</a>' + - '<table role="presentation" cellspacing=0 cellpadding=0 width="100%">' ); - - // Render the color boxes. - for ( var i = 0; i < colors.length; i++ ) { - if ( ( i % 8 ) === 0 ) - output.push( '</tr><tr>' ); - - var parts = colors[ i ].split( '/' ), - colorName = parts[ 0 ], - colorCode = parts[ 1 ] || colorName; - - // The data can be only a color code (without #) or colorName + color code - // If only a color code is provided, then the colorName is the color with the hash - // Convert the color from RGB to RRGGBB for better compatibility with IE and <font>. See #5676 - if ( !parts[ 1 ] ) - colorName = '#' + colorName.replace( /^(.)(.)(.)$/, '$1$1$2$2$3$3' ); - - var colorLabel = editor.lang.colorbutton.colors[ colorCode ] || colorCode; - output.push( '<td>' + - '<a class="cke_colorbox" _cke_focus=1 hidefocus=true' + - ' title="', colorLabel, '"' + - ' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'', colorName, '\',\'', type, '\'); return false;"' + - ' href="javascript:void(\'', colorLabel, '\')"' + - ' role="option">' + - '<span class="cke_colorbox" style="background-color:#', colorCode, '"></span>' + - '</a>' + - '</td>' ); - } - - // Render the "More Colors" button. - if ( editor.plugins.colordialog && config.colorButton_enableMore === undefined || config.colorButton_enableMore ) { - output.push( '</tr>' + - '<tr>' + - '<td colspan=8 align=center>' + - '<a class="cke_colormore" _cke_focus=1 hidefocus=true' + - ' title="', lang.more, '"' + - ' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'?\',\'', type, '\');return false;"' + - ' href="javascript:void(\'', lang.more, '\')"', ' role="option">', lang.more, '</a>' + - '</td>' ); // tr is later in the code. - } - - output.push( '</tr></table>' ); - - return output.join( '' ); - } - - function isUnstylable( ele ) { - return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-nostyle' ); - } - } -}); - -/** - * Whether to enable the **More Colors*** button in the color selectors. - * - * config.colorButton_enableMore = false; - * - * @cfg {Boolean} [colorButton_enableMore=true] - * @member CKEDITOR.config - */ - -/** - * Defines the colors to be displayed in the color selectors. This is a string - * containing hexadecimal notation for HTML colors, without the `'#'` prefix. - * - * **Since 3.3:** A color name may optionally be defined by prefixing the entries with - * a name and the slash character. For example, `'FontColor1/FF9900'` will be - * displayed as the color `#FF9900` in the selector, but will be output as `'FontColor1'`. - * - * // Brazil colors only. - * config.colorButton_colors = '00923E,F8C100,28166F'; - * - * config.colorButton_colors = 'FontColor1/FF9900,FontColor2/0066CC,FontColor3/F00'; - * - * @cfg {String} [colorButton_colors=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.colorButton_colors = '000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,' + - 'B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,' + - 'F00,FF8C00,FFD700,008000,0FF,00F,EE82EE,A9A9A9,' + - 'FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,' + - 'FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF'; - -/** - * Stores the style definition that applies the text foreground color. - * - * // This is actually the default value. - * config.colorButton_foreStyle = { - * element: 'span', - * styles: { color: '#(color)' } - * }; - * - * @cfg [colorButton_foreStyle=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.colorButton_foreStyle = { - element: 'span', - styles: { 'color': '#(color)' }, - overrides: [ { - element: 'font', attributes: { 'color': null } - }] -}; - -/** - * Stores the style definition that applies the text background color. - * - * // This is actually the default value. - * config.colorButton_backStyle = { - * element: 'span', - * styles: { 'background-color': '#(color)' } - * }; - * - * @cfg [colorButton_backStyle=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.colorButton_backStyle = { - element: 'span', - styles: { 'background-color': '#(color)' } -}; diff --git a/addons/website/static/lib/ckeditor/plugins/colordialog/dialogs/colordialog.js b/addons/website/static/lib/ckeditor/plugins/colordialog/dialogs/colordialog.js deleted file mode 100644 index 032110cea68..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colordialog/dialogs/colordialog.js +++ /dev/null @@ -1,340 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'colordialog', function( editor ) { - // Define some shorthands. - var $el = CKEDITOR.dom.element, - $doc = CKEDITOR.document, - lang = editor.lang.colordialog; - - // Reference the dialog. - var dialog; - - var spacer = { - type: 'html', - html: ' ' - }; - - var selected; - - function clearSelected() { - $doc.getById( selHiColorId ).removeStyle( 'background-color' ); - dialog.getContentElement( 'picker', 'selectedColor' ).setValue( '' ); - selected && selected.removeAttribute( 'aria-selected' ); - selected = null; - } - - function updateSelected( evt ) { - var target = evt.data.getTarget(), - color; - - if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) { - selected = target; - selected.setAttribute( 'aria-selected', true ); - dialog.getContentElement( 'picker', 'selectedColor' ).setValue( color ); - } - } - - // Basing black-white decision off of luma scheme using the Rec. 709 version - function whiteOrBlack( color ) { - color = color.replace( /^#/, '' ); - for ( var i = 0, rgb = []; i <= 2; i++ ) - rgb[ i ] = parseInt( color.substr( i * 2, 2 ), 16 ); - var luma = ( 0.2126 * rgb[ 0 ] ) + ( 0.7152 * rgb[ 1 ] ) + ( 0.0722 * rgb[ 2 ] ); - return '#' + ( luma >= 165 ? '000' : 'fff' ); - } - - // Distinguish focused and hover states. - var focused, hovered; - - // Apply highlight style. - function updateHighlight( event ) { - // Convert to event. - !event.name && ( event = new CKEDITOR.event( event ) ); - - var isFocus = !( /mouse/ ).test( event.name ), - target = event.data.getTarget(), - color; - - if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) { - removeHighlight( event ); - - isFocus ? focused = target : hovered = target; - - // Apply outline style to show focus. - if ( isFocus ) { - target.setStyle( 'border-color', whiteOrBlack( color ) ); - target.setStyle( 'border-style', 'dotted' ); - } - - $doc.getById( hicolorId ).setStyle( 'background-color', color ); - $doc.getById( hicolorTextId ).setHtml( color ); - } - } - - function clearHighlight() { - var color = focused.getChild( 0 ).getHtml(); - focused.setStyle( 'border-color', color ); - focused.setStyle( 'border-style', 'solid' ); - $doc.getById( hicolorId ).removeStyle( 'background-color' ); - $doc.getById( hicolorTextId ).setHtml( ' ' ); - focused = null; - } - - // Remove previously focused style. - function removeHighlight( event ) { - var isFocus = !( /mouse/ ).test( event.name ), - target = isFocus && focused; - - if ( target ) { - var color = target.getChild( 0 ).getHtml(); - target.setStyle( 'border-color', color ); - target.setStyle( 'border-style', 'solid' ); - } - - if ( !( focused || hovered ) ) { - $doc.getById( hicolorId ).removeStyle( 'background-color' ); - $doc.getById( hicolorTextId ).setHtml( ' ' ); - } - } - - function onKeyStrokes( evt ) { - var domEvt = evt.data; - - var element = domEvt.getTarget(); - var relative, nodeToMove; - var keystroke = domEvt.getKeystroke(), - rtl = editor.lang.dir == 'rtl'; - - switch ( keystroke ) { - // UP-ARROW - case 38: - // relative is TR - if ( ( relative = element.getParent().getPrevious() ) ) { - nodeToMove = relative.getChild( [ element.getIndex() ] ); - nodeToMove.focus(); - } - domEvt.preventDefault(); - break; - // DOWN-ARROW - case 40: - // relative is TR - if ( ( relative = element.getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ element.getIndex() ] ); - if ( nodeToMove && nodeToMove.type == 1 ) { - nodeToMove.focus(); - } - } - domEvt.preventDefault(); - break; - - // SPACE - // ENTER - case 32: - case 13: - updateSelected( evt ); - domEvt.preventDefault(); - break; - - // RIGHT-ARROW - case rtl ? 37: - 39 : - // relative is TD - if ( ( nodeToMove = element.getNext() ) ) { - if ( nodeToMove.type == 1 ) { - nodeToMove.focus(); - domEvt.preventDefault( true ); - } - } - // relative is TR - else if ( ( relative = element.getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ 0 ] ); - if ( nodeToMove && nodeToMove.type == 1 ) { - nodeToMove.focus(); - domEvt.preventDefault( true ); - } - } - break; - - // LEFT-ARROW - case rtl ? 39: - 37 : - // relative is TD - if ( ( nodeToMove = element.getPrevious() ) ) { - nodeToMove.focus(); - domEvt.preventDefault( true ); - } - // relative is TR - else if ( ( relative = element.getParent().getPrevious() ) ) { - nodeToMove = relative.getLast(); - nodeToMove.focus(); - domEvt.preventDefault( true ); - } - break; - default: - // Do not stop not handled events. - return; - } - } - - function createColorTable() { - table = CKEDITOR.dom.element.createFromHtml( '<table tabIndex="-1" aria-label="' + lang.options + '"' + - ' role="grid" style="border-collapse:separate;" cellspacing="0">' + - '<caption class="cke_voice_label">' + lang.options + '</caption>' + - '<tbody role="presentation"></tbody></table>' ); - - table.on( 'mouseover', updateHighlight ); - table.on( 'mouseout', removeHighlight ); - - // Create the base colors array. - var aColors = [ '00', '33', '66', '99', 'cc', 'ff' ]; - - // This function combines two ranges of three values from the color array into a row. - function appendColorRow( rangeA, rangeB ) { - for ( var i = rangeA; i < rangeA + 3; i++ ) { - var row = new $el( table.$.insertRow( -1 ) ); - row.setAttribute( 'role', 'row' ); - - for ( var j = rangeB; j < rangeB + 3; j++ ) { - for ( var n = 0; n < 6; n++ ) { - appendColorCell( row.$, '#' + aColors[ j ] + aColors[ n ] + aColors[ i ] ); - } - } - } - } - - // This function create a single color cell in the color table. - function appendColorCell( targetRow, color ) { - var cell = new $el( targetRow.insertCell( -1 ) ); - cell.setAttribute( 'class', 'ColorCell' ); - cell.setAttribute( 'tabIndex', -1 ); - cell.setAttribute( 'role', 'gridcell' ); - - cell.on( 'keydown', onKeyStrokes ); - cell.on( 'click', updateSelected ); - cell.on( 'focus', updateHighlight ); - cell.on( 'blur', removeHighlight ); - - cell.setStyle( 'background-color', color ); - cell.setStyle( 'border', '1px solid ' + color ); - - cell.setStyle( 'width', '14px' ); - cell.setStyle( 'height', '14px' ); - - var colorLabel = numbering( 'color_table_cell' ); - cell.setAttribute( 'aria-labelledby', colorLabel ); - cell.append( CKEDITOR.dom.element.createFromHtml( '<span id="' + colorLabel + '" class="cke_voice_label">' + color + '</span>', CKEDITOR.document ) ); - } - - appendColorRow( 0, 0 ); - appendColorRow( 3, 0 ); - appendColorRow( 0, 3 ); - appendColorRow( 3, 3 ); - - // Create the last row. - var oRow = new $el( table.$.insertRow( -1 ) ); - oRow.setAttribute( 'role', 'row' ); - - // Create the gray scale colors cells. - for ( var n = 0; n < 6; n++ ) { - appendColorCell( oRow.$, '#' + aColors[ n ] + aColors[ n ] + aColors[ n ] ); - } - - // Fill the row with black cells. - for ( var i = 0; i < 12; i++ ) { - appendColorCell( oRow.$, '#000000' ); - } - } - - var numbering = function( id ) { - return CKEDITOR.tools.getNextId() + '_' + id; - }, - hicolorId = numbering( 'hicolor' ), - hicolorTextId = numbering( 'hicolortext' ), - selHiColorId = numbering( 'selhicolor' ), - table; - - createColorTable(); - - return { - title: lang.title, - minWidth: 360, - minHeight: 220, - onLoad: function() { - // Update reference. - dialog = this; - }, - onHide: function() { - clearSelected(); - clearHighlight(); - }, - contents: [ - { - id: 'picker', - label: lang.title, - accessKey: 'I', - elements: [ - { - type: 'hbox', - padding: 0, - widths: [ '70%', '10%', '30%' ], - children: [ - { - type: 'html', - html: '<div></div>', - onLoad: function() { - CKEDITOR.document.getById( this.domId ).append( table ); - }, - focus: function() { - // Restore the previously focused cell, - // otherwise put the initial focus on the first table cell. - ( focused || this.getElement().getElementsByTag( 'td' ).getItem( 0 ) ).focus(); - } - }, - spacer, - { - type: 'vbox', - padding: 0, - widths: [ '70%', '5%', '25%' ], - children: [ - { - type: 'html', - html: '<span>' + lang.highlight + '</span>\ - <div id="' + hicolorId + '" style="border: 1px solid; height: 74px; width: 74px;"></div>\ - <div id="' + hicolorTextId + '"> </div><span>' + lang.selected + '</span>\ - <div id="' + selHiColorId + '" style="border: 1px solid; height: 20px; width: 74px;"></div>' - }, - { - type: 'text', - label: lang.selected, - labelStyle: 'display:none', - id: 'selectedColor', - style: 'width: 74px', - onChange: function() { - // Try to update color preview with new value. If fails, then set it no none. - try { - $doc.getById( selHiColorId ).setStyle( 'background-color', this.getValue() ); - } catch ( e ) { - clearSelected(); - } - } - }, - spacer, - { - type: 'button', - id: 'clear', - style: 'margin-top: 5px', - label: lang.clear, - onClick: clearSelected - } - ] - } - ] - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/colordialog/lang/en.js b/addons/website/static/lib/ckeditor/plugins/colordialog/lang/en.js deleted file mode 100644 index 3bc8587a406..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colordialog/lang/en.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'colordialog', 'en', { - clear: 'Clear', - highlight: 'Highlight', - options: 'Color Options', - selected: 'Selected Color', - title: 'Select color' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/colordialog/plugin.js b/addons/website/static/lib/ckeditor/plugins/colordialog/plugin.js deleted file mode 100644 index e2eed57712a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/colordialog/plugin.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.colordialog = { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.addCommand( 'colordialog', new CKEDITOR.dialogCommand( 'colordialog' ) ); - CKEDITOR.dialog.add( 'colordialog', this.path + 'dialogs/colordialog.js' ); - - /** - * Open up color dialog and to receive the selected color. - * - * @param {Function} callback The callback when color dialog is closed - * @param {String} callback.color The color value received if selected on the dialog. - * @param [scope] The scope in which the callback will be bound. - * @member CKEDITOR.editor - */ - editor.getColorFromDialog = function( callback, scope ) { - var onClose = function( evt ) { - releaseHandlers( this ); - var color = evt.name == 'ok' ? this.getValueOf( 'picker', 'selectedColor' ) : null; - callback.call( scope, color ); - }; - var releaseHandlers = function( dialog ) { - dialog.removeListener( 'ok', onClose ); - dialog.removeListener( 'cancel', onClose ); - }; - var bindToDialog = function( dialog ) { - dialog.on( 'ok', onClose ); - dialog.on( 'cancel', onClose ); - }; - - editor.execCommand( 'colordialog' ); - - if ( editor._.storedDialogs && editor._.storedDialogs.colordialog ) - bindToDialog( editor._.storedDialogs.colordialog ); - else { - CKEDITOR.on( 'dialogDefinition', function( e ) { - if ( e.data.name != 'colordialog' ) - return; - - var definition = e.data.definition; - - e.removeListener(); - definition.onLoad = CKEDITOR.tools.override( definition.onLoad, - function( orginal ) { - return function() { - bindToDialog( this ); - definition.onLoad = orginal; - if ( typeof orginal == 'function' ) - orginal.call( this ); - }; - } ); - } ); - } - }; - - - } -}; - -CKEDITOR.plugins.add( 'colordialog', CKEDITOR.plugins.colordialog ); diff --git a/addons/website/static/lib/ckeditor/plugins/contextmenu/lang/en.js b/addons/website/static/lib/ckeditor/plugins/contextmenu/lang/en.js deleted file mode 100644 index fea4479bc72..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/contextmenu/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'contextmenu', 'en', { - options: 'Context Menu Options' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/contextmenu/plugin.js b/addons/website/static/lib/ckeditor/plugins/contextmenu/plugin.js deleted file mode 100644 index 2481fe07229..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/contextmenu/plugin.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'contextmenu', { - requires: 'menu', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - - // Make sure the base class (CKEDITOR.menu) is loaded before it (#3318). - onLoad: function() { - /** - * @class - * @extends CKEDITOR.menu - */ - CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass({ - base: CKEDITOR.menu, - - /** - * @constructor - */ - $: function( editor ) { - this.base.call( this, editor, { - panel: { - className: 'cke_menu_panel', - attributes: { - 'aria-label': editor.lang.contextmenu.options - } - } - }); - }, - - proto: { - addTarget: function( element, nativeContextMenuOnCtrl ) { - // Opera doesn't support 'contextmenu' event, we have duo approaches employed here: - // 1. Inherit the 'button override' hack we introduced in v2 (#4530), while this require the Opera browser - // option 'Allow script to detect context menu/right click events' to be always turned on. - // 2. Considering the fact that ctrl/meta key is not been occupied - // for multiple range selecting (like Gecko), we use this key - // combination as a fallback for triggering context-menu. (#4530) - if ( CKEDITOR.env.opera && !( 'oncontextmenu' in document.body ) ) { - var contextMenuOverrideButton; - element.on( 'mousedown', function( evt ) { - evt = evt.data; - if ( evt.$.button != 2 ) { - if ( evt.getKeystroke() == CKEDITOR.CTRL + 1 ) - element.fire( 'contextmenu', evt ); - return; - } - - if ( nativeContextMenuOnCtrl && ( CKEDITOR.env.mac ? evt.$.metaKey : evt.$.ctrlKey ) ) - return; - - var target = evt.getTarget(); - - if ( !contextMenuOverrideButton ) { - var ownerDoc = target.getDocument(); - contextMenuOverrideButton = ownerDoc.createElement( 'input' ); - contextMenuOverrideButton.$.type = 'button'; - ownerDoc.getBody().append( contextMenuOverrideButton ); - } - - contextMenuOverrideButton.setAttribute( 'style', 'position:absolute;top:' + ( evt.$.clientY - 2 ) + - 'px;left:' + ( evt.$.clientX - 2 ) + - 'px;width:5px;height:5px;opacity:0.01' ); - - }); - - element.on( 'mouseup', function( evt ) { - if ( contextMenuOverrideButton ) { - contextMenuOverrideButton.remove(); - contextMenuOverrideButton = undefined; - // Simulate 'contextmenu' event. - element.fire( 'contextmenu', evt.data ); - } - }); - } - - element.on( 'contextmenu', function( event ) { - var domEvent = event.data; - - if ( nativeContextMenuOnCtrl && - // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event, - // which make this property unreliable. (#4826) - ( CKEDITOR.env.webkit ? holdCtrlKey : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) ) ) - return; - - - // Cancel the browser context menu. - domEvent.preventDefault(); - - var doc = domEvent.getTarget().getDocument(), - offsetParent = domEvent.getTarget().getDocument().getDocumentElement(), - fromFrame = !doc.equals( CKEDITOR.document ), - scroll = doc.getWindow().getScrollPosition(), - offsetX = fromFrame ? domEvent.$.clientX : domEvent.$.pageX || scroll.x + domEvent.$.clientX, - offsetY = fromFrame ? domEvent.$.clientY : domEvent.$.pageY || scroll.y + domEvent.$.clientY; - - CKEDITOR.tools.setTimeout( function() { - this.open( offsetParent, null, offsetX, offsetY ); - - // IE needs a short while to allow selection change before opening menu. (#7908) - }, CKEDITOR.env.ie ? 200 : 0, this ); - }, this ); - - if ( CKEDITOR.env.opera ) { - // 'contextmenu' event triggered by Windows menu key is unpreventable, - // cancel the key event itself. (#6534) - element.on( 'keypress', function( evt ) { - var domEvent = evt.data; - - if ( domEvent.$.keyCode === 0 ) - domEvent.preventDefault(); - }); - } - - if ( CKEDITOR.env.webkit ) { - var holdCtrlKey, - onKeyDown = function( event ) { - holdCtrlKey = CKEDITOR.env.mac ? event.data.$.metaKey : event.data.$.ctrlKey; - }, - resetOnKeyUp = function() { - holdCtrlKey = 0; - }; - - element.on( 'keydown', onKeyDown ); - element.on( 'keyup', resetOnKeyUp ); - element.on( 'contextmenu', resetOnKeyUp ); - } - }, - - open: function( offsetParent, corner, offsetX, offsetY ) { - this.editor.focus(); - offsetParent = offsetParent || CKEDITOR.document.getDocumentElement(); - - // #9362: Force selection check to update commands' states in the new context. - this.editor.selectionChange( 1 ); - - this.show( offsetParent, corner, offsetX, offsetY ); - } - } - }); - }, - - beforeInit: function( editor ) { - var contextMenu = editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor ); - - editor.on( 'contentDom', function() { - contextMenu.addTarget( editor.editable(), editor.config.browserContextMenuOnCtrl !== false ); - }); - - editor.addCommand( 'contextMenu', { - exec: function() { - editor.contextMenu.open( editor.document.getBody() ); - } - }); - - editor.setKeystroke( CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ); - editor.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ); - } -}); - -/** - * Whether to show the browser native context menu when the *Ctrl* or - * *Meta* (Mac) key is pressed on opening the context menu with the - * right mouse button click or the *Menu* key. - * - * config.browserContextMenuOnCtrl = false; - * - * @since 3.0.2 - * @cfg {Boolean} [browserContextMenuOnCtrl=true] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/devtools/lang/en.js b/addons/website/static/lib/ckeditor/plugins/devtools/lang/en.js deleted file mode 100644 index 17798a278f7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/devtools/lang/en.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'devtools', 'en', { - title: 'Element Information', - dialogName: 'Dialog window name', - tabName: 'Tab name', - elementId: 'Element ID', - elementType: 'Element type' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/devtools/plugin.js b/addons/website/static/lib/ckeditor/plugins/devtools/plugin.js deleted file mode 100644 index b8f5dfd3f1e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/devtools/plugin.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'devtools', { - lang: 'en,bg,cs,cy,da,de,el,eo,et,fa,fi,fr,gu,he,hr,it,ku,nb,nl,no,pl,tr,ug,uk,vi,zh-cn', // %REMOVE_LINE_CORE% - - init: function( editor ) { - editor._.showDialogDefinitionTooltips = 1; - }, - onLoad: function() { - CKEDITOR.document.appendStyleText( CKEDITOR.config.devtools_styles || '#cke_tooltip { padding: 5px; border: 2px solid #333; background: #ffffff }' + - '#cke_tooltip h2 { font-size: 1.1em; border-bottom: 1px solid; margin: 0; padding: 1px; }' + - '#cke_tooltip ul { padding: 0pt; list-style-type: none; }' ); - } -}); - -(function() { - function defaultCallback( editor, dialog, element, tabName ) { - var lang = editor.lang.devtools, - link = '<a href="http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition.' + - ( element ? ( element.type == 'text' ? 'textInput' : element.type ) : 'content' ) + - '" target="_blank">' + ( element ? element.type : 'content' ) + '</a>', - str = '<h2>' + lang.title + '</h2>' + - '<ul>' + - '<li><strong>' + lang.dialogName + '</strong> : ' + dialog.getName() + '</li>' + - '<li><strong>' + lang.tabName + '</strong> : ' + tabName + '</li>'; - - if ( element ) - str += '<li><strong>' + lang.elementId + '</strong> : ' + element.id + '</li>'; - - str += '<li><strong>' + lang.elementType + '</strong> : ' + link + '</li>'; - - return str + '</ul>'; - } - - function showTooltip( callback, el, editor, dialog, obj, tabName ) { - var pos = el.getDocumentPosition(), - styles = { 'z-index': CKEDITOR.dialog._.currentZIndex + 10, top: ( pos.y + el.getSize( 'height' ) ) + 'px' }; - - tooltip.setHtml( callback( editor, dialog, obj, tabName ) ); - tooltip.show(); - - // Translate coordinate for RTL. - if ( editor.lang.dir == 'rtl' ) { - var viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(); - styles.right = ( viewPaneSize.width - pos.x - el.getSize( 'width' ) ) + 'px'; - } else - styles.left = pos.x + 'px'; - - tooltip.setStyles( styles ); - } - - var tooltip; - CKEDITOR.on( 'reset', function() { - tooltip && tooltip.remove(); - tooltip = null; - }); - - CKEDITOR.on( 'dialogDefinition', function( evt ) { - var editor = evt.editor; - if ( editor._.showDialogDefinitionTooltips ) { - if ( !tooltip ) { - tooltip = CKEDITOR.dom.element.createFromHtml( '<div id="cke_tooltip" tabindex="-1" style="position: absolute"></div>', CKEDITOR.document ); - tooltip.hide(); - tooltip.on( 'mouseover', function() { - this.show(); - }); - tooltip.on( 'mouseout', function() { - this.hide(); - }); - tooltip.appendTo( CKEDITOR.document.getBody() ); - } - - var dialog = evt.data.definition.dialog, - callback = editor.config.devtools_textCallback || defaultCallback; - - dialog.on( 'load', function() { - var tabs = dialog.parts.tabs.getChildren(), - tab; - for ( var i = 0, len = tabs.count(); i < len; i++ ) { - tab = tabs.getItem( i ); - tab.on( 'mouseover', function() { - var id = this.$.id; - showTooltip( callback, this, editor, dialog, null, id.substring( 4, id.lastIndexOf( '_' ) ) ); - }); - tab.on( 'mouseout', function() { - tooltip.hide(); - }); - } - - dialog.foreach( function( obj ) { - if ( obj.type in { hbox:1,vbox:1 } ) - return; - - var el = obj.getElement(); - if ( el ) { - el.on( 'mouseover', function() { - showTooltip( callback, this, editor, dialog, obj, dialog._.currentTabId ); - }); - el.on( 'mouseout', function() { - tooltip.hide(); - }); - } - }); - }); - } - }); -})(); - -/** - * A function that returns the text to be displayed inside the Developer Tools - * tooltip when hovering over a dialog UI element. - * - * // This is actually the default value. - * // Show dialog window name, tab ID, and element ID. - * config.devtools_textCallback = function( editor, dialog, element, tabName ) { - * var lang = editor.lang.devtools, - * link = '<a href="http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition.' + - * ( element ? ( element.type == 'text' ? 'textInput' : element.type ) : 'content' ) + - * '.html" target="_blank">' + ( element ? element.type : 'content' ) + '</a>', - * str = - * '<h2>' + lang.title + '</h2>' + - * '<ul>' + - * '<li><strong>' + lang.dialogName + '</strong> : ' + dialog.getName() + '</li>' + - * '<li><strong>' + lang.tabName + '</strong> : ' + tabName + '</li>'; - * - * if ( element ) - * str += '<li><strong>' + lang.elementId + '</strong> : ' + element.id + '</li>'; - * - * str += '<li><strong>' + lang.elementType + '</strong> : ' + link + '</li>'; - * - * return str + '</ul>'; - * }; - * - * @since 3.6 - * @cfg {Function} [devtools_textCallback=see example] - * @member CKEDITOR.config - * @param {CKEDITOR.editor} editor - * @param dialog - * @param element - * @param tabName - */ - -/** - * A setting that stores CSS rules to be injected into the page with styles to be applied to the tooltip element. - * - * // This is actually the default value. - * CKEDITOR.config.devtools_styles = - * '#cke_tooltip { padding: 5px; border: 2px solid #333; background: #ffffff }' + - * '#cke_tooltip h2 { font-size: 1.1em; border-bottom: 1px solid; margin: 0; padding: 1px; }' + - * '#cke_tooltip ul { padding: 0pt; list-style-type: none; }'; - * - * @since 3.6 - * @cfg {String} [devtools_styles=see example] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/dialog/dialogDefinition.js b/addons/website/static/lib/ckeditor/plugins/dialog/dialogDefinition.js deleted file mode 100644 index e427c9419e4..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/dialog/dialogDefinition.js +++ /dev/null @@ -1,1006 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Defines the "virtual" dialog, dialog content and dialog button - * definition classes. - */ - -/** - * The definition of a dialog window. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create dialogs. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * CKEDITOR.dialog.add( 'testOnly', function( editor ) { - * return { - * title: 'Test Dialog', - * resizable: CKEDITOR.DIALOG_RESIZE_BOTH, - * minWidth: 500, - * minHeight: 400, - * contents: [ - * { - * id: 'tab1', - * label: 'First Tab', - * title: 'First Tab Title', - * accessKey: 'Q', - * elements: [ - * { - * type: 'text', - * label: 'Test Text 1', - * id: 'testText1', - * 'default': 'hello world!' - * } - * ] - * } - * ] - * }; - * } ); - * - * @class CKEDITOR.dialog.definition - */ - -/** - * The dialog title, displayed in the dialog's header. Required. - * - * @property {String} title - */ - -/** - * How the dialog can be resized, must be one of the four contents defined below. - * - * * {@link CKEDITOR#DIALOG_RESIZE_NONE} - * * {@link CKEDITOR#DIALOG_RESIZE_WIDTH} - * * {@link CKEDITOR#DIALOG_RESIZE_HEIGHT} - * * {@link CKEDITOR#DIALOG_RESIZE_BOTH} - * - * @property {Number} [resizable=CKEDITOR.DIALOG_RESIZE_NONE] - */ - -/** - * The minimum width of the dialog, in pixels. - * - * @property {Number} [minWidth=600] - */ - -/** - * The minimum height of the dialog, in pixels. - * - * @property {Number} [minHeight=400] - */ - - -/** - * The initial width of the dialog, in pixels. - * - * @since 3.5.3 - * @property {Number} [width=CKEDITOR.dialog.definition#minWidth] - */ - -/** - * The initial height of the dialog, in pixels. - * - * @since 3.5.3 - * @property {Number} [height=CKEDITOR.dialog.definition.minHeight] - */ - -/** - * The buttons in the dialog, defined as an array of - * {@link CKEDITOR.dialog.definition.button} objects. - * - * @property {Array} [buttons=[ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]] - */ - -/** - * The contents in the dialog, defined as an array of - * {@link CKEDITOR.dialog.definition.content} objects. Required. - * - * @property {Array} contents - */ - -/** - * The function to execute when OK is pressed. - * - * @property {Function} onOk - */ - -/** - * The function to execute when Cancel is pressed. - * - * @property {Function} onCancel - */ - -/** - * The function to execute when the dialog is displayed for the first time. - * - * @property {Function} onLoad - */ - -/** - * The function to execute when the dialog is loaded (executed every time the dialog is opened). - * - * @property {Function} onShow - */ - -/** - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create dialog content pages. - * - * @class CKEDITOR.dialog.definition.content. - */ - -/** - * The id of the content page. - * - * @property {String} id - */ - -/** - * The tab label of the content page. - * - * @property {String} label - */ - -/** - * The popup message of the tab label. - * - * @property {String} title - */ - -/** - * The CTRL hotkey for switching to the tab. - * - * contentDefinition.accessKey = 'Q'; // Switch to this page when CTRL-Q is pressed. - * - * @property {String} accessKey - */ - -/** - * The UI elements contained in this content page, defined as an array of - * {@link CKEDITOR.dialog.definition.uiElement} objects. - * - * @property {Array} elements - */ - -/** - * The definition of user interface element (textarea, radio etc). - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create dialog UI elements. - * - * @class CKEDITOR.dialog.definition.uiElement - * @see CKEDITOR.ui.dialog.uiElement - */ - -/** - * The id of the UI element. - * - * @property {String} id - */ - -/** - * The type of the UI element. Required. - * - * @property {String} type - */ - -/** - * The popup label of the UI element. - * - * @property {String} title - */ - -/** - * The content that needs to be allowed to enable this UI element. - * All formats accepted by {@link CKEDITOR.filter#check} may be used. - * - * When all UI elements in a tab are disabled, this tab will be disabled automatically. - * - * @property {String/Object/CKEDITOR.style} requiredContent - */ - -/** - * CSS class names to append to the UI element. - * - * @property {String} className - */ - -/** - * Inline CSS classes to append to the UI element. - * - * @property {String} style - */ - -/** - * Horizontal alignment (in container) of the UI element. - * - * @property {String} align - */ - -/** - * Function to execute the first time the UI element is displayed. - * - * @property {Function} onLoad - */ - -/** - * Function to execute whenever the UI element's parent dialog is displayed. - * - * @property {Function} onShow - */ - -/** - * Function to execute whenever the UI element's parent dialog is closed. - * - * @property {Function} onHide - */ - -/** - * Function to execute whenever the UI element's parent - * dialog's {@link CKEDITOR.dialog#setupContent} method is executed. - * It usually takes care of the respective UI element as a standalone element. - * - * @property {Function} setup - */ - -/** - * Function to execute whenever the UI element's parent - * dialog's {@link CKEDITOR.dialog#commitContent} method is executed. - * It usually takes care of the respective UI element as a standalone element. - * - * @property {Function} commit - */ - -// ----- hbox ----------------------------------------------------------------- - -/** - * Horizontal layout box for dialog UI elements, auto-expends to available width of container. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create horizontal layouts. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.hbox} object and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'hbox', - * widths: [ '25%', '25%', '50%' ], - * children: [ - * { - * type: 'text', - * id: 'id1', - * width: '40px', - * }, - * { - * type: 'text', - * id: 'id2', - * width: '40px', - * }, - * { - * type: 'text', - * id: 'id3' - * } - * ] - * } - * - * @class CKEDITOR.dialog.definition.hbox - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container. - * - * @property {Array} children - */ - -/** - * (Optional) The widths of child cells. - * - * @property {Array} widths - */ - -/** - * (Optional) The height of the layout. - * - * @property {Number} height - */ - -/** - * The CSS styles to apply to this element. - * - * @property {String} styles - */ - -/** - * (Optional) The padding width inside child cells. Example: 0, 1. - * - * @property {Number} padding - */ - -/** - * (Optional) The alignment of the whole layout. Example: center, top. - * - * @property {String} align - */ - -// ----- vbox ----------------------------------------------------------------- - -/** - * Vertical layout box for dialog UI elements. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create vertical layouts. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.vbox} object and can - * be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'vbox', - * align: 'right', - * width: '200px', - * children: [ - * { - * type: 'text', - * id: 'age', - * label: 'Age' - * }, - * { - * type: 'text', - * id: 'sex', - * label: 'Sex' - * }, - * { - * type: 'text', - * id: 'nationality', - * label: 'Nationality' - * } - * ] - * } - * - * @class CKEDITOR.dialog.definition.vbox - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container. - * - * @property {Array} children - */ - -/** - * (Optional) The width of the layout. - * - * @property {Array} width - */ - -/** - * (Optional) The heights of individual cells. - * - * @property {Number} heights - */ - -/** - * The CSS styles to apply to this element. - * - * @property {String} styles - */ - -/** - * (Optional) The padding width inside child cells. Example: 0, 1. - * - * @property {Number} padding - */ - -/** - * (Optional) The alignment of the whole layout. Example: center, top. - * - * @property {String} align - */ - -/** - * (Optional) Whether the layout should expand vertically to fill its container. - * - * @property {Boolean} expand - */ - -// ----- labeled element ------------------------------------------------------ - -/** - * The definition of labeled user interface element (textarea, textInput etc). - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create dialog UI elements. - * - * @class CKEDITOR.dialog.definition.labeledElement - * @extends CKEDITOR.dialog.definition.uiElement - * @see CKEDITOR.ui.dialog.labeledElement - */ - -/** - * The label of the UI element. - * - * { - * type: 'text', - * label: 'My Label' - * } - * - * @property {String} label - */ - -/** - * (Optional) Specify the layout of the label. Set to `'horizontal'` for horizontal layout. - * The default layout is vertical. - * - * { - * type: 'text', - * label: 'My Label', - * labelLayout: 'horizontal' - * } - * - * @property {String} labelLayout - */ - -/** - * (Optional) Applies only to horizontal layouts: a two elements array of lengths to specify the widths of the - * label and the content element. See also {@link CKEDITOR.dialog.definition.labeledElement#labelLayout}. - * - * { - * type: 'text', - * label: 'My Label', - * labelLayout: 'horizontal', - * widths: [100, 200] - * } - * - * @property {Array} widths - */ - -/** - * Specify the inline style of the uiElement label. - * - * { - * type: 'text', - * label: 'My Label', - * labelStyle: 'color: red' - * } - * - * @property {String} labelStyle - */ - - -/** - * Specify the inline style of the input element. - * - * { - * type: 'text', - * label: 'My Label', - * inputStyle: 'text-align: center' - * } - * - * @since 3.6.1 - * @property {String} inputStyle - */ - -/** - * Specify the inline style of the input element container. - * - * { - * type: 'text', - * label: 'My Label', - * controlStyle: 'width: 3em' - * } - * - * @since 3.6.1 - * @property {String} controlStyle - */ - -// ----- button --------------------------------------------------------------- - -/** - * The definition of a button. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create buttons. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.button} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'button', - * id: 'buttonId', - * label: 'Click me', - * title: 'My title', - * onClick: function() { - * // this = CKEDITOR.ui.dialog.button - * alert( 'Clicked: ' + this.id ); - * } - * } - * - * @class CKEDITOR.dialog.definition.button - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * Whether the button is disabled. - * - * @property {Boolean} disabled - */ - -/** - * The label of the UI element. - * - * @property {String} label - */ - -// ----- checkbox ------ -/** - * The definition of a checkbox element. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create groups of checkbox buttons. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.checkbox} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'checkbox', - * id: 'agree', - * label: 'I agree', - * 'default': 'checked', - * onClick: function() { - * // this = CKEDITOR.ui.dialog.checkbox - * alert( 'Checked: ' + this.getValue() ); - * } - * } - * - * @class CKEDITOR.dialog.definition.checkbox - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * The label of the UI element. - * - * @property {String} label - */ - -/** - * The default state. - * - * @property {String} [default='' (unchecked)] - */ - -// ----- file ----------------------------------------------------------------- - -/** - * The definition of a file upload input. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create file upload elements. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.file} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'file', - * id: 'upload', - * label: 'Select file from your computer', - * size: 38 - * }, - * { - * type: 'fileButton', - * id: 'fileId', - * label: 'Upload file', - * 'for': [ 'tab1', 'upload' ], - * filebrowser: { - * onSelect: function( fileUrl, data ) { - * alert( 'Successfully uploaded: ' + fileUrl ); - * } - * } - * } - * - * @class CKEDITOR.dialog.definition.file - * @extends CKEDITOR.dialog.definition.labeledElement - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * (Optional) The action attribute of the form element associated with this file upload input. - * If empty, CKEditor will use path to server connector for currently opened folder. - * - * @property {String} action - */ - -/** - * The size of the UI element. - * - * @property {Number} size - */ - -// ----- fileButton ----------------------------------------------------------- - -/** - * The definition of a button for submitting the file in a file upload input. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create a button for submitting the file in a file upload input. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.fileButton} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * @class CKEDITOR.dialog.definition.fileButton - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * The label of the UI element. - * - * @property {String} label - */ - -/** - * The instruction for CKEditor how to deal with file upload. - * By default, the file and fileButton elements will not work "as expected" if this attribute is not set. - * - * // Update field with id 'txtUrl' in the 'tab1' tab when file is uploaded. - * filebrowser: 'tab1:txtUrl' - * - * // Call custom onSelect function when file is successfully uploaded. - * filebrowser: { - * onSelect: function( fileUrl, data ) { - * alert( 'Successfully uploaded: ' + fileUrl ); - * } - * } - * - * @property {String} filebrowser/Object - */ - -/** - * An array that contains pageId and elementId of the file upload input element for which this button is created. - * - * [ pageId, elementId ] - * - * @property {String} for - */ - -// ----- html ----------------------------------------------------------------- - -/** - * The definition of a raw HTML element. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create elements made from raw HTML code. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.html} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * To access HTML elements use {@link CKEDITOR.dom.document#getById}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example 1: - * { - * type: 'html', - * html: '<h3>This is some sample HTML content.</h3>' - * } - * - * // Example 2: - * // Complete sample with document.getById() call when the "Ok" button is clicked. - * var dialogDefinition = { - * title: 'Sample dialog', - * minWidth: 300, - * minHeight: 200, - * onOk: function() { - * // "this" is now a CKEDITOR.dialog object. - * var document = this.getElement().getDocument(); - * // document = CKEDITOR.dom.document - * var element = <b>document.getById( 'myDiv' );</b> - * if ( element ) - * alert( element.getHtml() ); - * }, - * contents: [ - * { - * id: 'tab1', - * label: '', - * title: '', - * elements: [ - * { - * type: 'html', - * html: '<div id="myDiv">Sample <b>text</b>.</div><div id="otherId">Another div.</div>' - * } - * ] - * } - * ], - * buttons: [ CKEDITOR.dialog.cancelButton, CKEDITOR.dialog.okButton ] - * }; - * - * @class CKEDITOR.dialog.definition.html - * @extends CKEDITOR.dialog.definition.uiElement - */ - -/** - * (Required) HTML code of this element. - * - * @property {String} html - */ - -// ----- radio ---------------------------------------------------------------- - -/** - * The definition of a radio group. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create groups of radio buttons. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.radio} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'radio', - * id: 'country', - * label: 'Which country is bigger', - * items: [ [ 'France', 'FR' ], [ 'Germany', 'DE' ] ], - * style: 'color: green', - * 'default': 'DE', - * onClick: function() { - * // this = CKEDITOR.ui.dialog.radio - * alert( 'Current value: ' + this.getValue() ); - * } - * } - * - * @class CKEDITOR.dialog.definition.radio - * @extends CKEDITOR.dialog.definition.labeledElement - */ - -/** - * The default value. - * - * @property {String} default - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * An array of options. Each option is a 1- or 2-item array of format `[ 'Description', 'Value' ]`. - * If `'Value'` is missing, then the value would be assumed to be the same as the description. - * - * @property {Array} items - */ - -// ----- selectElement -------------------------------------------------------- - -/** - * The definition of a select element. - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create select elements. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.select} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * // Example: - * { - * type: 'select', - * id: 'sport', - * label: 'Select your favourite sport', - * items: [ [ 'Basketball' ], [ 'Baseball' ], [ 'Hockey' ], [ 'Football' ] ], - * 'default': 'Football', - * onChange: function( api ) { - * // this = CKEDITOR.ui.dialog.select - * alert( 'Current value: ' + this.getValue() ); - * } - * } - * - * @class CKEDITOR.dialog.definition.select - * @extends CKEDITOR.dialog.definition.labeledElement - */ - -/** - * The default value. - * - * @property {String} default - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * An array of options. Each option is a 1- or 2-item array of format `[ 'Description', 'Value' ]`. - * If `'Value'` is missing, then the value would be assumed to be the same as the description. - * - * @property {Array} items - */ - -/** - * (Optional) Set this to true if you'd like to have a multiple-choice select box. - * - * @property {Boolean} [multiple=false] - */ - -/** - * (Optional) The number of items to display in the select box. - * - * @property {Number} size - */ - -// ----- textInput ------------------------------------------------------------ - -/** - * The definition of a text field (single line). - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create text fields. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.textInput} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * - * // There is no constructor for this class, the user just has to define an - * // object with the appropriate properties. - * - * { - * type: 'text', - * id: 'name', - * label: 'Your name', - * 'default': '', - * validate: function() { - * if ( !this.getValue() ) { - * api.openMsgDialog( '', 'Name cannot be empty.' ); - * return false; - * } - * } - * } - * - * @class CKEDITOR.dialog.definition.textInput - * @extends CKEDITOR.dialog.definition.labeledElement - */ - -/** - * The default value. - * - * @property {String} default - */ - -/** - * (Optional) The maximum length. - * - * @property {Number} maxLength - */ - -/** - * (Optional) The size of the input field. - * - * @property {Number} size - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -// ----- textarea ------------------------------------------------------------- - -/** - * The definition of a text field (multiple lines). - * - * This class is not really part of the API. It just illustrates the properties - * that developers can use to define and create textarea. - * - * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.textarea} object - * and can be accessed with {@link CKEDITOR.dialog#getContentElement}. - * - * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}. - * -* // There is no constructor for this class, the user just has to define an -* // object with the appropriate properties. -* -* // Example: -* { -* type: 'textarea', -* id: 'message', -* label: 'Your comment', -* 'default': '', -* validate: function() { -* if ( this.getValue().length < 5 ) { -* api.openMsgDialog( 'The comment is too short.' ); -* return false; -* } -* } -* } - * - * @class CKEDITOR.dialog.definition.textarea - * @extends CKEDITOR.dialog.definition.labeledElement - */ - -/** - * The number of rows. - * - * @property {Number} rows - */ - -/** - * The number of columns. - * - * @property {Number} cols - */ - -/** - * (Optional) The validation function. - * - * @property {Function} validate - */ - -/** - * The default value. - * - * @property {String} default - */ diff --git a/addons/website/static/lib/ckeditor/plugins/dialog/plugin.js b/addons/website/static/lib/ckeditor/plugins/dialog/plugin.js deleted file mode 100644 index 4c378897f89..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/dialog/plugin.js +++ /dev/null @@ -1,3222 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The floating dialog plugin. - */ - -/** - * No resize for this dialog. - * - * @readonly - * @property {Number} [=0] - * @member CKEDITOR - */ -CKEDITOR.DIALOG_RESIZE_NONE = 0; - -/** - * Only allow horizontal resizing for this dialog, disable vertical resizing. - * - * @readonly - * @property {Number} [=1] - * @member CKEDITOR - */ -CKEDITOR.DIALOG_RESIZE_WIDTH = 1; - -/** - * Only allow vertical resizing for this dialog, disable horizontal resizing. - * - * @readonly - * @property {Number} [=2] - * @member CKEDITOR - */ -CKEDITOR.DIALOG_RESIZE_HEIGHT = 2; - -/** - * Allow the dialog to be resized in both directions. - * - * @readonly - * @property {Number} [=3] - * @member CKEDITOR - */ -CKEDITOR.DIALOG_RESIZE_BOTH = 3; - -(function() { - var cssLength = CKEDITOR.tools.cssLength; - - function isTabVisible( tabId ) { - return !!this._.tabs[ tabId ][ 0 ].$.offsetHeight; - } - - function getPreviousVisibleTab() { - var tabId = this._.currentTabId, - length = this._.tabIdList.length, - tabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, tabId ) + length; - - for ( var i = tabIndex - 1; i > tabIndex - length; i-- ) { - if ( isTabVisible.call( this, this._.tabIdList[ i % length ] ) ) - return this._.tabIdList[ i % length ]; - } - - return null; - } - - function getNextVisibleTab() { - var tabId = this._.currentTabId, - length = this._.tabIdList.length, - tabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, tabId ); - - for ( var i = tabIndex + 1; i < tabIndex + length; i++ ) { - if ( isTabVisible.call( this, this._.tabIdList[ i % length ] ) ) - return this._.tabIdList[ i % length ]; - } - - return null; - } - - - function clearOrRecoverTextInputValue( container, isRecover ) { - var inputs = container.$.getElementsByTagName( 'input' ); - for ( var i = 0, length = inputs.length; i < length; i++ ) { - var item = new CKEDITOR.dom.element( inputs[ i ] ); - - if ( item.getAttribute( 'type' ).toLowerCase() == 'text' ) { - if ( isRecover ) { - item.setAttribute( 'value', item.getCustomData( 'fake_value' ) || '' ); - item.removeCustomData( 'fake_value' ); - } else { - item.setCustomData( 'fake_value', item.getAttribute( 'value' ) ); - item.setAttribute( 'value', '' ); - } - } - } - } - - // Handle dialog element validation state UI changes. - function handleFieldValidated( isValid, msg ) { - var input = this.getInputElement(); - if ( input ) { - isValid ? input.removeAttribute( 'aria-invalid' ) : input.setAttribute( 'aria-invalid', true ); - } - - if ( !isValid ) { - if ( this.select ) - this.select(); - else - this.focus(); - } - - msg && alert( msg ); - - this.fire( 'validated', { valid: isValid, msg: msg } ); - } - - function resetField() { - var input = this.getInputElement(); - input && input.removeAttribute( 'aria-invalid' ); - } - - var templateSource = '<div class="cke_reset_all {editorId} {editorDialogClass} {hidpi}' + - '" dir="{langDir}"' + - ' lang="{langCode}"' + - ' role="dialog"' + - ' aria-labelledby="cke_dialog_title_{id}"' + - '>' + - '<table class="cke_dialog ' + CKEDITOR.env.cssClass + ' cke_{langDir}"' + - ' style="position:absolute" role="presentation">' + - '<tr><td role="presentation">' + - '<div class="cke_dialog_body" role="presentation">' + - '<div id="cke_dialog_title_{id}" class="cke_dialog_title" role="presentation"></div>' + - '<a id="cke_dialog_close_button_{id}" class="cke_dialog_close_button" href="javascript:void(0)" title="{closeTitle}" role="button"><span class="cke_label">X</span></a>' + - '<div id="cke_dialog_tabs_{id}" class="cke_dialog_tabs" role="tablist"></div>' + - '<table class="cke_dialog_contents" role="presentation">' + - '<tr>' + - '<td id="cke_dialog_contents_{id}" class="cke_dialog_contents_body" role="presentation"></td>' + - '</tr>' + - '<tr>' + - '<td id="cke_dialog_footer_{id}" class="cke_dialog_footer" role="presentation"></td>' + - '</tr>' + - '</table>' + - '</div>' + - '</td></tr>' + - '</table>' + - '</div>'; - - function buildDialog( editor ) { - var element = CKEDITOR.dom.element.createFromHtml( CKEDITOR.addTemplate( 'dialog', templateSource ).output({ - id: CKEDITOR.tools.getNextNumber(), - editorId: editor.id, - langDir: editor.lang.dir, - langCode: editor.langCode, - editorDialogClass: 'cke_editor_' + editor.name.replace( /\./g, '\\.' ) + '_dialog', - closeTitle: editor.lang.common.close, - hidpi: CKEDITOR.env.hidpi ? 'cke_hidpi' : '' - })); - - // TODO: Change this to getById(), so it'll support custom templates. - var body = element.getChild( [ 0, 0, 0, 0, 0 ] ), - title = body.getChild( 0 ), - close = body.getChild( 1 ); - - // IFrame shim for dialog that masks activeX in IE. (#7619) - if ( CKEDITOR.env.ie && !CKEDITOR.env.ie6Compat ) { - var src = 'javascript:void(function(){' + encodeURIComponent( 'document.open();(' + CKEDITOR.tools.fixDomain + ')();document.close();' ) + '}())', - iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' + - ' frameBorder="0"' + - ' class="cke_iframe_shim"' + - ' src="' + src + '"' + - ' tabIndex="-1"' + - '></iframe>' ); - iframe.appendTo( body.getParent() ); - } - - // Make the Title and Close Button unselectable. - title.unselectable(); - close.unselectable(); - - return { - element: element, - parts: { - dialog: element.getChild( 0 ), - title: title, - close: close, - tabs: body.getChild( 2 ), - contents: body.getChild( [ 3, 0, 0, 0 ] ), - footer: body.getChild( [ 3, 0, 1, 0 ] ) - } - }; - } - - /** - * This is the base class for runtime dialog objects. An instance of this - * class represents a single named dialog for a single editor instance. - * - * var dialogObj = new CKEDITOR.dialog( editor, 'smiley' ); - * - * @class - * @constructor Creates a dialog class instance. - * @param {Object} editor The editor which created the dialog. - * @param {String} dialogName The dialog's registered name. - */ - CKEDITOR.dialog = function( editor, dialogName ) { - // Load the dialog definition. - var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ], - defaultDefinition = CKEDITOR.tools.clone( defaultDialogDefinition ), - buttonsOrder = editor.config.dialog_buttonsOrder || 'OS', - dir = editor.lang.dir, - tabsToRemove = {}, - i, processed, stopPropagation; - - if ( ( buttonsOrder == 'OS' && CKEDITOR.env.mac ) || // The buttons in MacOS Apps are in reverse order (#4750) - ( buttonsOrder == 'rtl' && dir == 'ltr' ) || ( buttonsOrder == 'ltr' && dir == 'rtl' ) ) - defaultDefinition.buttons.reverse(); - - - // Completes the definition with the default values. - definition = CKEDITOR.tools.extend( definition( editor ), defaultDefinition ); - - // Clone a functionally independent copy for this dialog. - definition = CKEDITOR.tools.clone( definition ); - - // Create a complex definition object, extending it with the API - // functions. - definition = new definitionObject( this, definition ); - - var doc = CKEDITOR.document; - - var themeBuilt = buildDialog( editor ); - - // Initialize some basic parameters. - this._ = { - editor: editor, - element: themeBuilt.element, - name: dialogName, - contentSize: { width: 0, height: 0 }, - size: { width: 0, height: 0 }, - contents: {}, - buttons: {}, - accessKeyMap: {}, - - // Initialize the tab and page map. - tabs: {}, - tabIdList: [], - currentTabId: null, - currentTabIndex: null, - pageCount: 0, - lastTab: null, - tabBarMode: false, - - // Initialize the tab order array for input widgets. - focusList: [], - currentFocusIndex: 0, - hasFocus: false - }; - - this.parts = themeBuilt.parts; - - CKEDITOR.tools.setTimeout( function() { - editor.fire( 'ariaWidget', this.parts.contents ); - }, 0, this ); - - // Set the startup styles for the dialog, avoiding it enlarging the - // page size on the dialog creation. - var startStyles = { - position: CKEDITOR.env.ie6Compat ? 'absolute' : 'fixed', - top: 0, - visibility: 'hidden' - }; - - startStyles[ dir == 'rtl' ? 'right' : 'left' ] = 0; - this.parts.dialog.setStyles( startStyles ); - - - // Call the CKEDITOR.event constructor to initialize this instance. - CKEDITOR.event.call( this ); - - // Fire the "dialogDefinition" event, making it possible to customize - // the dialog definition. - this.definition = definition = CKEDITOR.fire( 'dialogDefinition', { - name: dialogName, - definition: definition - }, editor ).definition; - - // Cache tabs that should be removed. - if ( !( 'removeDialogTabs' in editor._ ) && editor.config.removeDialogTabs ) { - var removeContents = editor.config.removeDialogTabs.split( ';' ); - - for ( i = 0; i < removeContents.length; i++ ) { - var parts = removeContents[ i ].split( ':' ); - if ( parts.length == 2 ) { - var removeDialogName = parts[ 0 ]; - if ( !tabsToRemove[ removeDialogName ] ) - tabsToRemove[ removeDialogName ] = []; - tabsToRemove[ removeDialogName ].push( parts[ 1 ] ); - } - } - editor._.removeDialogTabs = tabsToRemove; - } - - // Remove tabs of this dialog. - if ( editor._.removeDialogTabs && ( tabsToRemove = editor._.removeDialogTabs[ dialogName ] ) ) { - for ( i = 0; i < tabsToRemove.length; i++ ) - definition.removeContents( tabsToRemove[ i ] ); - } - - // Initialize load, show, hide, ok and cancel events. - if ( definition.onLoad ) - this.on( 'load', definition.onLoad ); - - if ( definition.onShow ) - this.on( 'show', definition.onShow ); - - if ( definition.onHide ) - this.on( 'hide', definition.onHide ); - - if ( definition.onOk ) { - this.on( 'ok', function( evt ) { - // Dialog confirm might probably introduce content changes (#5415). - editor.fire( 'saveSnapshot' ); - setTimeout( function() { - editor.fire( 'saveSnapshot' ); - }, 0 ); - if ( definition.onOk.call( this, evt ) === false ) - evt.data.hide = false; - }); - } - - if ( definition.onCancel ) { - this.on( 'cancel', function( evt ) { - if ( definition.onCancel.call( this, evt ) === false ) - evt.data.hide = false; - }); - } - - var me = this; - - // Iterates over all items inside all content in the dialog, calling a - // function for each of them. - var iterContents = function( func ) { - var contents = me._.contents, - stop = false; - - for ( var i in contents ) { - for ( var j in contents[ i ] ) { - stop = func.call( this, contents[ i ][ j ] ); - if ( stop ) - return; - } - } - }; - - this.on( 'ok', function( evt ) { - iterContents( function( item ) { - if ( item.validate ) { - var retval = item.validate( this ), - invalid = typeof( retval ) == 'string' || retval === false; - - if ( invalid ) { - evt.data.hide = false; - evt.stop(); - } - - handleFieldValidated.call( item, !invalid, typeof retval == 'string' ? retval : undefined ); - return invalid; - } - }); - }, this, null, 0 ); - - this.on( 'cancel', function( evt ) { - iterContents( function( item ) { - if ( item.isChanged() ) { - if ( !confirm( editor.lang.common.confirmCancel ) ) - evt.data.hide = false; - return true; - } - }); - }, this, null, 0 ); - - this.parts.close.on( 'click', function( evt ) { - if ( this.fire( 'cancel', { hide: true } ).hide !== false ) - this.hide(); - evt.data.preventDefault(); - }, this ); - - // Sort focus list according to tab order definitions. - function setupFocus() { - var focusList = me._.focusList; - focusList.sort( function( a, b ) { - // Mimics browser tab order logics; - if ( a.tabIndex != b.tabIndex ) - return b.tabIndex - a.tabIndex; - // Sort is not stable in some browsers, - // fall-back the comparator to 'focusIndex'; - else - return a.focusIndex - b.focusIndex; - }); - - var size = focusList.length; - for ( var i = 0; i < size; i++ ) - focusList[ i ].focusIndex = i; - } - - function changeFocus( offset ) { - var focusList = me._.focusList; - offset = offset || 0; - - if ( focusList.length < 1 ) - return; - - var current = me._.currentFocusIndex; - - // Trigger the 'blur' event of any input element before anything, - // since certain UI updates may depend on it. - try { - focusList[ current ].getInputElement().$.blur(); - } catch ( e ) {} - - var startIndex = ( current + offset + focusList.length ) % focusList.length, - currentIndex = startIndex; - while ( offset && !focusList[ currentIndex ].isFocusable() ) { - currentIndex = ( currentIndex + offset + focusList.length ) % focusList.length; - if ( currentIndex == startIndex ) - break; - } - - focusList[ currentIndex ].focus(); - - // Select whole field content. - if ( focusList[ currentIndex ].type == 'text' ) - focusList[ currentIndex ].select(); - } - - this.changeFocus = changeFocus; - - - function keydownHandler( evt ) { - // If I'm not the top dialog, ignore. - if ( me != CKEDITOR.dialog._.currentTop ) - return; - - var keystroke = evt.data.getKeystroke(), - rtl = editor.lang.dir == 'rtl', - button; - - processed = stopPropagation = 0; - - if ( keystroke == 9 || keystroke == CKEDITOR.SHIFT + 9 ) { - var shiftPressed = ( keystroke == CKEDITOR.SHIFT + 9 ); - - // Handling Tab and Shift-Tab. - if ( me._.tabBarMode ) { - // Change tabs. - var nextId = shiftPressed ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me ); - me.selectPage( nextId ); - me._.tabs[ nextId ][ 0 ].focus(); - } else { - // Change the focus of inputs. - changeFocus( shiftPressed ? -1 : 1 ); - } - - processed = 1; - } else if ( keystroke == CKEDITOR.ALT + 121 && !me._.tabBarMode && me.getPageCount() > 1 ) { - // Alt-F10 puts focus into the current tab item in the tab bar. - me._.tabBarMode = true; - me._.tabs[ me._.currentTabId ][ 0 ].focus(); - processed = 1; - } else if ( ( keystroke == 37 || keystroke == 39 ) && me._.tabBarMode ) { - // Arrow keys - used for changing tabs. - nextId = ( keystroke == ( rtl ? 39 : 37 ) ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me ) ); - me.selectPage( nextId ); - me._.tabs[ nextId ][ 0 ].focus(); - processed = 1; - } else if ( ( keystroke == 13 || keystroke == 32 ) && me._.tabBarMode ) { - this.selectPage( this._.currentTabId ); - this._.tabBarMode = false; - this._.currentFocusIndex = -1; - changeFocus( 1 ); - processed = 1; - } - // If user presses enter key in a text box, it implies clicking OK for the dialog. - else if ( keystroke == 13 /*ENTER*/ ) { - // Don't do that for a target that handles ENTER. - var target = evt.data.getTarget(); - if ( !target.is( 'a', 'button', 'select', 'textarea' ) && ( !target.is( 'input' ) || target.$.type != 'button' ) ) { - button = this.getButton( 'ok' ); - button && CKEDITOR.tools.setTimeout( button.click, 0, button ); - processed = 1; - } - stopPropagation = 1; // Always block the propagation (#4269) - } else if ( keystroke == 27 /*ESC*/ ) { - button = this.getButton( 'cancel' ); - - // If there's a Cancel button, click it, else just fire the cancel event and hide the dialog. - if ( button ) - CKEDITOR.tools.setTimeout( button.click, 0, button ); - else { - if ( this.fire( 'cancel', { hide: true } ).hide !== false ) - this.hide(); - } - stopPropagation = 1; // Always block the propagation (#4269) - } else - return; - - keypressHandler( evt ); - } - - function keypressHandler( evt ) { - if ( processed ) - evt.data.preventDefault( 1 ); - else if ( stopPropagation ) - evt.data.stopPropagation(); - } - - var dialogElement = this._.element; - - editor.focusManager.add( dialogElement, 1 ); - - // Add the dialog keyboard handlers. - this.on( 'show', function() { - dialogElement.on( 'keydown', keydownHandler, this ); - - // Some browsers instead, don't cancel key events in the keydown, but in the - // keypress. So we must do a longer trip in those cases. (#4531,#8985) - if ( CKEDITOR.env.opera || CKEDITOR.env.gecko ) - dialogElement.on( 'keypress', keypressHandler, this ); - - }); - this.on( 'hide', function() { - dialogElement.removeListener( 'keydown', keydownHandler ); - if ( CKEDITOR.env.opera || CKEDITOR.env.gecko ) - dialogElement.removeListener( 'keypress', keypressHandler ); - - // Reset fields state when closing dialog. - iterContents( function( item ) { - resetField.apply( item ); - }); - }); - this.on( 'iframeAdded', function( evt ) { - var doc = new CKEDITOR.dom.document( evt.data.iframe.$.contentWindow.document ); - doc.on( 'keydown', keydownHandler, this, null, 0 ); - }); - - // Auto-focus logic in dialog. - this.on( 'show', function() { - // Setup tabIndex on showing the dialog instead of on loading - // to allow dynamic tab order happen in dialog definition. - setupFocus(); - - if ( editor.config.dialog_startupFocusTab && me._.pageCount > 1 ) { - me._.tabBarMode = true; - me._.tabs[ me._.currentTabId ][ 0 ].focus(); - } else if ( !this._.hasFocus ) { - this._.currentFocusIndex = -1; - - // Decide where to put the initial focus. - if ( definition.onFocus ) { - var initialFocus = definition.onFocus.call( this ); - // Focus the field that the user specified. - initialFocus && initialFocus.focus(); - } - // Focus the first field in layout order. - else - changeFocus( 1 ); - } - }, this, null, 0xffffffff ); - - // IE6 BUG: Text fields and text areas are only half-rendered the first time the dialog appears in IE6 (#2661). - // This is still needed after [2708] and [2709] because text fields in hidden TR tags are still broken. - if ( CKEDITOR.env.ie6Compat ) { - this.on( 'load', function( evt ) { - var outer = this.getElement(), - inner = outer.getFirst(); - inner.remove(); - inner.appendTo( outer ); - }, this ); - } - - initDragAndDrop( this ); - initResizeHandles( this ); - - // Insert the title. - ( new CKEDITOR.dom.text( definition.title, CKEDITOR.document ) ).appendTo( this.parts.title ); - - // Insert the tabs and contents. - for ( i = 0; i < definition.contents.length; i++ ) { - var page = definition.contents[ i ]; - page && this.addPage( page ); - } - - this.parts[ 'tabs' ].on( 'click', function( evt ) { - var target = evt.data.getTarget(); - // If we aren't inside a tab, bail out. - if ( target.hasClass( 'cke_dialog_tab' ) ) { - // Get the ID of the tab, without the 'cke_' prefix and the unique number suffix. - var id = target.$.id; - this.selectPage( id.substring( 4, id.lastIndexOf( '_' ) ) ); - - if ( this._.tabBarMode ) { - this._.tabBarMode = false; - this._.currentFocusIndex = -1; - changeFocus( 1 ); - } - evt.data.preventDefault(); - } - }, this ); - - // Insert buttons. - var buttonsHtml = [], - buttons = CKEDITOR.dialog._.uiElementBuilders.hbox.build( this, { - type: 'hbox', - className: 'cke_dialog_footer_buttons', - widths: [], - children: definition.buttons - }, buttonsHtml ).getChild(); - this.parts.footer.setHtml( buttonsHtml.join( '' ) ); - - for ( i = 0; i < buttons.length; i++ ) - this._.buttons[ buttons[ i ].id ] = buttons[ i ]; - }; - - // Focusable interface. Use it via dialog.addFocusable. - function Focusable( dialog, element, index ) { - this.element = element; - this.focusIndex = index; - // TODO: support tabIndex for focusables. - this.tabIndex = 0; - this.isFocusable = function() { - return !element.getAttribute( 'disabled' ) && element.isVisible(); - }; - this.focus = function() { - dialog._.currentFocusIndex = this.focusIndex; - this.element.focus(); - }; - // Bind events - element.on( 'keydown', function( e ) { - if ( e.data.getKeystroke() in { 32:1,13:1 } ) - this.fire( 'click' ); - }); - element.on( 'focus', function() { - this.fire( 'mouseover' ); - }); - element.on( 'blur', function() { - this.fire( 'mouseout' ); - }); - } - - // Re-layout the dialog on window resize. - function resizeWithWindow( dialog ) { - var win = CKEDITOR.document.getWindow(); - function resizeHandler() { dialog.layout(); } - win.on( 'resize', resizeHandler ); - dialog.on( 'hide', function() { win.removeListener( 'resize', resizeHandler ); } ); - } - - CKEDITOR.dialog.prototype = { - destroy: function() { - this.hide(); - this._.element.remove(); - }, - - /** - * Resizes the dialog. - * - * dialogObj.resize( 800, 640 ); - * - * @method - * @param {Number} width The width of the dialog in pixels. - * @param {Number} height The height of the dialog in pixels. - */ - resize: (function() { - return function( width, height ) { - if ( this._.contentSize && this._.contentSize.width == width && this._.contentSize.height == height ) - return; - - CKEDITOR.dialog.fire( 'resize', { - dialog: this, - width: width, - height: height - }, this._.editor ); - - this.fire( 'resize', { - width: width, - height: height - }, this._.editor ); - - var contents = this.parts.contents; - contents.setStyles({ - width: width + 'px', - height: height + 'px' - }); - - // Update dialog position when dimension get changed in RTL. - if ( this._.editor.lang.dir == 'rtl' && this._.position ) - this._.position.x = CKEDITOR.document.getWindow().getViewPaneSize().width - this._.contentSize.width - parseInt( this._.element.getFirst().getStyle( 'right' ), 10 ); - - this._.contentSize = { width: width, height: height }; - }; - })(), - - /** - * Gets the current size of the dialog in pixels. - * - * var width = dialogObj.getSize().width; - * - * @returns {Object} - * @returns {Number} return.width - * @returns {Number} return.height - */ - getSize: function() { - var element = this._.element.getFirst(); - return { width: element.$.offsetWidth || 0, height: element.$.offsetHeight || 0 }; - }, - - /** - * Moves the dialog to an `(x, y)` coordinate relative to the window. - * - * dialogObj.move( 10, 40 ); - * - * @method - * @param {Number} x The target x-coordinate. - * @param {Number} y The target y-coordinate. - * @param {Boolean} save Flag indicate whether the dialog position should be remembered on next open up. - */ - move: function( x, y, save ) { - - // The dialog may be fixed positioned or absolute positioned. Ask the - // browser what is the current situation first. - var element = this._.element.getFirst(), rtl = this._.editor.lang.dir == 'rtl'; - var isFixed = element.getComputedStyle( 'position' ) == 'fixed'; - - // (#8888) In some cases of a very small viewport, dialog is incorrectly - // positioned in IE7. It also happens that it remains sticky and user cannot - // scroll down/up to reveal dialog's content below/above the viewport; this is - // cumbersome. - // The only way to fix this is to move mouse out of the browser and - // go back to see that dialog position is automagically fixed. No events, - // no style change - pure magic. This is a IE7 rendering issue, which can be - // fixed with dummy style redraw on each move. - if ( CKEDITOR.env.ie ) - element.setStyle( 'zoom', '100%' ); - - if ( isFixed && this._.position && this._.position.x == x && this._.position.y == y ) - return; - - // Save the current position. - this._.position = { x: x, y: y }; - - // If not fixed positioned, add scroll position to the coordinates. - if ( !isFixed ) { - var scrollPosition = CKEDITOR.document.getWindow().getScrollPosition(); - x += scrollPosition.x; - y += scrollPosition.y; - } - - // Translate coordinate for RTL. - if ( rtl ) { - var dialogSize = this.getSize(), viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(); - x = viewPaneSize.width - dialogSize.width - x; - } - - var styles = { 'top': ( y > 0 ? y : 0 ) + 'px' }; - styles[ rtl ? 'right' : 'left' ] = ( x > 0 ? x : 0 ) + 'px'; - - element.setStyles( styles ); - - save && ( this._.moved = 1 ); - }, - - /** - * Gets the dialog's position in the window. - * - * var dialogX = dialogObj.getPosition().x; - * - * @returns {Object} - * @returns {Number} return.x - * @returns {Number} return.y - */ - getPosition: function() { - return CKEDITOR.tools.extend( {}, this._.position ); - }, - - /** - * Shows the dialog box. - * - * dialogObj.show(); - */ - show: function() { - // Insert the dialog's element to the root document. - var element = this._.element; - var definition = this.definition; - if ( !( element.getParent() && element.getParent().equals( CKEDITOR.document.getBody() ) ) ) - element.appendTo( CKEDITOR.document.getBody() ); - else - element.setStyle( 'display', 'block' ); - - // FIREFOX BUG: Fix vanishing caret for Firefox 2 or Gecko 1.8. - if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) { - var dialogElement = this.parts.dialog; - dialogElement.setStyle( 'position', 'absolute' ); - setTimeout( function() { - dialogElement.setStyle( 'position', 'fixed' ); - }, 0 ); - } - - - // First, set the dialog to an appropriate size. - this.resize( this._.contentSize && this._.contentSize.width || definition.width || definition.minWidth, this._.contentSize && this._.contentSize.height || definition.height || definition.minHeight ); - - // Reset all inputs back to their default value. - this.reset(); - - // Select the first tab by default. - this.selectPage( this.definition.contents[ 0 ].id ); - - // Set z-index. - if ( CKEDITOR.dialog._.currentZIndex === null ) - CKEDITOR.dialog._.currentZIndex = this._.editor.config.baseFloatZIndex; - this._.element.getFirst().setStyle( 'z-index', CKEDITOR.dialog._.currentZIndex += 10 ); - - // Maintain the dialog ordering and dialog cover. - if ( CKEDITOR.dialog._.currentTop === null ) { - CKEDITOR.dialog._.currentTop = this; - this._.parentDialog = null; - showCover( this._.editor ); - - } else { - this._.parentDialog = CKEDITOR.dialog._.currentTop; - var parentElement = this._.parentDialog.getElement().getFirst(); - parentElement.$.style.zIndex -= Math.floor( this._.editor.config.baseFloatZIndex / 2 ); - CKEDITOR.dialog._.currentTop = this; - } - - element.on( 'keydown', accessKeyDownHandler ); - element.on( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler ); - - // Reset the hasFocus state. - this._.hasFocus = false; - - CKEDITOR.tools.setTimeout( function() { - this.layout(); - resizeWithWindow( this ); - - this.parts.dialog.setStyle( 'visibility', '' ); - - // Execute onLoad for the first show. - this.fireOnce( 'load', {} ); - CKEDITOR.ui.fire( 'ready', this ); - - this.fire( 'show', {} ); - this._.editor.fire( 'dialogShow', this ); - - if ( !this._.parentDialog ) - this._.editor.focusManager.lock(); - - // Save the initial values of the dialog. - this.foreach( function( contentObj ) { - contentObj.setInitValue && contentObj.setInitValue(); - }); - - }, 100, this ); - }, - - /** - * Rearrange the dialog to its previous position or the middle of the window. - * - * @since 3.5 - */ - layout: function() { - var el = this.parts.dialog; - var dialogSize = this.getSize(); - var win = CKEDITOR.document.getWindow(), - viewSize = win.getViewPaneSize(); - - var posX = ( viewSize.width - dialogSize.width ) / 2, - posY = ( viewSize.height - dialogSize.height ) / 2; - - // Switch to absolute position when viewport is smaller than dialog size. - if ( !CKEDITOR.env.ie6Compat ) { - if ( dialogSize.height + ( posY > 0 ? posY : 0 ) > viewSize.height || - dialogSize.width + ( posX > 0 ? posX : 0 ) > viewSize.width ) - el.setStyle( 'position', 'absolute' ); - else - el.setStyle( 'position', 'fixed' ); - } - - this.move( this._.moved ? this._.position.x : posX, - this._.moved ? this._.position.y : posY ); - }, - - /** - * Executes a function for each UI element. - * - * @param {Function} fn Function to execute for each UI element. - * @returns {CKEDITOR.dialog} The current dialog object. - */ - foreach: function( fn ) { - for ( var i in this._.contents ) { - for ( var j in this._.contents[ i ] ) - fn.call( this, this._.contents[ i ][ j ] ); - } - return this; - }, - - /** - * Resets all input values in the dialog. - * - * dialogObj.reset(); - * - * @method - * @chainable - */ - reset: (function() { - var fn = function( widget ) { - if ( widget.reset ) - widget.reset( 1 ); - }; - return function() { - this.foreach( fn ); - return this; - }; - })(), - - - /** - * Calls the {@link CKEDITOR.dialog.definition.uiElement#setup} method of each - * of the UI elements, with the arguments passed through it. - * It is usually being called when the dialog is opened, to put the initial value inside the field. - * - * dialogObj.setupContent(); - * - * var timestamp = ( new Date() ).valueOf(); - * dialogObj.setupContent( timestamp ); - */ - setupContent: function() { - var args = arguments; - this.foreach( function( widget ) { - if ( widget.setup ) - widget.setup.apply( widget, args ); - }); - }, - - /** - * Calls the {@link CKEDITOR.dialog.definition.uiElement#commit} method of each - * of the UI elements, with the arguments passed through it. - * It is usually being called when the user confirms the dialog, to process the values. - * - * dialogObj.commitContent(); - * - * var timestamp = ( new Date() ).valueOf(); - * dialogObj.commitContent( timestamp ); - */ - commitContent: function() { - var args = arguments; - this.foreach( function( widget ) { - // Make sure IE triggers "change" event on last focused input before closing the dialog. (#7915) - if ( CKEDITOR.env.ie && this._.currentFocusIndex == widget.focusIndex ) - widget.getInputElement().$.blur(); - - if ( widget.commit ) - widget.commit.apply( widget, args ); - }); - }, - - /** - * Hides the dialog box. - * - * dialogObj.hide(); - */ - hide: function() { - if ( !this.parts.dialog.isVisible() ) - return; - - this.fire( 'hide', {} ); - this._.editor.fire( 'dialogHide', this ); - // Reset the tab page. - this.selectPage( this._.tabIdList[ 0 ] ); - var element = this._.element; - element.setStyle( 'display', 'none' ); - this.parts.dialog.setStyle( 'visibility', 'hidden' ); - // Unregister all access keys associated with this dialog. - unregisterAccessKey( this ); - - // Close any child(top) dialogs first. - while ( CKEDITOR.dialog._.currentTop != this ) - CKEDITOR.dialog._.currentTop.hide(); - - // Maintain dialog ordering and remove cover if needed. - if ( !this._.parentDialog ) - hideCover( this._.editor ); - else { - var parentElement = this._.parentDialog.getElement().getFirst(); - parentElement.setStyle( 'z-index', parseInt( parentElement.$.style.zIndex, 10 ) + Math.floor( this._.editor.config.baseFloatZIndex / 2 ) ); - } - CKEDITOR.dialog._.currentTop = this._.parentDialog; - - // Deduct or clear the z-index. - if ( !this._.parentDialog ) { - CKEDITOR.dialog._.currentZIndex = null; - - // Remove access key handlers. - element.removeListener( 'keydown', accessKeyDownHandler ); - element.removeListener( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler ); - - var editor = this._.editor; - editor.focus(); - - // Give a while before unlock, waiting for focus to return to the editable. (#172) - setTimeout( function() { editor.focusManager.unlock(); }, 0 ); - - } else - CKEDITOR.dialog._.currentZIndex -= 10; - - delete this._.parentDialog; - // Reset the initial values of the dialog. - this.foreach( function( contentObj ) { - contentObj.resetInitValue && contentObj.resetInitValue(); - }); - }, - - /** - * Adds a tabbed page into the dialog. - * - * @param {Object} contents Content definition. - */ - addPage: function( contents ) { - if ( contents.requiredContent && !this._.editor.filter.check( contents.requiredContent ) ) - return; - - var pageHtml = [], - titleHtml = contents.label ? ' title="' + CKEDITOR.tools.htmlEncode( contents.label ) + '"' : '', - elements = contents.elements, - vbox = CKEDITOR.dialog._.uiElementBuilders.vbox.build( this, { - type: 'vbox', - className: 'cke_dialog_page_contents', - children: contents.elements, - expand: !!contents.expand, - padding: contents.padding, - style: contents.style || 'width: 100%;' - }, pageHtml ); - - var contentMap = this._.contents[ contents.id ] = {}, - cursor, - children = vbox.getChild(), - enabledFields = 0; - - while ( ( cursor = children.shift() ) ) { - // Count all allowed fields. - if ( !cursor.notAllowed && cursor.type != 'hbox' && cursor.type != 'vbox' ) - enabledFields++; - - contentMap[ cursor.id ] = cursor; - if ( typeof( cursor.getChild ) == 'function' ) - children.push.apply( children, cursor.getChild() ); - } - - // If all fields are disabled (because they are not allowed) hide this tab. - if ( !enabledFields ) - contents.hidden = true; - - // Create the HTML for the tab and the content block. - var page = CKEDITOR.dom.element.createFromHtml( pageHtml.join( '' ) ); - page.setAttribute( 'role', 'tabpanel' ); - - var env = CKEDITOR.env; - var tabId = 'cke_' + contents.id + '_' + CKEDITOR.tools.getNextNumber(), - tab = CKEDITOR.dom.element.createFromHtml( [ - '<a class="cke_dialog_tab"', - ( this._.pageCount > 0 ? ' cke_last' : 'cke_first' ), - titleHtml, - ( !!contents.hidden ? ' style="display:none"' : '' ), - ' id="', tabId, '"', - env.gecko && env.version >= 10900 && !env.hc ? '' : ' href="javascript:void(0)"', - ' tabIndex="-1"', - ' hidefocus="true"', - ' role="tab">', - contents.label, - '</a>' - ].join( '' ) ); - - page.setAttribute( 'aria-labelledby', tabId ); - - // Take records for the tabs and elements created. - this._.tabs[ contents.id ] = [ tab, page ]; - this._.tabIdList.push( contents.id ); - !contents.hidden && this._.pageCount++; - this._.lastTab = tab; - this.updateStyle(); - - // Attach the DOM nodes. - - page.setAttribute( 'name', contents.id ); - page.appendTo( this.parts.contents ); - - tab.unselectable(); - this.parts.tabs.append( tab ); - - // Add access key handlers if access key is defined. - if ( contents.accessKey ) { - registerAccessKey( this, this, 'CTRL+' + contents.accessKey, tabAccessKeyDown, tabAccessKeyUp ); - this._.accessKeyMap[ 'CTRL+' + contents.accessKey ] = contents.id; - } - }, - - /** - * Activates a tab page in the dialog by its id. - * - * dialogObj.selectPage( 'tab_1' ); - * - * @param {String} id The id of the dialog tab to be activated. - */ - selectPage: function( id ) { - if ( this._.currentTabId == id ) - return; - - // Returning true means that the event has been canceled - if ( this.fire( 'selectPage', { page: id, currentPage: this._.currentTabId } ) === true ) - return; - - // Hide the non-selected tabs and pages. - for ( var i in this._.tabs ) { - var tab = this._.tabs[ i ][ 0 ], - page = this._.tabs[ i ][ 1 ]; - if ( i != id ) { - tab.removeClass( 'cke_dialog_tab_selected' ); - page.hide(); - } - page.setAttribute( 'aria-hidden', i != id ); - } - - var selected = this._.tabs[ id ]; - selected[ 0 ].addClass( 'cke_dialog_tab_selected' ); - - // [IE] an invisible input[type='text'] will enlarge it's width - // if it's value is long when it shows, so we clear it's value - // before it shows and then recover it (#5649) - if ( CKEDITOR.env.ie6Compat || CKEDITOR.env.ie7Compat ) { - clearOrRecoverTextInputValue( selected[ 1 ] ); - selected[ 1 ].show(); - setTimeout( function() { - clearOrRecoverTextInputValue( selected[ 1 ], 1 ); - }, 0 ); - } else - selected[ 1 ].show(); - - this._.currentTabId = id; - this._.currentTabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, id ); - }, - - /** - * Dialog state-specific style updates. - */ - updateStyle: function() { - // If only a single page shown, a different style is used in the central pane. - this.parts.dialog[ ( this._.pageCount === 1 ? 'add' : 'remove' ) + 'Class' ]( 'cke_single_page' ); - }, - - /** - * Hides a page's tab away from the dialog. - * - * dialog.hidePage( 'tab_3' ); - * - * @param {String} id The page's Id. - */ - hidePage: function( id ) { - var tab = this._.tabs[ id ] && this._.tabs[ id ][ 0 ]; - if ( !tab || this._.pageCount == 1 || !tab.isVisible() ) - return; - // Switch to other tab first when we're hiding the active tab. - else if ( id == this._.currentTabId ) - this.selectPage( getPreviousVisibleTab.call( this ) ); - - tab.hide(); - this._.pageCount--; - this.updateStyle(); - }, - - /** - * Unhides a page's tab. - * - * dialog.showPage( 'tab_2' ); - * - * @param {String} id The page's Id. - */ - showPage: function( id ) { - var tab = this._.tabs[ id ] && this._.tabs[ id ][ 0 ]; - if ( !tab ) - return; - tab.show(); - this._.pageCount++; - this.updateStyle(); - }, - - /** - * Gets the root DOM element of the dialog. - * - * var dialogElement = dialogObj.getElement().getFirst(); - * dialogElement.setStyle( 'padding', '5px' ); - * - * @returns {CKEDITOR.dom.element} The `<span>` element containing this dialog. - */ - getElement: function() { - return this._.element; - }, - - /** - * Gets the name of the dialog. - * - * var dialogName = dialogObj.getName(); - * - * @returns {String} The name of this dialog. - */ - getName: function() { - return this._.name; - }, - - /** - * Gets a dialog UI element object from a dialog page. - * - * dialogObj.getContentElement( 'tabId', 'elementId' ).setValue( 'Example' ); - * - * @param {String} pageId id of dialog page. - * @param {String} elementId id of UI element. - * @returns {CKEDITOR.ui.dialog.uiElement} The dialog UI element. - */ - getContentElement: function( pageId, elementId ) { - var page = this._.contents[ pageId ]; - return page && page[ elementId ]; - }, - - /** - * Gets the value of a dialog UI element. - * - * alert( dialogObj.getValueOf( 'tabId', 'elementId' ) ); - * - * @param {String} pageId id of dialog page. - * @param {String} elementId id of UI element. - * @returns {Object} The value of the UI element. - */ - getValueOf: function( pageId, elementId ) { - return this.getContentElement( pageId, elementId ).getValue(); - }, - - /** - * Sets the value of a dialog UI element. - * - * dialogObj.setValueOf( 'tabId', 'elementId', 'Example' ); - * - * @param {String} pageId id of the dialog page. - * @param {String} elementId id of the UI element. - * @param {Object} value The new value of the UI element. - */ - setValueOf: function( pageId, elementId, value ) { - return this.getContentElement( pageId, elementId ).setValue( value ); - }, - - /** - * Gets the UI element of a button in the dialog's button row. - * - * @returns {CKEDITOR.ui.dialog.button} The button object. - * - * @param {String} id The id of the button. - */ - getButton: function( id ) { - return this._.buttons[ id ]; - }, - - /** - * Simulates a click to a dialog button in the dialog's button row. - * - * @returns The return value of the dialog's `click` event. - * - * @param {String} id The id of the button. - */ - click: function( id ) { - return this._.buttons[ id ].click(); - }, - - /** - * Disables a dialog button. - * - * @param {String} id The id of the button. - */ - disableButton: function( id ) { - return this._.buttons[ id ].disable(); - }, - - /** - * Enables a dialog button. - * - * @param {String} id The id of the button. - */ - enableButton: function( id ) { - return this._.buttons[ id ].enable(); - }, - - /** - * Gets the number of pages in the dialog. - * - * @returns {Number} Page count. - */ - getPageCount: function() { - return this._.pageCount; - }, - - /** - * Gets the editor instance which opened this dialog. - * - * @returns {CKEDITOR.editor} Parent editor instances. - */ - getParentEditor: function() { - return this._.editor; - }, - - /** - * Gets the element that was selected when opening the dialog, if any. - * - * @returns {CKEDITOR.dom.element} The element that was selected, or `null`. - */ - getSelectedElement: function() { - return this.getParentEditor().getSelection().getSelectedElement(); - }, - - /** - * Adds element to dialog's focusable list. - * - * @param {CKEDITOR.dom.element} element - * @param {Number} [index] - */ - addFocusable: function( element, index ) { - if ( typeof index == 'undefined' ) { - index = this._.focusList.length; - this._.focusList.push( new Focusable( this, element, index ) ); - } else { - this._.focusList.splice( index, 0, new Focusable( this, element, index ) ); - for ( var i = index + 1; i < this._.focusList.length; i++ ) - this._.focusList[ i ].focusIndex++; - } - } - }; - - CKEDITOR.tools.extend( CKEDITOR.dialog, { - /** - * Registers a dialog. - * - * // Full sample plugin, which does not only register a dialog window but also adds an item to the context menu. - * // To open the dialog window, choose "Open dialog" in the context menu. - * CKEDITOR.plugins.add( 'myplugin', { - * init: function( editor ) { - * editor.addCommand( 'mydialog',new CKEDITOR.dialogCommand( 'mydialog' ) ); - * - * if ( editor.contextMenu ) { - * editor.addMenuGroup( 'mygroup', 10 ); - * editor.addMenuItem( 'My Dialog', { - * label: 'Open dialog', - * command: 'mydialog', - * group: 'mygroup' - * } ); - * editor.contextMenu.addListener( function( element ) { - * return { 'My Dialog': CKEDITOR.TRISTATE_OFF }; - * } ); - * } - * - * CKEDITOR.dialog.add( 'mydialog', function( api ) { - * // CKEDITOR.dialog.definition - * var dialogDefinition = { - * title: 'Sample dialog', - * minWidth: 390, - * minHeight: 130, - * contents: [ - * { - * id: 'tab1', - * label: 'Label', - * title: 'Title', - * expand: true, - * padding: 0, - * elements: [ - * { - * type: 'html', - * html: '<p>This is some sample HTML content.</p>' - * }, - * { - * type: 'textarea', - * id: 'textareaId', - * rows: 4, - * cols: 40 - * } - * ] - * } - * ], - * buttons: [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ], - * onOk: function() { - * // "this" is now a CKEDITOR.dialog object. - * // Accessing dialog elements: - * var textareaObj = this.getContentElement( 'tab1', 'textareaId' ); - * alert( "You have entered: " + textareaObj.getValue() ); - * } - * }; - * - * return dialogDefinition; - * } ); - * } - * } ); - * - * CKEDITOR.replace( 'editor1', { extraPlugins: 'myplugin' } ); - * - * @static - * @param {String} name The dialog's name. - * @param {Function/String} dialogDefinition - * A function returning the dialog's definition, or the URL to the `.js` file holding the function. - * The function should accept an argument `editor` which is the current editor instance, and - * return an object conforming to {@link CKEDITOR.dialog.definition}. - * @see CKEDITOR.dialog.definition - */ - add: function( name, dialogDefinition ) { - // Avoid path registration from multiple instances override definition. - if ( !this._.dialogDefinitions[ name ] || typeof dialogDefinition == 'function' ) - this._.dialogDefinitions[ name ] = dialogDefinition; - }, - - /** - * @static - * @todo - */ - exists: function( name ) { - return !!this._.dialogDefinitions[ name ]; - }, - - /** - * @static - * @todo - */ - getCurrent: function() { - return CKEDITOR.dialog._.currentTop; - }, - - /** - * Check whether tab wasn't removed by {@link CKEDITOR.config#removeDialogTabs}. - * - * @since 4.1 - * @static - * @param {CKEDITOR.editor} editor - * @param {String} dialogName - * @param {String} tabName - * @returns {Boolean} - */ - isTabEnabled: function( editor, dialogName, tabName ) { - var cfg = editor.config.removeDialogTabs; - - return !( cfg && cfg.match( new RegExp( '(?:^|;)' + dialogName + ':' + tabName + '(?:$|;)', 'i' ) ) ); - }, - - /** - * The default OK button for dialogs. Fires the `ok` event and closes the dialog if the event succeeds. - * - * @static - * @method - */ - okButton: (function() { - var retval = function( editor, override ) { - override = override || {}; - return CKEDITOR.tools.extend({ - id: 'ok', - type: 'button', - label: editor.lang.common.ok, - 'class': 'cke_dialog_ui_button_ok', - onClick: function( evt ) { - var dialog = evt.data.dialog; - if ( dialog.fire( 'ok', { hide: true } ).hide !== false ) - dialog.hide(); - } - }, override, true ); - }; - retval.type = 'button'; - retval.override = function( override ) { - return CKEDITOR.tools.extend( function( editor ) { - return retval( editor, override ); - }, { type: 'button' }, true ); - }; - return retval; - })(), - - /** - * The default cancel button for dialogs. Fires the `cancel` event and - * closes the dialog if no UI element value changed. - * - * @static - * @method - */ - cancelButton: (function() { - var retval = function( editor, override ) { - override = override || {}; - return CKEDITOR.tools.extend({ - id: 'cancel', - type: 'button', - label: editor.lang.common.cancel, - 'class': 'cke_dialog_ui_button_cancel', - onClick: function( evt ) { - var dialog = evt.data.dialog; - if ( dialog.fire( 'cancel', { hide: true } ).hide !== false ) - dialog.hide(); - } - }, override, true ); - }; - retval.type = 'button'; - retval.override = function( override ) { - return CKEDITOR.tools.extend( function( editor ) { - return retval( editor, override ); - }, { type: 'button' }, true ); - }; - return retval; - })(), - - /** - * Registers a dialog UI element. - * - * @static - * @param {String} typeName The name of the UI element. - * @param {Function} builder The function to build the UI element. - */ - addUIElement: function( typeName, builder ) { - this._.uiElementBuilders[ typeName ] = builder; - } - }); - - CKEDITOR.dialog._ = { - uiElementBuilders: {}, - - dialogDefinitions: {}, - - currentTop: null, - - currentZIndex: null - }; - - // "Inherit" (copy actually) from CKEDITOR.event. - CKEDITOR.event.implementOn( CKEDITOR.dialog ); - CKEDITOR.event.implementOn( CKEDITOR.dialog.prototype ); - - var defaultDialogDefinition = { - resizable: CKEDITOR.DIALOG_RESIZE_BOTH, - minWidth: 600, - minHeight: 400, - buttons: [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ] - }; - - // Tool function used to return an item from an array based on its id - // property. - var getById = function( array, id, recurse ) { - for ( var i = 0, item; - ( item = array[ i ] ); i++ ) { - if ( item.id == id ) - return item; - if ( recurse && item[ recurse ] ) { - var retval = getById( item[ recurse ], id, recurse ); - if ( retval ) - return retval; - } - } - return null; - }; - - // Tool function used to add an item into an array. - var addById = function( array, newItem, nextSiblingId, recurse, nullIfNotFound ) { - if ( nextSiblingId ) { - for ( var i = 0, item; - ( item = array[ i ] ); i++ ) { - if ( item.id == nextSiblingId ) { - array.splice( i, 0, newItem ); - return newItem; - } - - if ( recurse && item[ recurse ] ) { - var retval = addById( item[ recurse ], newItem, nextSiblingId, recurse, true ); - if ( retval ) - return retval; - } - } - - if ( nullIfNotFound ) - return null; - } - - array.push( newItem ); - return newItem; - }; - - // Tool function used to remove an item from an array based on its id. - var removeById = function( array, id, recurse ) { - for ( var i = 0, item; - ( item = array[ i ] ); i++ ) { - if ( item.id == id ) - return array.splice( i, 1 ); - if ( recurse && item[ recurse ] ) { - var retval = removeById( item[ recurse ], id, recurse ); - if ( retval ) - return retval; - } - } - return null; - }; - - /** - * This class is not really part of the API. It is the `definition` property value - * passed to `dialogDefinition` event handlers. - * - * CKEDITOR.on( 'dialogDefinition', function( evt ) { - * var definition = evt.data.definition; - * var content = definition.getContents( 'page1' ); - * // ... - * } ); - * - * @private - * @class CKEDITOR.dialog.definitionObject - * @extends CKEDITOR.dialog.definition - * @constructor Creates a definitionObject class instance. - */ - var definitionObject = function( dialog, dialogDefinition ) { - // TODO : Check if needed. - this.dialog = dialog; - - // Transform the contents entries in contentObjects. - var contents = dialogDefinition.contents; - for ( var i = 0, content; - ( content = contents[ i ] ); i++ ) - contents[ i ] = content && new contentObject( dialog, content ); - - CKEDITOR.tools.extend( this, dialogDefinition ); - }; - - definitionObject.prototype = { - /** - * Gets a content definition. - * - * @param {String} id The id of the content definition. - * @returns {CKEDITOR.dialog.definition.content} The content definition matching id. - */ - getContents: function( id ) { - return getById( this.contents, id ); - }, - - /** - * Gets a button definition. - * - * @param {String} id The id of the button definition. - * @returns {CKEDITOR.dialog.definition.button} The button definition matching id. - */ - getButton: function( id ) { - return getById( this.buttons, id ); - }, - - /** - * Adds a content definition object under this dialog definition. - * - * @param {CKEDITOR.dialog.definition.content} contentDefinition The - * content definition. - * @param {String} [nextSiblingId] The id of an existing content - * definition which the new content definition will be inserted - * before. Omit if the new content definition is to be inserted as - * the last item. - * @returns {CKEDITOR.dialog.definition.content} The inserted content definition. - */ - addContents: function( contentDefinition, nextSiblingId ) { - return addById( this.contents, contentDefinition, nextSiblingId ); - }, - - /** - * Adds a button definition object under this dialog definition. - * - * @param {CKEDITOR.dialog.definition.button} buttonDefinition The - * button definition. - * @param {String} [nextSiblingId] The id of an existing button - * definition which the new button definition will be inserted - * before. Omit if the new button definition is to be inserted as - * the last item. - * @returns {CKEDITOR.dialog.definition.button} The inserted button definition. - */ - addButton: function( buttonDefinition, nextSiblingId ) { - return addById( this.buttons, buttonDefinition, nextSiblingId ); - }, - - /** - * Removes a content definition from this dialog definition. - * - * @param {String} id The id of the content definition to be removed. - * @returns {CKEDITOR.dialog.definition.content} The removed content definition. - */ - removeContents: function( id ) { - removeById( this.contents, id ); - }, - - /** - * Removes a button definition from the dialog definition. - * - * @param {String} id The id of the button definition to be removed. - * @returns {CKEDITOR.dialog.definition.button} The removed button definition. - */ - removeButton: function( id ) { - removeById( this.buttons, id ); - } - }; - - /** - * This class is not really part of the API. It is the template of the - * objects representing content pages inside the - * CKEDITOR.dialog.definitionObject. - * - * CKEDITOR.on( 'dialogDefinition', function( evt ) { - * var definition = evt.data.definition; - * var content = definition.getContents( 'page1' ); - * content.remove( 'textInput1' ); - * // ... - * } ); - * - * @private - * @class CKEDITOR.dialog.definition.contentObject - * @constructor Creates a contentObject class instance. - */ - function contentObject( dialog, contentDefinition ) { - this._ = { - dialog: dialog - }; - - CKEDITOR.tools.extend( this, contentDefinition ); - } - - contentObject.prototype = { - /** - * Gets a UI element definition under the content definition. - * - * @param {String} id The id of the UI element definition. - * @returns {CKEDITOR.dialog.definition.uiElement} - */ - get: function( id ) { - return getById( this.elements, id, 'children' ); - }, - - /** - * Adds a UI element definition to the content definition. - * - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition The - * UI elemnet definition to be added. - * @param {String} nextSiblingId The id of an existing UI element - * definition which the new UI element definition will be inserted - * before. Omit if the new button definition is to be inserted as - * the last item. - * @returns {CKEDITOR.dialog.definition.uiElement} The element definition inserted. - */ - add: function( elementDefinition, nextSiblingId ) { - return addById( this.elements, elementDefinition, nextSiblingId, 'children' ); - }, - - /** - * Removes a UI element definition from the content definition. - * - * @param {String} id The id of the UI element definition to be removed. - * @returns {CKEDITOR.dialog.definition.uiElement} The element definition removed. - */ - remove: function( id ) { - removeById( this.elements, id, 'children' ); - } - }; - - function initDragAndDrop( dialog ) { - var lastCoords = null, - abstractDialogCoords = null, - element = dialog.getElement().getFirst(), - editor = dialog.getParentEditor(), - magnetDistance = editor.config.dialog_magnetDistance, - margins = CKEDITOR.skin.margins || [ 0, 0, 0, 0 ]; - - if ( typeof magnetDistance == 'undefined' ) - magnetDistance = 20; - - function mouseMoveHandler( evt ) { - var dialogSize = dialog.getSize(), - viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(), - x = evt.data.$.screenX, - y = evt.data.$.screenY, - dx = x - lastCoords.x, - dy = y - lastCoords.y, - realX, realY; - - lastCoords = { x: x, y: y }; - abstractDialogCoords.x += dx; - abstractDialogCoords.y += dy; - - if ( abstractDialogCoords.x + margins[ 3 ] < magnetDistance ) - realX = -margins[ 3 ]; - else if ( abstractDialogCoords.x - margins[ 1 ] > viewPaneSize.width - dialogSize.width - magnetDistance ) - realX = viewPaneSize.width - dialogSize.width + ( editor.lang.dir == 'rtl' ? 0 : margins[ 1 ] ); - else - realX = abstractDialogCoords.x; - - if ( abstractDialogCoords.y + margins[ 0 ] < magnetDistance ) - realY = -margins[ 0 ]; - else if ( abstractDialogCoords.y - margins[ 2 ] > viewPaneSize.height - dialogSize.height - magnetDistance ) - realY = viewPaneSize.height - dialogSize.height + margins[ 2 ]; - else - realY = abstractDialogCoords.y; - - dialog.move( realX, realY, 1 ); - - evt.data.preventDefault(); - } - - function mouseUpHandler( evt ) { - CKEDITOR.document.removeListener( 'mousemove', mouseMoveHandler ); - CKEDITOR.document.removeListener( 'mouseup', mouseUpHandler ); - - if ( CKEDITOR.env.ie6Compat ) { - var coverDoc = currentCover.getChild( 0 ).getFrameDocument(); - coverDoc.removeListener( 'mousemove', mouseMoveHandler ); - coverDoc.removeListener( 'mouseup', mouseUpHandler ); - } - } - - dialog.parts.title.on( 'mousedown', function( evt ) { - lastCoords = { x: evt.data.$.screenX, y: evt.data.$.screenY }; - - CKEDITOR.document.on( 'mousemove', mouseMoveHandler ); - CKEDITOR.document.on( 'mouseup', mouseUpHandler ); - abstractDialogCoords = dialog.getPosition(); - - if ( CKEDITOR.env.ie6Compat ) { - var coverDoc = currentCover.getChild( 0 ).getFrameDocument(); - coverDoc.on( 'mousemove', mouseMoveHandler ); - coverDoc.on( 'mouseup', mouseUpHandler ); - } - - evt.data.preventDefault(); - }, dialog ); - } - - function initResizeHandles( dialog ) { - var def = dialog.definition, - resizable = def.resizable; - - if ( resizable == CKEDITOR.DIALOG_RESIZE_NONE ) - return; - - var editor = dialog.getParentEditor(); - var wrapperWidth, wrapperHeight, viewSize, origin, startSize, dialogCover; - - var mouseDownFn = CKEDITOR.tools.addFunction( function( $event ) { - startSize = dialog.getSize(); - - var content = dialog.parts.contents, - iframeDialog = content.$.getElementsByTagName( 'iframe' ).length; - - // Shim to help capturing "mousemove" over iframe. - if ( iframeDialog ) { - dialogCover = CKEDITOR.dom.element.createFromHtml( '<div class="cke_dialog_resize_cover" style="height: 100%; position: absolute; width: 100%;"></div>' ); - content.append( dialogCover ); - } - - // Calculate the offset between content and chrome size. - wrapperHeight = startSize.height - dialog.parts.contents.getSize( 'height', !( CKEDITOR.env.gecko || CKEDITOR.env.opera || CKEDITOR.env.ie && CKEDITOR.env.quirks ) ); - wrapperWidth = startSize.width - dialog.parts.contents.getSize( 'width', 1 ); - - origin = { x: $event.screenX, y: $event.screenY }; - - viewSize = CKEDITOR.document.getWindow().getViewPaneSize(); - - CKEDITOR.document.on( 'mousemove', mouseMoveHandler ); - CKEDITOR.document.on( 'mouseup', mouseUpHandler ); - - if ( CKEDITOR.env.ie6Compat ) { - var coverDoc = currentCover.getChild( 0 ).getFrameDocument(); - coverDoc.on( 'mousemove', mouseMoveHandler ); - coverDoc.on( 'mouseup', mouseUpHandler ); - } - - $event.preventDefault && $event.preventDefault(); - }); - - // Prepend the grip to the dialog. - dialog.on( 'load', function() { - var direction = ''; - if ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH ) - direction = ' cke_resizer_horizontal'; - else if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT ) - direction = ' cke_resizer_vertical'; - var resizer = CKEDITOR.dom.element.createFromHtml( - '<div' + - ' class="cke_resizer' + direction + ' cke_resizer_' + editor.lang.dir + '"' + - ' title="' + CKEDITOR.tools.htmlEncode( editor.lang.common.resize ) + '"' + - ' onmousedown="CKEDITOR.tools.callFunction(' + mouseDownFn + ', event )">' + - // BLACK LOWER RIGHT TRIANGLE (ltr) - // BLACK LOWER LEFT TRIANGLE (rtl) - ( editor.lang.dir == 'ltr' ? '\u25E2' : '\u25E3' ) + - '</div>' ); - dialog.parts.footer.append( resizer, 1 ); - }); - editor.on( 'destroy', function() { - CKEDITOR.tools.removeFunction( mouseDownFn ); - }); - - function mouseMoveHandler( evt ) { - var rtl = editor.lang.dir == 'rtl', - dx = ( evt.data.$.screenX - origin.x ) * ( rtl ? -1 : 1 ), - dy = evt.data.$.screenY - origin.y, - width = startSize.width, - height = startSize.height, - internalWidth = width + dx * ( dialog._.moved ? 1 : 2 ), - internalHeight = height + dy * ( dialog._.moved ? 1 : 2 ), - element = dialog._.element.getFirst(), - right = rtl && element.getComputedStyle( 'right' ), - position = dialog.getPosition(); - - if ( position.y + internalHeight > viewSize.height ) - internalHeight = viewSize.height - position.y; - - if ( ( rtl ? right : position.x ) + internalWidth > viewSize.width ) - internalWidth = viewSize.width - ( rtl ? right : position.x ); - - // Make sure the dialog will not be resized to the wrong side when it's in the leftmost position for RTL. - if ( ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH || resizable == CKEDITOR.DIALOG_RESIZE_BOTH ) ) - width = Math.max( def.minWidth || 0, internalWidth - wrapperWidth ); - - if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT || resizable == CKEDITOR.DIALOG_RESIZE_BOTH ) - height = Math.max( def.minHeight || 0, internalHeight - wrapperHeight ); - - dialog.resize( width, height ); - - if ( !dialog._.moved ) - dialog.layout(); - - evt.data.preventDefault(); - } - - function mouseUpHandler() { - CKEDITOR.document.removeListener( 'mouseup', mouseUpHandler ); - CKEDITOR.document.removeListener( 'mousemove', mouseMoveHandler ); - - if ( dialogCover ) { - dialogCover.remove(); - dialogCover = null; - } - - if ( CKEDITOR.env.ie6Compat ) { - var coverDoc = currentCover.getChild( 0 ).getFrameDocument(); - coverDoc.removeListener( 'mouseup', mouseUpHandler ); - coverDoc.removeListener( 'mousemove', mouseMoveHandler ); - } - } - } - - var resizeCover; - // Caching resuable covers and allowing only one cover - // on screen. - var covers = {}, - currentCover; - - function cancelEvent( ev ) { - ev.data.preventDefault( 1 ); - } - - function showCover( editor ) { - var win = CKEDITOR.document.getWindow(); - var config = editor.config, - backgroundColorStyle = config.dialog_backgroundCoverColor || 'white', - backgroundCoverOpacity = config.dialog_backgroundCoverOpacity, - baseFloatZIndex = config.baseFloatZIndex, - coverKey = CKEDITOR.tools.genKey( backgroundColorStyle, backgroundCoverOpacity, baseFloatZIndex ), - coverElement = covers[ coverKey ]; - - if ( !coverElement ) { - var html = [ - '<div tabIndex="-1" style="position: ', ( CKEDITOR.env.ie6Compat ? 'absolute' : 'fixed' ), - '; z-index: ', baseFloatZIndex, - '; top: 0px; left: 0px; ', - ( !CKEDITOR.env.ie6Compat ? 'background-color: ' + backgroundColorStyle : '' ), - '" class="cke_dialog_background_cover">' - ]; - - if ( CKEDITOR.env.ie6Compat ) { - // Support for custom document.domain in IE. - var iframeHtml = '<html><body style=\\\'background-color:' + backgroundColorStyle + ';\\\'></body></html>'; - - html.push( '<iframe' + - ' hidefocus="true"' + - ' frameborder="0"' + - ' id="cke_dialog_background_iframe"' + - ' src="javascript:' ); - - html.push( 'void((function(){' + encodeURIComponent( - 'document.open();' + - // Support for custom document.domain in IE. - '(' + CKEDITOR.tools.fixDomain + ')();' + - 'document.write( \'' + iframeHtml + '\' );' + - 'document.close();' - ) + '})())' ); - - html.push( '"' + - ' style="' + - 'position:absolute;' + - 'left:0;' + - 'top:0;' + - 'width:100%;' + - 'height: 100%;' + - 'filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0)">' + - '</iframe>' ); - } - - html.push( '</div>' ); - - coverElement = CKEDITOR.dom.element.createFromHtml( html.join( '' ) ); - coverElement.setOpacity( backgroundCoverOpacity != undefined ? backgroundCoverOpacity : 0.5 ); - - coverElement.on( 'keydown', cancelEvent ); - coverElement.on( 'keypress', cancelEvent ); - coverElement.on( 'keyup', cancelEvent ); - - coverElement.appendTo( CKEDITOR.document.getBody() ); - covers[ coverKey ] = coverElement; - } else - coverElement.show(); - - // Makes the dialog cover a focus holder as well. - editor.focusManager.add( coverElement ); - - currentCover = coverElement; - var resizeFunc = function() { - var size = win.getViewPaneSize(); - coverElement.setStyles({ - width: size.width + 'px', - height: size.height + 'px' - }); - }; - - var scrollFunc = function() { - var pos = win.getScrollPosition(), - cursor = CKEDITOR.dialog._.currentTop; - coverElement.setStyles({ - left: pos.x + 'px', - top: pos.y + 'px' - }); - - if ( cursor ) { - do { - var dialogPos = cursor.getPosition(); - cursor.move( dialogPos.x, dialogPos.y ); - } while ( ( cursor = cursor._.parentDialog ) ); - } - }; - - resizeCover = resizeFunc; - win.on( 'resize', resizeFunc ); - resizeFunc(); - // Using Safari/Mac, focus must be kept where it is (#7027) - if ( !( CKEDITOR.env.mac && CKEDITOR.env.webkit ) ) - coverElement.focus(); - - if ( CKEDITOR.env.ie6Compat ) { - // IE BUG: win.$.onscroll assignment doesn't work.. it must be window.onscroll. - // So we need to invent a really funny way to make it work. - var myScrollHandler = function() { - scrollFunc(); - arguments.callee.prevScrollHandler.apply( this, arguments ); - }; - win.$.setTimeout( function() { - myScrollHandler.prevScrollHandler = window.onscroll || - function() {}; - window.onscroll = myScrollHandler; - }, 0 ); - scrollFunc(); - } - } - - function hideCover( editor ) { - if ( !currentCover ) - return; - - editor.focusManager.remove( currentCover ); - var win = CKEDITOR.document.getWindow(); - currentCover.hide(); - win.removeListener( 'resize', resizeCover ); - - if ( CKEDITOR.env.ie6Compat ) { - win.$.setTimeout( function() { - var prevScrollHandler = window.onscroll && window.onscroll.prevScrollHandler; - window.onscroll = prevScrollHandler || null; - }, 0 ); - } - resizeCover = null; - } - - function removeCovers() { - for ( var coverId in covers ) - covers[ coverId ].remove(); - covers = {}; - } - - var accessKeyProcessors = {}; - - var accessKeyDownHandler = function( evt ) { - var ctrl = evt.data.$.ctrlKey || evt.data.$.metaKey, - alt = evt.data.$.altKey, - shift = evt.data.$.shiftKey, - key = String.fromCharCode( evt.data.$.keyCode ), - keyProcessor = accessKeyProcessors[ ( ctrl ? 'CTRL+' : '' ) + ( alt ? 'ALT+' : '' ) + ( shift ? 'SHIFT+' : '' ) + key ]; - - if ( !keyProcessor || !keyProcessor.length ) - return; - - keyProcessor = keyProcessor[ keyProcessor.length - 1 ]; - keyProcessor.keydown && keyProcessor.keydown.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key ); - evt.data.preventDefault(); - }; - - var accessKeyUpHandler = function( evt ) { - var ctrl = evt.data.$.ctrlKey || evt.data.$.metaKey, - alt = evt.data.$.altKey, - shift = evt.data.$.shiftKey, - key = String.fromCharCode( evt.data.$.keyCode ), - keyProcessor = accessKeyProcessors[ ( ctrl ? 'CTRL+' : '' ) + ( alt ? 'ALT+' : '' ) + ( shift ? 'SHIFT+' : '' ) + key ]; - - if ( !keyProcessor || !keyProcessor.length ) - return; - - keyProcessor = keyProcessor[ keyProcessor.length - 1 ]; - if ( keyProcessor.keyup ) { - keyProcessor.keyup.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key ); - evt.data.preventDefault(); - } - }; - - var registerAccessKey = function( uiElement, dialog, key, downFunc, upFunc ) { - var procList = accessKeyProcessors[ key ] || ( accessKeyProcessors[ key ] = [] ); - procList.push({ - uiElement: uiElement, - dialog: dialog, - key: key, - keyup: upFunc || uiElement.accessKeyUp, - keydown: downFunc || uiElement.accessKeyDown - }); - }; - - var unregisterAccessKey = function( obj ) { - for ( var i in accessKeyProcessors ) { - var list = accessKeyProcessors[ i ]; - for ( var j = list.length - 1; j >= 0; j-- ) { - if ( list[ j ].dialog == obj || list[ j ].uiElement == obj ) - list.splice( j, 1 ); - } - if ( list.length === 0 ) - delete accessKeyProcessors[ i ]; - } - }; - - var tabAccessKeyUp = function( dialog, key ) { - if ( dialog._.accessKeyMap[ key ] ) - dialog.selectPage( dialog._.accessKeyMap[ key ] ); - }; - - var tabAccessKeyDown = function( dialog, key ) {}; - - (function() { - CKEDITOR.ui.dialog = { - /** - * The base class of all dialog UI elements. - * - * @class CKEDITOR.ui.dialog.uiElement - * @constructor Creates a uiElement class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition Element - * definition. - * - * Accepted fields: - * - * * `id` (Required) The id of the UI element. See {@link CKEDITOR.dialog#getContentElement}. - * * `type` (Required) The type of the UI element. The - * value to this field specifies which UI element class will be used to - * generate the final widget. - * * `title` (Optional) The popup tooltip for the UI - * element. - * * `hidden` (Optional) A flag that tells if the element - * should be initially visible. - * * `className` (Optional) Additional CSS class names - * to add to the UI element. Separated by space. - * * `style` (Optional) Additional CSS inline styles - * to add to the UI element. A semicolon (;) is required after the last - * style declaration. - * * `accessKey` (Optional) The alphanumeric access key - * for this element. Access keys are automatically prefixed by CTRL. - * * `on*` (Optional) Any UI element definition field that - * starts with `on` followed immediately by a capital letter and - * probably more letters is an event handler. Event handlers may be further - * divided into registered event handlers and DOM event handlers. Please - * refer to {@link CKEDITOR.ui.dialog.uiElement#registerEvents} and - * {@link CKEDITOR.ui.dialog.uiElement#eventProcessors} for more information. - * - * @param {Array} htmlList - * List of HTML code to be added to the dialog's content area. - * @param {Function/String} [nodeNameArg='div'] - * A function returning a string, or a simple string for the node name for - * the root DOM node. - * @param {Function/Object} [stylesArg={}] - * A function returning an object, or a simple object for CSS styles applied - * to the DOM node. - * @param {Function/Object} [attributesArg={}] - * A fucntion returning an object, or a simple object for attributes applied - * to the DOM node. - * @param {Function/String} [contentsArg=''] - * A function returning a string, or a simple string for the HTML code inside - * the root DOM node. Default is empty string. - */ - uiElement: function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg ) { - if ( arguments.length < 4 ) - return; - - var nodeName = ( nodeNameArg.call ? nodeNameArg( elementDefinition ) : nodeNameArg ) || 'div', - html = [ '<', nodeName, ' ' ], - styles = ( stylesArg && stylesArg.call ? stylesArg( elementDefinition ) : stylesArg ) || {}, - attributes = ( attributesArg && attributesArg.call ? attributesArg( elementDefinition ) : attributesArg ) || {}, - innerHTML = ( contentsArg && contentsArg.call ? contentsArg.call( this, dialog, elementDefinition ) : contentsArg ) || '', - domId = this.domId = attributes.id || CKEDITOR.tools.getNextId() + '_uiElement', - id = this.id = elementDefinition.id, - i; - - if ( elementDefinition.requiredContent && !dialog.getParentEditor().filter.check( elementDefinition.requiredContent ) ) { - styles.display = 'none'; - this.notAllowed = true; - } - - // Set the id, a unique id is required for getElement() to work. - attributes.id = domId; - - // Set the type and definition CSS class names. - var classes = {}; - if ( elementDefinition.type ) - classes[ 'cke_dialog_ui_' + elementDefinition.type ] = 1; - if ( elementDefinition.className ) - classes[ elementDefinition.className ] = 1; - if ( elementDefinition.disabled ) - classes[ 'cke_disabled' ] = 1; - - var attributeClasses = ( attributes[ 'class' ] && attributes[ 'class' ].split ) ? attributes[ 'class' ].split( ' ' ) : []; - for ( i = 0; i < attributeClasses.length; i++ ) { - if ( attributeClasses[ i ] ) - classes[ attributeClasses[ i ] ] = 1; - } - var finalClasses = []; - for ( i in classes ) - finalClasses.push( i ); - attributes[ 'class' ] = finalClasses.join( ' ' ); - - // Set the popup tooltop. - if ( elementDefinition.title ) - attributes.title = elementDefinition.title; - - // Write the inline CSS styles. - var styleStr = ( elementDefinition.style || '' ).split( ';' ); - - // Element alignment support. - if ( elementDefinition.align ) { - var align = elementDefinition.align; - styles[ 'margin-left' ] = align == 'left' ? 0 : 'auto'; - styles[ 'margin-right' ] = align == 'right' ? 0 : 'auto'; - } - - for ( i in styles ) - styleStr.push( i + ':' + styles[ i ] ); - if ( elementDefinition.hidden ) - styleStr.push( 'display:none' ); - for ( i = styleStr.length - 1; i >= 0; i-- ) { - if ( styleStr[ i ] === '' ) - styleStr.splice( i, 1 ); - } - if ( styleStr.length > 0 ) - attributes.style = ( attributes.style ? ( attributes.style + '; ' ) : '' ) + styleStr.join( '; ' ); - - // Write the attributes. - for ( i in attributes ) - html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[ i ] ) + '" ' ); - - // Write the content HTML. - html.push( '>', innerHTML, '</', nodeName, '>' ); - - // Add contents to the parent HTML array. - htmlList.push( html.join( '' ) ); - - ( this._ || ( this._ = {} ) ).dialog = dialog; - - // Override isChanged if it is defined in element definition. - if ( typeof( elementDefinition.isChanged ) == 'boolean' ) - this.isChanged = function() { - return elementDefinition.isChanged; - }; - if ( typeof( elementDefinition.isChanged ) == 'function' ) - this.isChanged = elementDefinition.isChanged; - - // Overload 'get(set)Value' on definition. - if ( typeof( elementDefinition.setValue ) == 'function' ) { - this.setValue = CKEDITOR.tools.override( this.setValue, function( org ) { - return function( val ) { - org.call( this, elementDefinition.setValue.call( this, val ) ); - }; - }); - } - - if ( typeof( elementDefinition.getValue ) == 'function' ) { - this.getValue = CKEDITOR.tools.override( this.getValue, function( org ) { - return function() { - return elementDefinition.getValue.call( this, org.call( this ) ); - }; - }); - } - - // Add events. - CKEDITOR.event.implementOn( this ); - - this.registerEvents( elementDefinition ); - if ( this.accessKeyUp && this.accessKeyDown && elementDefinition.accessKey ) - registerAccessKey( this, dialog, 'CTRL+' + elementDefinition.accessKey ); - - var me = this; - dialog.on( 'load', function() { - var input = me.getInputElement(); - if ( input ) { - var focusClass = me.type in { 'checkbox':1,'ratio':1 } && CKEDITOR.env.ie && CKEDITOR.env.version < 8 ? 'cke_dialog_ui_focused' : ''; - input.on( 'focus', function() { - dialog._.tabBarMode = false; - dialog._.hasFocus = true; - me.fire( 'focus' ); - focusClass && this.addClass( focusClass ); - - }); - - input.on( 'blur', function() { - me.fire( 'blur' ); - focusClass && this.removeClass( focusClass ); - }); - } - }); - - // Register the object as a tab focus if it can be included. - if ( this.keyboardFocusable ) { - this.tabIndex = elementDefinition.tabIndex || 0; - - this.focusIndex = dialog._.focusList.push( this ) - 1; - this.on( 'focus', function() { - dialog._.currentFocusIndex = me.focusIndex; - }); - } - - // Completes this object with everything we have in the - // definition. - CKEDITOR.tools.extend( this, elementDefinition ); - }, - - /** - * Horizontal layout box for dialog UI elements, auto-expends to available width of container. - * - * @class CKEDITOR.ui.dialog.hbox - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a hbox class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {Array} childObjList - * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container. - * @param {Array} childHtmlList - * Array of HTML code that correspond to the HTML output of all the - * objects in childObjList. - * @param {Array} htmlList - * Array of HTML code that this element will output to. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `widths` (Optional) The widths of child cells. - * * `height` (Optional) The height of the layout. - * * `padding` (Optional) The padding width inside child cells. - * * `align` (Optional) The alignment of the whole layout. - */ - hbox: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) { - if ( arguments.length < 4 ) - return; - - this._ || ( this._ = {} ); - - var children = this._.children = childObjList, - widths = elementDefinition && elementDefinition.widths || null, - height = elementDefinition && elementDefinition.height || null, - styles = {}, - i; - /** @ignore */ - var innerHTML = function() { - var html = [ '<tbody><tr class="cke_dialog_ui_hbox">' ]; - for ( i = 0; i < childHtmlList.length; i++ ) { - var className = 'cke_dialog_ui_hbox_child', - styles = []; - if ( i === 0 ) - className = 'cke_dialog_ui_hbox_first'; - if ( i == childHtmlList.length - 1 ) - className = 'cke_dialog_ui_hbox_last'; - html.push( '<td class="', className, '" role="presentation" ' ); - if ( widths ) { - if ( widths[ i ] ) - styles.push( 'width:' + cssLength( widths[ i ] ) ); - } else - styles.push( 'width:' + Math.floor( 100 / childHtmlList.length ) + '%' ); - if ( height ) - styles.push( 'height:' + cssLength( height ) ); - if ( elementDefinition && elementDefinition.padding != undefined ) - styles.push( 'padding:' + cssLength( elementDefinition.padding ) ); - // In IE Quirks alignment has to be done on table cells. (#7324) - if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align ) - styles.push( 'text-align:' + children[ i ].align ); - if ( styles.length > 0 ) - html.push( 'style="' + styles.join( '; ' ) + '" ' ); - html.push( '>', childHtmlList[ i ], '</td>' ); - } - html.push( '</tr></tbody>' ); - return html.join( '' ); - }; - - var attribs = { role: 'presentation' }; - elementDefinition && elementDefinition.align && ( attribs.align = elementDefinition.align ); - - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'hbox' }, htmlList, 'table', styles, attribs, innerHTML ); - }, - - /** - * Vertical layout box for dialog UI elements. - * - * @class CKEDITOR.ui.dialog.vbox - * @extends CKEDITOR.ui.dialog.hbox - * @constructor Creates a vbox class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {Array} childObjList - * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container. - * @param {Array} childHtmlList - * Array of HTML code that correspond to the HTML output of all the - * objects in childObjList. - * @param {Array} htmlList Array of HTML code that this element will output to. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `width` (Optional) The width of the layout. - * * `heights` (Optional) The heights of individual cells. - * * `align` (Optional) The alignment of the layout. - * * `padding` (Optional) The padding width inside child cells. - * * `expand` (Optional) Whether the layout should expand - * vertically to fill its container. - */ - vbox: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) { - if ( arguments.length < 3 ) - return; - - this._ || ( this._ = {} ); - - var children = this._.children = childObjList, - width = elementDefinition && elementDefinition.width || null, - heights = elementDefinition && elementDefinition.heights || null; - /** @ignore */ - var innerHTML = function() { - var html = [ '<table role="presentation" cellspacing="0" border="0" ' ]; - html.push( 'style="' ); - if ( elementDefinition && elementDefinition.expand ) - html.push( 'height:100%;' ); - html.push( 'width:' + cssLength( width || '100%' ), ';' ); - - // (#10123) Temp fix for dialog broken layout in latest webkit. - if ( CKEDITOR.env.webkit ) - html.push( 'float:none;' ); - - html.push( '"' ); - html.push( 'align="', CKEDITOR.tools.htmlEncode( - ( elementDefinition && elementDefinition.align ) || ( dialog.getParentEditor().lang.dir == 'ltr' ? 'left' : 'right' ) ), '" ' ); - - html.push( '><tbody>' ); - for ( var i = 0; i < childHtmlList.length; i++ ) { - var styles = []; - html.push( '<tr><td role="presentation" ' ); - if ( width ) - styles.push( 'width:' + cssLength( width || '100%' ) ); - if ( heights ) - styles.push( 'height:' + cssLength( heights[ i ] ) ); - else if ( elementDefinition && elementDefinition.expand ) - styles.push( 'height:' + Math.floor( 100 / childHtmlList.length ) + '%' ); - if ( elementDefinition && elementDefinition.padding != undefined ) - styles.push( 'padding:' + cssLength( elementDefinition.padding ) ); - // In IE Quirks alignment has to be done on table cells. (#7324) - if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align ) - styles.push( 'text-align:' + children[ i ].align ); - if ( styles.length > 0 ) - html.push( 'style="', styles.join( '; ' ), '" ' ); - html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[ i ], '</td></tr>' ); - } - html.push( '</tbody></table>' ); - return html.join( '' ); - }; - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'vbox' }, htmlList, 'div', null, { role: 'presentation' }, innerHTML ); - } - }; - })(); - - /** @class CKEDITOR.ui.dialog.uiElement */ - CKEDITOR.ui.dialog.uiElement.prototype = { - /** - * Gets the root DOM element of this dialog UI object. - * - * uiElement.getElement().hide(); - * - * @returns {CKEDITOR.dom.element} Root DOM element of UI object. - */ - getElement: function() { - return CKEDITOR.document.getById( this.domId ); - }, - - /** - * Gets the DOM element that the user inputs values. - * - * This function is used by {@link #setValue}, {@link #getValue} and {@link #focus}. It should - * be overrided in child classes where the input element isn't the root - * element. - * - * var rawValue = textInput.getInputElement().$.value; - * - * @returns {CKEDITOR.dom.element} The element where the user input values. - */ - getInputElement: function() { - return this.getElement(); - }, - - /** - * Gets the parent dialog object containing this UI element. - * - * var dialog = uiElement.getDialog(); - * - * @returns {CKEDITOR.dialog} Parent dialog object. - */ - getDialog: function() { - return this._.dialog; - }, - - /** - * Sets the value of this dialog UI object. - * - * uiElement.setValue( 'Dingo' ); - * - * @chainable - * @param {Object} value The new value. - * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element. - */ - setValue: function( value, noChangeEvent ) { - this.getInputElement().setValue( value ); - !noChangeEvent && this.fire( 'change', { value: value } ); - return this; - }, - - /** - * Gets the current value of this dialog UI object. - * - * var myValue = uiElement.getValue(); - * - * @returns {Object} The current value. - */ - getValue: function() { - return this.getInputElement().getValue(); - }, - - /** - * Tells whether the UI object's value has changed. - * - * if ( uiElement.isChanged() ) - * confirm( 'Value changed! Continue?' ); - * - * @returns {Boolean} `true` if changed, `false` if not changed. - */ - isChanged: function() { - // Override in input classes. - return false; - }, - - /** - * Selects the parent tab of this element. Usually called by focus() or overridden focus() methods. - * - * focus : function() { - * this.selectParentTab(); - * // do something else. - * } - * - * @chainable - */ - selectParentTab: function() { - var element = this.getInputElement(), - cursor = element, - tabId; - while ( ( cursor = cursor.getParent() ) && cursor.$.className.search( 'cke_dialog_page_contents' ) == -1 ) { - /*jsl:pass*/ - } - - // Some widgets don't have parent tabs (e.g. OK and Cancel buttons). - if ( !cursor ) - return this; - - tabId = cursor.getAttribute( 'name' ); - // Avoid duplicate select. - if ( this._.dialog._.currentTabId != tabId ) - this._.dialog.selectPage( tabId ); - return this; - }, - - /** - * Puts the focus to the UI object. Switches tabs if the UI object isn't in the active tab page. - * - * uiElement.focus(); - * - * @chainable - */ - focus: function() { - this.selectParentTab().getInputElement().focus(); - return this; - }, - - /** - * Registers the `on*` event handlers defined in the element definition. - * - * The default behavior of this function is: - * - * 1. If the on* event is defined in the class's eventProcesors list, - * then the registration is delegated to the corresponding function - * in the eventProcessors list. - * 2. If the on* event is not defined in the eventProcessors list, then - * register the event handler under the corresponding DOM event of - * the UI element's input DOM element (as defined by the return value - * of {@link #getInputElement}). - * - * This function is only called at UI element instantiation, but can - * be overridded in child classes if they require more flexibility. - * - * @chainable - * @param {CKEDITOR.dialog.definition.uiElement} definition The UI element - * definition. - */ - registerEvents: function( definition ) { - var regex = /^on([A-Z]\w+)/, - match; - - var registerDomEvent = function( uiElement, dialog, eventName, func ) { - dialog.on( 'load', function() { - uiElement.getInputElement().on( eventName, func, uiElement ); - }); - }; - - for ( var i in definition ) { - if ( !( match = i.match( regex ) ) ) - continue; - if ( this.eventProcessors[ i ] ) - this.eventProcessors[ i ].call( this, this._.dialog, definition[ i ] ); - else - registerDomEvent( this, this._.dialog, match[ 1 ].toLowerCase(), definition[ i ] ); - } - - return this; - }, - - /** - * The event processor list used by - * {@link CKEDITOR.ui.dialog.uiElement#getInputElement} at UI element - * instantiation. The default list defines three `on*` events: - * - * 1. `onLoad` - Called when the element's parent dialog opens for the - * first time. - * 2. `onShow` - Called whenever the element's parent dialog opens. - * 3. `onHide` - Called whenever the element's parent dialog closes. - * - * // This connects the 'click' event in CKEDITOR.ui.dialog.button to onClick - * // handlers in the UI element's definitions. - * CKEDITOR.ui.dialog.button.eventProcessors = CKEDITOR.tools.extend( {}, - * CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, - * { onClick : function( dialog, func ) { this.on( 'click', func ); } }, - * true - * ); - * - * @property {Object} - */ - eventProcessors: { - onLoad: function( dialog, func ) { - dialog.on( 'load', func, this ); - }, - - onShow: function( dialog, func ) { - dialog.on( 'show', func, this ); - }, - - onHide: function( dialog, func ) { - dialog.on( 'hide', func, this ); - } - }, - - /** - * The default handler for a UI element's access key down event, which - * tries to put focus to the UI element. - * - * Can be overridded in child classes for more sophisticaed behavior. - * - * @param {CKEDITOR.dialog} dialog The parent dialog object. - * @param {String} key The key combination pressed. Since access keys - * are defined to always include the `CTRL` key, its value should always - * include a `'CTRL+'` prefix. - */ - accessKeyDown: function( dialog, key ) { - this.focus(); - }, - - /** - * The default handler for a UI element's access key up event, which - * does nothing. - * - * Can be overridded in child classes for more sophisticated behavior. - * - * @param {CKEDITOR.dialog} dialog The parent dialog object. - * @param {String} key The key combination pressed. Since access keys - * are defined to always include the `CTRL` key, its value should always - * include a `'CTRL+'` prefix. - */ - accessKeyUp: function( dialog, key ) {}, - - /** - * Disables a UI element. - */ - disable: function() { - var element = this.getElement(), - input = this.getInputElement(); - input.setAttribute( 'disabled', 'true' ); - element.addClass( 'cke_disabled' ); - }, - - /** - * Enables a UI element. - */ - enable: function() { - var element = this.getElement(), - input = this.getInputElement(); - input.removeAttribute( 'disabled' ); - element.removeClass( 'cke_disabled' ); - }, - - /** - * Determines whether an UI element is enabled or not. - * - * @returns {Boolean} Whether the UI element is enabled. - */ - isEnabled: function() { - return !this.getElement().hasClass( 'cke_disabled' ); - }, - - /** - * Determines whether an UI element is visible or not. - * - * @returns {Boolean} Whether the UI element is visible. - */ - isVisible: function() { - return this.getInputElement().isVisible(); - }, - - /** - * Determines whether an UI element is focus-able or not. - * Focus-able is defined as being both visible and enabled. - * - * @returns {Boolean} Whether the UI element can be focused. - */ - isFocusable: function() { - if ( !this.isEnabled() || !this.isVisible() ) - return false; - return true; - } - }; - - /** @class CKEDITOR.ui.dialog.hbox */ - CKEDITOR.ui.dialog.hbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, { - /** - * Gets a child UI element inside this container. - * - * var checkbox = hbox.getChild( [0,1] ); - * checkbox.setValue( true ); - * - * @param {Array/Number} indices An array or a single number to indicate the child's - * position in the container's descendant tree. Omit to get all the children in an array. - * @returns {Array/CKEDITOR.ui.dialog.uiElement} Array of all UI elements in the container - * if no argument given, or the specified UI element if indices is given. - */ - getChild: function( indices ) { - // If no arguments, return a clone of the children array. - if ( arguments.length < 1 ) - return this._.children.concat(); - - // If indices isn't array, make it one. - if ( !indices.splice ) - indices = [ indices ]; - - // Retrieve the child element according to tree position. - if ( indices.length < 2 ) - return this._.children[ indices[ 0 ] ]; - else - return ( this._.children[ indices[ 0 ] ] && this._.children[ indices[ 0 ] ].getChild ) ? this._.children[ indices[ 0 ] ].getChild( indices.slice( 1, indices.length ) ) : null; - } - }, true ); - - CKEDITOR.ui.dialog.vbox.prototype = new CKEDITOR.ui.dialog.hbox(); - - (function() { - var commonBuilder = { - build: function( dialog, elementDefinition, output ) { - var children = elementDefinition.children, - child, - childHtmlList = [], - childObjList = []; - for ( var i = 0; - ( i < children.length && ( child = children[ i ] ) ); i++ ) { - var childHtml = []; - childHtmlList.push( childHtml ); - childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) ); - } - return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition ); - } - }; - - CKEDITOR.dialog.addUIElement( 'hbox', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'vbox', commonBuilder ); - })(); - - /** - * Generic dialog command. It opens a specific dialog when executed. - * - * // Register the "link" command, which opens the "link" dialog. - * editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) ); - * - * @class - * @constructor Creates a dialogCommand class instance. - * @extends CKEDITOR.commandDefinition - * @param {String} dialogName The name of the dialog to open when executing - * this command. - * @param {Object} [ext] Additional command definition's properties. - */ - CKEDITOR.dialogCommand = function( dialogName, ext ) { - this.dialogName = dialogName; - CKEDITOR.tools.extend( this, ext, true ); - }; - - CKEDITOR.dialogCommand.prototype = { - exec: function( editor ) { - // Special treatment for Opera. (#8031) - CKEDITOR.env.opera ? CKEDITOR.tools.setTimeout( function() { - editor.openDialog( this.dialogName ); - }, 0, this ) : editor.openDialog( this.dialogName ); - }, - - // Dialog commands just open a dialog ui, thus require no undo logic, - // undo support should dedicate to specific dialog implementation. - canUndo: false, - - editorFocus: 1 - }; - - (function() { - var notEmptyRegex = /^([a]|[^a])+$/, - integerRegex = /^\d*$/, - numberRegex = /^\d*(?:\.\d+)?$/, - htmlLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|\%)?)?$/, - cssLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|em|ex|in|cm|mm|pt|pc|\%)?)?$/i, - inlineStyleRegex = /^(\s*[\w-]+\s*:\s*[^:;]+(?:;|$))*$/; - - CKEDITOR.VALIDATE_OR = 1; - CKEDITOR.VALIDATE_AND = 2; - - CKEDITOR.dialog.validate = { - functions: function() { - var args = arguments; - return function() { - /** - * It's important for validate functions to be able to accept the value - * as argument in addition to this.getValue(), so that it is possible to - * combine validate functions together to make more sophisticated - * validators. - */ - var value = this && this.getValue ? this.getValue() : args[ 0 ]; - - var msg = undefined, - relation = CKEDITOR.VALIDATE_AND, - functions = [], - i; - - for ( i = 0; i < args.length; i++ ) { - if ( typeof( args[ i ] ) == 'function' ) - functions.push( args[ i ] ); - else - break; - } - - if ( i < args.length && typeof( args[ i ] ) == 'string' ) { - msg = args[ i ]; - i++; - } - - if ( i < args.length && typeof( args[ i ] ) == 'number' ) - relation = args[ i ]; - - var passed = ( relation == CKEDITOR.VALIDATE_AND ? true : false ); - for ( i = 0; i < functions.length; i++ ) { - if ( relation == CKEDITOR.VALIDATE_AND ) - passed = passed && functions[ i ]( value ); - else - passed = passed || functions[ i ]( value ); - } - - return !passed ? msg : true; - }; - }, - - regex: function( regex, msg ) { - /* - * Can be greatly shortened by deriving from functions validator if code size - * turns out to be more important than performance. - */ - return function() { - var value = this && this.getValue ? this.getValue() : arguments[ 0 ]; - return !regex.test( value ) ? msg : true; - }; - }, - - notEmpty: function( msg ) { - return this.regex( notEmptyRegex, msg ); - }, - - integer: function( msg ) { - return this.regex( integerRegex, msg ); - }, - - 'number': function( msg ) { - return this.regex( numberRegex, msg ); - }, - - 'cssLength': function( msg ) { - return this.functions( function( val ) { - return cssLengthRegex.test( CKEDITOR.tools.trim( val ) ); - }, msg ); - }, - - 'htmlLength': function( msg ) { - return this.functions( function( val ) { - return htmlLengthRegex.test( CKEDITOR.tools.trim( val ) ); - }, msg ); - }, - - 'inlineStyle': function( msg ) { - return this.functions( function( val ) { - return inlineStyleRegex.test( CKEDITOR.tools.trim( val ) ); - }, msg ); - }, - - equals: function( value, msg ) { - return this.functions( function( val ) { - return val == value; - }, msg ); - }, - - notEqual: function( value, msg ) { - return this.functions( function( val ) { - return val != value; - }, msg ); - } - }; - - CKEDITOR.on( 'instanceDestroyed', function( evt ) { - // Remove dialog cover on last instance destroy. - if ( CKEDITOR.tools.isEmpty( CKEDITOR.instances ) ) { - var currentTopDialog; - while ( ( currentTopDialog = CKEDITOR.dialog._.currentTop ) ) - currentTopDialog.hide(); - removeCovers(); - } - - var dialogs = evt.editor._.storedDialogs; - for ( var name in dialogs ) - dialogs[ name ].destroy(); - - }); - - })(); - - // Extend the CKEDITOR.editor class with dialog specific functions. - CKEDITOR.tools.extend( CKEDITOR.editor.prototype, { - /** - * Loads and opens a registered dialog. - * - * CKEDITOR.instances.editor1.openDialog( 'smiley' ); - * - * @member CKEDITOR.editor - * @param {String} dialogName The registered name of the dialog. - * @param {Function} callback The function to be invoked after dialog instance created. - * @returns {CKEDITOR.dialog} The dialog object corresponding to the dialog displayed. - * `null` if the dialog name is not registered. - * @see CKEDITOR.dialog#add - */ - openDialog: function( dialogName, callback ) { - var dialog = null, dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ]; - - if ( CKEDITOR.dialog._.currentTop === null ) - showCover( this ); - - // If the dialogDefinition is already loaded, open it immediately. - if ( typeof dialogDefinitions == 'function' ) { - var storedDialogs = this._.storedDialogs || ( this._.storedDialogs = {} ); - - dialog = storedDialogs[ dialogName ] || ( storedDialogs[ dialogName ] = new CKEDITOR.dialog( this, dialogName ) ); - - callback && callback.call( dialog, dialog ); - dialog.show(); - - } else if ( dialogDefinitions == 'failed' ) { - hideCover( this ); - throw new Error( '[CKEDITOR.dialog.openDialog] Dialog "' + dialogName + '" failed when loading definition.' ); - } else if ( typeof dialogDefinitions == 'string' ) { - - CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( dialogDefinitions ), - function() { - var dialogDefinition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ]; - // In case of plugin error, mark it as loading failed. - if ( typeof dialogDefinition != 'function' ) - CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed'; - - this.openDialog( dialogName, callback ); - }, this, 0, 1 ); - } - - CKEDITOR.skin.loadPart( 'dialog' ); - - return dialog; - } - }); -})(); - -CKEDITOR.plugins.add( 'dialog', { - requires: 'dialogui', - init: function( editor ) { - editor.on( 'doubleclick', function( evt ) { - if ( evt.data.dialog ) - editor.openDialog( evt.data.dialog ); - }, null, null, 999 ); - } -}); - -// Dialog related configurations. - -/** - * The color of the dialog background cover. It should be a valid CSS color string. - * - * config.dialog_backgroundCoverColor = 'rgb(255, 254, 253)'; - * - * @cfg {String} [dialog_backgroundCoverColor='white'] - * @member CKEDITOR.config - */ - -/** - * The opacity of the dialog background cover. It should be a number within the - * range `[0.0, 1.0]`. - * - * config.dialog_backgroundCoverOpacity = 0.7; - * - * @cfg {Number} [dialog_backgroundCoverOpacity=0.5] - * @member CKEDITOR.config - */ - -/** - * If the dialog has more than one tab, put focus into the first tab as soon as dialog is opened. - * - * config.dialog_startupFocusTab = true; - * - * @cfg {Boolean} [dialog_startupFocusTab=false] - * @member CKEDITOR.config - */ - -/** - * The distance of magnetic borders used in moving and resizing dialogs, - * measured in pixels. - * - * config.dialog_magnetDistance = 30; - * - * @cfg {Number} [dialog_magnetDistance=20] - * @member CKEDITOR.config - */ - -/** - * The guideline to follow when generating the dialog buttons. There are 3 possible options: - * - * * `'OS'` - the buttons will be displayed in the default order of the user's OS; - * * `'ltr'` - for Left-To-Right order; - * * `'rtl'` - for Right-To-Left order. - * - * Example: - * - * config.dialog_buttonsOrder = 'rtl'; - * - * @since 3.5 - * @cfg {String} [dialog_buttonsOrder='OS'] - * @member CKEDITOR.config - */ - -/** - * The dialog contents to removed. It's a string composed by dialog name and tab name with a colon between them. - * - * Separate each pair with semicolon (see example). - * - * **Note:** All names are case-sensitive. - * - * **Note:** Be cautious when specifying dialog tabs that are mandatory, - * like `'info'`, dialog functionality might be broken because of this! - * - * config.removeDialogTabs = 'flash:advanced;image:Link'; - * - * @since 3.5 - * @cfg {String} [removeDialogTabs=''] - * @member CKEDITOR.config - */ - -/** - * Fired when a dialog definition is about to be used to create a dialog into - * an editor instance. This event makes it possible to customize the definition - * before creating it. - * - * Note that this event is called only the first time a specific dialog is - * opened. Successive openings will use the cached dialog, and this event will - * not get fired. - * - * @event dialogDefinition - * @member CKEDITOR - * @param {CKEDITOR.dialog.definition} data The dialog defination that - * is being loaded. - * @param {CKEDITOR.editor} editor The editor instance that will use the dialog. - */ - -/** - * Fired when a tab is going to be selected in a dialog. - * - * @event selectPage - * @member CKEDITOR.dialog - * @param data - * @param {String} data.page The id of the page that it's gonna be selected. - * @param {String} data.currentPage The id of the current page. - */ - -/** - * Fired when the user tries to dismiss a dialog. - * - * @event cancel - * @member CKEDITOR.dialog - * @param data - * @param {Boolean} data.hide Whether the event should proceed or not. - */ - -/** - * Fired when the user tries to confirm a dialog. - * - * @event ok - * @member CKEDITOR.dialog - * @param data - * @param {Boolean} data.hide Whether the event should proceed or not. - */ - -/** - * Fired when a dialog is shown. - * - * @event show - * @member CKEDITOR.dialog - */ - -/** - * Fired when a dialog is shown. - * - * @event dialogShow - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {CKEDITOR.dialog} data The opened dialog instance. - */ - -/** - * Fired when a dialog is hidden. - * - * @event hide - * @member CKEDITOR.dialog - */ - -/** - * Fired when a dialog is hidden. - * - * @event dialogHide - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {CKEDITOR.dialog} data The hidden dialog instance. - */ - -/** - * Fired when a dialog is being resized. The event is fired on - * both the {@link CKEDITOR.dialog} object and the dialog instance - * since 3.5.3, previously it's available only in the global object. - * - * @static - * @event resize - * @member CKEDITOR.dialog - * @param data - * @param {CKEDITOR.dialog} data.dialog The dialog being resized (if - * it's fired on the dialog itself, this parameter isn't sent). - * @param {String} data.skin The skin name. - * @param {Number} data.width The new width. - * @param {Number} data.height The new height. - */ - -/** - * Fired when a dialog is being resized. The event is fired on - * both the {@link CKEDITOR.dialog} object and the dialog instance - * since 3.5.3, previously it's available only in the global object. - * - * @since 3.5 - * @event resize - * @member CKEDITOR.dialog - * @param data - * @param {Number} data.width The new width. - * @param {Number} data.height The new height. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/dialogadvtab/plugin.js b/addons/website/static/lib/ckeditor/plugins/dialogadvtab/plugin.js deleted file mode 100644 index 27a14d6dba6..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/dialogadvtab/plugin.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - - function setupAdvParams( element ) { - var attrName = this.att; - - var value = element && element.hasAttribute( attrName ) && element.getAttribute( attrName ) || ''; - - if ( value !== undefined ) - this.setValue( value ); - } - - function commitAdvParams() { - // Dialogs may use different parameters in the commit list, so, by - // definition, we take the first CKEDITOR.dom.element available. - var element; - - for ( var i = 0; i < arguments.length; i++ ) { - if ( arguments[ i ] instanceof CKEDITOR.dom.element ) { - element = arguments[ i ]; - break; - } - } - - if ( element ) { - var attrName = this.att, - value = this.getValue(); - - if ( value ) - element.setAttribute( attrName, value ); - else - element.removeAttribute( attrName, value ); - } - } - - var defaultTabConfig = { id:1,dir:1,classes:1,styles:1 }; - - CKEDITOR.plugins.add( 'dialogadvtab', { - requires : 'dialog', - - // Returns allowed content rule for the content created by this plugin. - allowedContent: function( tabConfig ) { - if ( !tabConfig ) - tabConfig = defaultTabConfig; - - var allowedAttrs = []; - if ( tabConfig.id ) - allowedAttrs.push( 'id' ); - if ( tabConfig.dir ) - allowedAttrs.push( 'dir' ); - - var allowed = ''; - - if ( allowedAttrs.length ) - allowed += '[' + allowedAttrs.join( ',' ) + ']'; - - if ( tabConfig.classes ) - allowed += '(*)'; - if ( tabConfig.styles ) - allowed += '{*}'; - - return allowed; - }, - - // @param tabConfig - // id, dir, classes, styles - createAdvancedTab: function( editor, tabConfig, element ) { - if ( !tabConfig ) - tabConfig = defaultTabConfig; - - var lang = editor.lang.common; - - var result = { - id: 'advanced', - label: lang.advancedTab, - title: lang.advancedTab, - elements: [ - { - type: 'vbox', - padding: 1, - children: [] - } - ] - }; - - var contents = []; - - if ( tabConfig.id || tabConfig.dir ) { - if ( tabConfig.id ) { - contents.push({ - id: 'advId', - att: 'id', - type: 'text', - requiredContent: element ? element + '[id]' : null, - label: lang.id, - setup: setupAdvParams, - commit: commitAdvParams - }); - } - - if ( tabConfig.dir ) { - contents.push({ - id: 'advLangDir', - att: 'dir', - type: 'select', - requiredContent: element ? element + '[dir]' : null, - label: lang.langDir, - 'default': '', - style: 'width:100%', - items: [ - [ lang.notSet, '' ], - [ lang.langDirLTR, 'ltr' ], - [ lang.langDirRTL, 'rtl' ] - ], - setup: setupAdvParams, - commit: commitAdvParams - }); - } - - result.elements[ 0 ].children.push({ - type: 'hbox', - widths: [ '50%', '50%' ], - children: [].concat( contents ) - }); - } - - if ( tabConfig.styles || tabConfig.classes ) { - contents = []; - - if ( tabConfig.styles ) { - contents.push({ - id: 'advStyles', - att: 'style', - type: 'text', - requiredContent: element ? element + '{cke-xyz}' : null, - label: lang.styles, - 'default': '', - - validate: CKEDITOR.dialog.validate.inlineStyle( lang.invalidInlineStyle ), - onChange: function() {}, - - getStyle: function( name, defaultValue ) { - var match = this.getValue().match( new RegExp( '(?:^|;)\\s*' + name + '\\s*:\\s*([^;]*)', 'i' ) ); - return match ? match[ 1 ] : defaultValue; - }, - - updateStyle: function( name, value ) { - var styles = this.getValue(); - - var tmp = editor.document.createElement( 'span' ); - tmp.setAttribute( 'style', styles ); - tmp.setStyle( name, value ); - styles = CKEDITOR.tools.normalizeCssText( tmp.getAttribute( 'style' ) ); - - this.setValue( styles, 1 ); - }, - - setup: setupAdvParams, - - commit: commitAdvParams - - }); - } - - if ( tabConfig.classes ) { - contents.push({ - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - id: 'advCSSClasses', - att: 'class', - type: 'text', - requiredContent: element ? element + '(cke-xyz)' : null, - label: lang.cssClasses, - 'default': '', - setup: setupAdvParams, - commit: commitAdvParams - - } - ] - }); - } - - result.elements[ 0 ].children.push({ - type: 'hbox', - widths: [ '50%', '50%' ], - children: [].concat( contents ) - }); - } - - return result; - } - }); - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/dialogui/plugin.js b/addons/website/static/lib/ckeditor/plugins/dialogui/plugin.js deleted file mode 100644 index 55f04e32fe9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/dialogui/plugin.js +++ /dev/null @@ -1,1380 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "dialogui" plugin. - */ - -CKEDITOR.plugins.add( 'dialogui', { - onLoad: function() { - - var initPrivateObject = function( elementDefinition ) { - this._ || ( this._ = {} ); - this._[ 'default' ] = this._.initValue = elementDefinition[ 'default' ] || ''; - this._.required = elementDefinition[ 'required' ] || false; - var args = [ this._ ]; - for ( var i = 1; i < arguments.length; i++ ) - args.push( arguments[ i ] ); - args.push( true ); - CKEDITOR.tools.extend.apply( CKEDITOR.tools, args ); - return this._; - }, - textBuilder = { - build: function( dialog, elementDefinition, output ) { - return new CKEDITOR.ui.dialog.textInput( dialog, elementDefinition, output ); - } - }, - commonBuilder = { - build: function( dialog, elementDefinition, output ) { - return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, elementDefinition, output ); - } - }, - containerBuilder = { - build: function( dialog, elementDefinition, output ) { - var children = elementDefinition.children, - child, - childHtmlList = [], - childObjList = []; - for ( var i = 0; - ( i < children.length && ( child = children[ i ] ) ); i++ ) { - var childHtml = []; - childHtmlList.push( childHtml ); - childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) ); - } - return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition ); - } - }, - commonPrototype = { - isChanged: function() { - return this.getValue() != this.getInitValue(); - }, - - reset: function( noChangeEvent ) { - this.setValue( this.getInitValue(), noChangeEvent ); - }, - - setInitValue: function() { - this._.initValue = this.getValue(); - }, - - resetInitValue: function() { - this._.initValue = this._[ 'default' ]; - }, - - getInitValue: function() { - return this._.initValue; - } - }, - commonEventProcessors = CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, { - onChange: function( dialog, func ) { - if ( !this._.domOnChangeRegistered ) { - dialog.on( 'load', function() { - this.getInputElement().on( 'change', function() { - // Make sure 'onchange' doesn't get fired after dialog closed. (#5719) - if ( !dialog.parts.dialog.isVisible() ) - return; - - this.fire( 'change', { value: this.getValue() } ); - }, this ); - }, this ); - this._.domOnChangeRegistered = true; - } - - this.on( 'change', func ); - } - }, true ), - eventRegex = /^on([A-Z]\w+)/, - cleanInnerDefinition = function( def ) { - // An inner UI element should not have the parent's type, title or events. - for ( var i in def ) { - if ( eventRegex.test( i ) || i == 'title' || i == 'type' ) - delete def[ i ]; - } - return def; - }; - - CKEDITOR.tools.extend( CKEDITOR.ui.dialog, { - /** - * Base class for all dialog elements with a textual label on the left. - * - * @class CKEDITOR.ui.dialog.labeledElement - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a labeledElement class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `label` (Required) The label string. - * * `labelLayout` (Optional) Put 'horizontal' here if the - * label element is to be layed out horizontally. Otherwise a vertical - * layout will be used. - * * `widths` (Optional) This applies only for horizontal - * layouts - an 2-element array of lengths to specify the widths of the - * label and the content element. - * - * @param {Array} htmlList List of HTML code to output to. - * @param {Function} contentHtml - * A function returning the HTML code string to be added inside the content - * cell. - */ - labeledElement: function( dialog, elementDefinition, htmlList, contentHtml ) { - if ( arguments.length < 4 ) - return; - - var _ = initPrivateObject.call( this, elementDefinition ); - _.labelId = CKEDITOR.tools.getNextId() + '_label'; - var children = this._.children = []; - - var innerHTML = function() { - var html = [], - requiredClass = elementDefinition.required ? ' cke_required' : ''; - if ( elementDefinition.labelLayout != 'horizontal' ) - html.push( '<label class="cke_dialog_ui_labeled_label' + requiredClass + '" ', ' id="' + _.labelId + '"', ( _.inputId ? ' for="' + _.inputId + '"' : '' ), ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>', elementDefinition.label, '</label>', '<div class="cke_dialog_ui_labeled_content"' + ( elementDefinition.controlStyle ? ' style="' + elementDefinition.controlStyle + '"' : '' ) + ' role="presentation">', contentHtml.call( this, dialog, elementDefinition ), '</div>' ); - else { - var hboxDefinition = { - type: 'hbox', - widths: elementDefinition.widths, - padding: 0, - children: [ - { - type: 'html', - html: '<label class="cke_dialog_ui_labeled_label' + requiredClass + '"' + - ' id="' + _.labelId + '"' + - ' for="' + _.inputId + '"' + - ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>' + - CKEDITOR.tools.htmlEncode( elementDefinition.label ) + - '</span>' - }, - { - type: 'html', - html: '<span class="cke_dialog_ui_labeled_content"' + ( elementDefinition.controlStyle ? ' style="' + elementDefinition.controlStyle + '"' : '' ) + '>' + - contentHtml.call( this, dialog, elementDefinition ) + - '</span>' - } - ] - }; - CKEDITOR.dialog._.uiElementBuilders.hbox.build( dialog, hboxDefinition, html ); - } - return html.join( '' ); - }; - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, { role: 'presentation' }, innerHTML ); - }, - - /** - * A text input with a label. This UI element class represents both the - * single-line text inputs and password inputs in dialog boxes. - * - * @class CKEDITOR.ui.dialog.textInput - * @extends CKEDITOR.ui.dialog.labeledElement - * @constructor Creates a textInput class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `default` (Optional) The default value. - * * `validate` (Optional) The validation function. - * * `maxLength` (Optional) The maximum length of text box contents. - * * `size` (Optional) The size of the text box. This is - * usually overridden by the size defined by the skin, however. - * - * @param {Array} htmlList List of HTML code to output to. - */ - textInput: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - initPrivateObject.call( this, elementDefinition ); - var domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textInput', - attributes = { 'class': 'cke_dialog_ui_input_' + elementDefinition.type, id: domId, type: elementDefinition.type }, - i; - - // Set the validator, if any. - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - // Set the max length and size. - if ( elementDefinition.maxLength ) - attributes.maxlength = elementDefinition.maxLength; - if ( elementDefinition.size ) - attributes.size = elementDefinition.size; - - if ( elementDefinition.inputStyle ) - attributes.style = elementDefinition.inputStyle; - - // If user presses Enter in a text box, it implies clicking OK for the dialog. - var me = this, - keyPressedOnMe = false; - dialog.on( 'load', function() { - me.getInputElement().on( 'keydown', function( evt ) { - if ( evt.data.getKeystroke() == 13 ) - keyPressedOnMe = true; - }); - - // Lower the priority this 'keyup' since 'ok' will close the dialog.(#3749) - me.getInputElement().on( 'keyup', function( evt ) { - if ( evt.data.getKeystroke() == 13 && keyPressedOnMe ) { - dialog.getButton( 'ok' ) && setTimeout( function() { - dialog.getButton( 'ok' ).click(); - }, 0 ); - keyPressedOnMe = false; - } - }, null, null, 1000 ); - }); - - var innerHTML = function() { - // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline - // container's width, so need to wrap it inside a <div>. - var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ]; - - if ( elementDefinition.width ) - html.push( 'style="width:' + elementDefinition.width + '" ' ); - - html.push( '><input ' ); - - attributes[ 'aria-labelledby' ] = this._.labelId; - this._.required && ( attributes[ 'aria-required' ] = this._.required ); - for ( var i in attributes ) - html.push( i + '="' + attributes[ i ] + '" ' ); - html.push( ' /></div>' ); - return html.join( '' ); - }; - CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); - }, - - /** - * A text area with a label on the top or left. - * - * @class CKEDITOR.ui.dialog.textarea - * @extends CKEDITOR.ui.dialog.labeledElement - * @constructor Creates a textarea class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * - * The element definition. Accepted fields: - * - * * `rows` (Optional) The number of rows displayed. - * Defaults to 5 if not defined. - * * `cols` (Optional) The number of cols displayed. - * Defaults to 20 if not defined. Usually overridden by skins. - * * `default` (Optional) The default value. - * * `validate` (Optional) The validation function. - * - * @param {Array} htmlList List of HTML code to output to. - */ - textarea: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - initPrivateObject.call( this, elementDefinition ); - var me = this, - domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textarea', - attributes = {}; - - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - // Generates the essential attributes for the textarea tag. - attributes.rows = elementDefinition.rows || 5; - attributes.cols = elementDefinition.cols || 20; - - attributes[ 'class' ] = 'cke_dialog_ui_input_textarea ' + ( elementDefinition[ 'class' ] || '' ); - - if ( typeof elementDefinition.inputStyle != 'undefined' ) - attributes.style = elementDefinition.inputStyle; - - if ( elementDefinition.dir ) - attributes.dir = elementDefinition.dir; - - var innerHTML = function() { - attributes[ 'aria-labelledby' ] = this._.labelId; - this._.required && ( attributes[ 'aria-required' ] = this._.required ); - var html = [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea id="', domId, '" ' ]; - for ( var i in attributes ) - html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[ i ] ) + '" ' ); - html.push( '>', CKEDITOR.tools.htmlEncode( me._[ 'default' ] ), '</textarea></div>' ); - return html.join( '' ); - }; - CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); - }, - - /** - * A single checkbox with a label on the right. - * - * @class CKEDITOR.ui.dialog.checkbox - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a checkbox class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `checked` (Optional) Whether the checkbox is checked - * on instantiation. Defaults to false. - * * `validate` (Optional) The validation function. - * * `label` (Optional) The checkbox label. - * - * @param {Array} htmlList List of HTML code to output to. - */ - checkbox: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - var _ = initPrivateObject.call( this, elementDefinition, { 'default': !!elementDefinition[ 'default' ] } ); - - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - var innerHTML = function() { - var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition, { - id: elementDefinition.id ? elementDefinition.id + '_checkbox' : CKEDITOR.tools.getNextId() + '_checkbox' - }, true ), - html = []; - - var labelId = CKEDITOR.tools.getNextId() + '_label'; - var attributes = { 'class': 'cke_dialog_ui_checkbox_input', type: 'checkbox', 'aria-labelledby': labelId }; - cleanInnerDefinition( myDefinition ); - if ( elementDefinition[ 'default' ] ) - attributes.checked = 'checked'; - - if ( typeof myDefinition.inputStyle != 'undefined' ) - myDefinition.style = myDefinition.inputStyle; - - _.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes ); - html.push( ' <label id="', labelId, '" for="', attributes.id, '"' + ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>', CKEDITOR.tools.htmlEncode( elementDefinition.label ), '</label>' ); - return html.join( '' ); - }; - - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'span', null, null, innerHTML ); - }, - - /** - * A group of radio buttons. - * - * @class CKEDITOR.ui.dialog.radio - * @extends CKEDITOR.ui.dialog.labeledElement - * @constructor Creates a radio class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `default` (Required) The default value. - * * `validate` (Optional) The validation function. - * * `items` (Required) An array of options. Each option - * is a 1- or 2-item array of format `[ 'Description', 'Value' ]`. If `'Value'` - * is missing, then the value would be assumed to be the same as the description. - * - * @param {Array} htmlList List of HTML code to output to. - */ - radio: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - initPrivateObject.call( this, elementDefinition ); - if ( !this._[ 'default' ] ) - this._[ 'default' ] = this._.initValue = elementDefinition.items[ 0 ][ 1 ]; - if ( elementDefinition.validate ) - this.validate = elementDefinition.valdiate; - var children = [], - me = this; - - var innerHTML = function() { - var inputHtmlList = [], - html = [], - commonAttributes = { 'class': 'cke_dialog_ui_radio_item', 'aria-labelledby': this._.labelId }, - commonName = elementDefinition.id ? elementDefinition.id + '_radio' : CKEDITOR.tools.getNextId() + '_radio'; - for ( var i = 0; i < elementDefinition.items.length; i++ ) { - var item = elementDefinition.items[ i ], - title = item[ 2 ] !== undefined ? item[ 2 ] : item[ 0 ], - value = item[ 1 ] !== undefined ? item[ 1 ] : item[ 0 ], - inputId = CKEDITOR.tools.getNextId() + '_radio_input', - labelId = inputId + '_label', - inputDefinition = CKEDITOR.tools.extend( {}, elementDefinition, { - id: inputId, - title: null, - type: null - }, true ), - labelDefinition = CKEDITOR.tools.extend( {}, inputDefinition, { - title: title - }, true ), - inputAttributes = { - type: 'radio', - 'class': 'cke_dialog_ui_radio_input', - name: commonName, - value: value, - 'aria-labelledby': labelId - }, - inputHtml = []; - if ( me._[ 'default' ] == value ) - inputAttributes.checked = 'checked'; - cleanInnerDefinition( inputDefinition ); - cleanInnerDefinition( labelDefinition ); - - if ( typeof inputDefinition.inputStyle != 'undefined' ) - inputDefinition.style = inputDefinition.inputStyle; - - children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) ); - inputHtml.push( ' ' ); - new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { id: labelId, 'for': inputAttributes.id }, item[ 0 ] ); - inputHtmlList.push( inputHtml.join( '' ) ); - } - new CKEDITOR.ui.dialog.hbox( dialog, children, inputHtmlList, html ); - return html.join( '' ); - }; - - CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); - this._.children = children; - }, - - /** - * A button with a label inside. - * - * @class CKEDITOR.ui.dialog.button - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a button class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `label` (Required) The button label. - * * `disabled` (Optional) Set to true if you want the - * button to appear in disabled state. - * - * @param {Array} htmlList List of HTML code to output to. - */ - button: function( dialog, elementDefinition, htmlList ) { - if ( !arguments.length ) - return; - - if ( typeof elementDefinition == 'function' ) - elementDefinition = elementDefinition( dialog.getParentEditor() ); - - initPrivateObject.call( this, elementDefinition, { disabled: elementDefinition.disabled || false } ); - - // Add OnClick event to this input. - CKEDITOR.event.implementOn( this ); - - var me = this; - - // Register an event handler for processing button clicks. - dialog.on( 'load', function( eventInfo ) { - var element = this.getElement(); - - (function() { - element.on( 'click', function( evt ) { - me.click(); - // #9958 - evt.data.preventDefault(); - } ); - - element.on( 'keydown', function( evt ) { - if ( evt.data.getKeystroke() in { 32:1 } ) { - me.click(); - evt.data.preventDefault(); - } - }); - })(); - - element.unselectable(); - }, this ); - - var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition ); - delete outerDefinition.style; - - var labelId = CKEDITOR.tools.getNextId() + '_label'; - CKEDITOR.ui.dialog.uiElement.call( this, dialog, outerDefinition, htmlList, 'a', null, { - style: elementDefinition.style, - href: 'javascript:void(0)', - title: elementDefinition.label, - hidefocus: 'true', - 'class': elementDefinition[ 'class' ], - role: 'button', - 'aria-labelledby': labelId - }, '<span id="' + labelId + '" class="cke_dialog_ui_button">' + - CKEDITOR.tools.htmlEncode( elementDefinition.label ) + - '</span>' ); - }, - - /** - * A select box. - * - * @class CKEDITOR.ui.dialog.select - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a button class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `default` (Required) The default value. - * * `validate` (Optional) The validation function. - * * `items` (Required) An array of options. Each option - * is a 1- or 2-item array of format `[ 'Description', 'Value' ]`. If `'Value'` - * is missing, then the value would be assumed to be the same as the - * description. - * * `multiple` (Optional) Set this to true if you'd like - * to have a multiple-choice select box. - * * `size` (Optional) The number of items to display in - * the select box. - * - * @param {Array} htmlList List of HTML code to output to. - */ - select: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - var _ = initPrivateObject.call( this, elementDefinition ); - - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - _.inputId = CKEDITOR.tools.getNextId() + '_select'; - - var innerHTML = function() { - var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition, { - id: elementDefinition.id ? elementDefinition.id + '_select' : CKEDITOR.tools.getNextId() + '_select' - }, true ), - html = [], - innerHTML = [], - attributes = { 'id': _.inputId, 'class': 'cke_dialog_ui_input_select', 'aria-labelledby': this._.labelId }; - - html.push( '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ); - if ( elementDefinition.width ) - html.push( 'style="width:' + elementDefinition.width + '" ' ); - html.push( '>' ); - - // Add multiple and size attributes from element definition. - if ( elementDefinition.size != undefined ) - attributes.size = elementDefinition.size; - if ( elementDefinition.multiple != undefined ) - attributes.multiple = elementDefinition.multiple; - - cleanInnerDefinition( myDefinition ); - for ( var i = 0, item; i < elementDefinition.items.length && ( item = elementDefinition.items[ i ] ); i++ ) { - innerHTML.push( '<option value="', CKEDITOR.tools.htmlEncode( item[ 1 ] !== undefined ? item[ 1 ] : item[ 0 ] ).replace( /"/g, '"' ), '" /> ', CKEDITOR.tools.htmlEncode( item[ 0 ] ) ); - } - - if ( typeof myDefinition.inputStyle != 'undefined' ) - myDefinition.style = myDefinition.inputStyle; - - _.select = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'select', null, attributes, innerHTML.join( '' ) ); - - html.push( '</div>' ); - - return html.join( '' ); - }; - - CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); - }, - - /** - * A file upload input. - * - * @class CKEDITOR.ui.dialog.file - * @extends CKEDITOR.ui.dialog.labeledElement - * @constructor Creates a file class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `validate` (Optional) The validation function. - * - * @param {Array} htmlList List of HTML code to output to. - */ - file: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - if ( elementDefinition[ 'default' ] === undefined ) - elementDefinition[ 'default' ] = ''; - - var _ = CKEDITOR.tools.extend( initPrivateObject.call( this, elementDefinition ), { definition: elementDefinition, buttons: [] } ); - - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - /** @ignore */ - var innerHTML = function() { - _.frameId = CKEDITOR.tools.getNextId() + '_fileInput'; - - var html = [ - '<iframe' + - ' frameborder="0"' + - ' allowtransparency="0"' + - ' class="cke_dialog_ui_input_file"' + - ' role="presentation"' + - ' id="', _.frameId, '"' + - ' title="', elementDefinition.label, '"' + - ' src="javascript:void(' ]; - - // Support for custom document.domain on IE. (#10165) - html.push( CKEDITOR.env.ie ? - '(function(){' + encodeURIComponent( - 'document.open();' + - '(' + CKEDITOR.tools.fixDomain + ')();' + - 'document.close();' - ) + '})()' - : - '0' ); - - html.push( ')">' + - '</iframe>' ); - - return html.join( '' ); - }; - - // IE BUG: Parent container does not resize to contain the iframe automatically. - dialog.on( 'load', function() { - var iframe = CKEDITOR.document.getById( _.frameId ), - contentDiv = iframe.getParent(); - contentDiv.addClass( 'cke_dialog_ui_input_file' ); - }); - - CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); - }, - - /** - * A button for submitting the file in a file upload input. - * - * @class CKEDITOR.ui.dialog.fileButton - * @extends CKEDITOR.ui.dialog.button - * @constructor Creates a fileButton class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `for` (Required) The file input's page and element Id - * to associate to, in a 2-item array format: `[ 'page_id', 'element_id' ]`. - * * `validate` (Optional) The validation function. - * - * @param {Array} htmlList List of HTML code to output to. - */ - fileButton: function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - var _ = initPrivateObject.call( this, elementDefinition ), - me = this; - - if ( elementDefinition.validate ) - this.validate = elementDefinition.validate; - - var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition ); - var onClick = myDefinition.onClick; - myDefinition.className = ( myDefinition.className ? myDefinition.className + ' ' : '' ) + 'cke_dialog_ui_button'; - myDefinition.onClick = function( evt ) { - var target = elementDefinition[ 'for' ]; // [ pageId, elementId ] - if ( !onClick || onClick.call( this, evt ) !== false ) { - dialog.getContentElement( target[ 0 ], target[ 1 ] ).submit(); - this.disable(); - } - }; - - dialog.on( 'load', function() { - dialog.getContentElement( elementDefinition[ 'for' ][ 0 ], elementDefinition[ 'for' ][ 1 ] )._.buttons.push( me ); - }); - - CKEDITOR.ui.dialog.button.call( this, dialog, myDefinition, htmlList ); - }, - - html: (function() { - var myHtmlRe = /^\s*<[\w:]+\s+([^>]*)?>/, - theirHtmlRe = /^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/, - emptyTagRe = /\/$/; - /** - * A dialog element made from raw HTML code. - * - * @class CKEDITOR.ui.dialog.html - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a html class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition Element definition. - * Accepted fields: - * - * * `html` (Required) HTML code of this element. - * - * @param {Array} htmlList List of HTML code to be added to the dialog's content area. - */ - return function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - var myHtmlList = [], - myHtml, - theirHtml = elementDefinition.html, - myMatch, theirMatch; - - // If the HTML input doesn't contain any tags at the beginning, add a <span> tag around it. - if ( theirHtml.charAt( 0 ) != '<' ) - theirHtml = '<span>' + theirHtml + '</span>'; - - // Look for focus function in definition. - var focus = elementDefinition.focus; - if ( focus ) { - var oldFocus = this.focus; - this.focus = function() { - ( typeof focus == 'function' ? focus : oldFocus ).call( this ); - this.fire( 'focus' ); - }; - if ( elementDefinition.isFocusable ) { - var oldIsFocusable = this.isFocusable; - this.isFocusable = oldIsFocusable; - } - this.keyboardFocusable = true; - } - - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, myHtmlList, 'span', null, null, '' ); - - // Append the attributes created by the uiElement call to the real HTML. - myHtml = myHtmlList.join( '' ); - myMatch = myHtml.match( myHtmlRe ); - theirMatch = theirHtml.match( theirHtmlRe ) || [ '', '', '' ]; - - if ( emptyTagRe.test( theirMatch[ 1 ] ) ) { - theirMatch[ 1 ] = theirMatch[ 1 ].slice( 0, -1 ); - theirMatch[ 2 ] = '/' + theirMatch[ 2 ]; - } - - htmlList.push( [ theirMatch[ 1 ], ' ', myMatch[ 1 ] || '', theirMatch[ 2 ] ].join( '' ) ); - }; - })(), - - /** - * Form fieldset for grouping dialog UI elements. - * - * @class CKEDITOR.ui.dialog.fieldset - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor Creates a fieldset class instance. - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {Array} childObjList - * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container. - * @param {Array} childHtmlList Array of HTML code that correspond to the HTML output of all the - * objects in childObjList. - * @param {Array} htmlList Array of HTML code that this element will output to. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `label` (Optional) The legend of the this fieldset. - * * `children` (Required) An array of dialog field definitions which will be grouped inside this fieldset. - * - */ - fieldset: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) { - var legendLabel = elementDefinition.label; - /** @ignore */ - var innerHTML = function() { - var html = []; - legendLabel && html.push( '<legend' + - ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + - '>' + legendLabel + '</legend>' ); - for ( var i = 0; i < childHtmlList.length; i++ ) - html.push( childHtmlList[ i ] ); - return html.join( '' ); - }; - - this._ = { children: childObjList }; - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'fieldset', null, null, innerHTML ); - } - - }, true ); - - CKEDITOR.ui.dialog.html.prototype = new CKEDITOR.ui.dialog.uiElement; - - /** @class CKEDITOR.ui.dialog.labeledElement */ - CKEDITOR.ui.dialog.labeledElement.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, { - /** - * Sets the label text of the element. - * - * @param {String} label The new label text. - * @returns {CKEDITOR.ui.dialog.labeledElement} The current labeled element. - */ - setLabel: function( label ) { - var node = CKEDITOR.document.getById( this._.labelId ); - if ( node.getChildCount() < 1 ) - ( new CKEDITOR.dom.text( label, CKEDITOR.document ) ).appendTo( node ); - else - node.getChild( 0 ).$.nodeValue = label; - return this; - }, - - /** - * Retrieves the current label text of the elment. - * - * @returns {String} The current label text. - */ - getLabel: function() { - var node = CKEDITOR.document.getById( this._.labelId ); - if ( !node || node.getChildCount() < 1 ) - return ''; - else - return node.getChild( 0 ).getText(); - }, - - /** - * Defines the onChange event for UI element definitions. - * @property {Object} - */ - eventProcessors: commonEventProcessors - }, true ); - - /** @class CKEDITOR.ui.dialog.button */ - CKEDITOR.ui.dialog.button.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, { - /** - * Simulates a click to the button. - * - * @returns {Object} Return value of the `click` event. - */ - click: function() { - if ( !this._.disabled ) - return this.fire( 'click', { dialog: this._.dialog } ); - return false; - }, - - /** - * Enables the button. - */ - enable: function() { - this._.disabled = false; - var element = this.getElement(); - element && element.removeClass( 'cke_disabled' ); - }, - - /** - * Disables the button. - */ - disable: function() { - this._.disabled = true; - this.getElement().addClass( 'cke_disabled' ); - }, - - /** - * @todo - */ - isVisible: function() { - return this.getElement().getFirst().isVisible(); - }, - - /** - * @todo - */ - isEnabled: function() { - return !this._.disabled; - }, - - /** - * Defines the onChange event and onClick for button element definitions. - * - * @property {Object} - */ - eventProcessors: CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, { - onClick: function( dialog, func ) { - this.on( 'click', function() { - func.apply( this, arguments ); - }); - } - }, true ), - - /** - * Handler for the element's access key up event. Simulates a click to - * the button. - */ - accessKeyUp: function() { - this.click(); - }, - - /** - * Handler for the element's access key down event. Simulates a mouse - * down to the button. - */ - accessKeyDown: function() { - this.focus(); - }, - - keyboardFocusable: true - }, true ); - - /** @class CKEDITOR.ui.dialog.textInput */ - CKEDITOR.ui.dialog.textInput.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, { - /** - * Gets the text input DOM element under this UI object. - * - * @returns {CKEDITOR.dom.element} The DOM element of the text input. - */ - getInputElement: function() { - return CKEDITOR.document.getById( this._.inputId ); - }, - - /** - * Puts focus into the text input. - */ - focus: function() { - var me = this.selectParentTab(); - - // GECKO BUG: setTimeout() is needed to workaround invisible selections. - setTimeout( function() { - var element = me.getInputElement(); - element && element.$.focus(); - }, 0 ); - }, - - /** - * Selects all the text in the text input. - */ - select: function() { - var me = this.selectParentTab(); - - // GECKO BUG: setTimeout() is needed to workaround invisible selections. - setTimeout( function() { - var e = me.getInputElement(); - if ( e ) { - e.$.focus(); - e.$.select(); - } - }, 0 ); - }, - - /** - * Handler for the text input's access key up event. Makes a `select()` - * call to the text input. - */ - accessKeyUp: function() { - this.select(); - }, - - /** - * Sets the value of this text input object. - * - * uiElement.setValue( 'Blamo' ); - * - * @param {Object} value The new value. - * @returns {CKEDITOR.ui.dialog.textInput} The current UI element. - */ - setValue: function( value ) { - !value && ( value = '' ); - return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments ); - }, - - keyboardFocusable: true - }, commonPrototype, true ); - - CKEDITOR.ui.dialog.textarea.prototype = new CKEDITOR.ui.dialog.textInput(); - - /** @class CKEDITOR.ui.dialog.select */ - CKEDITOR.ui.dialog.select.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, { - /** - * Gets the DOM element of the select box. - * - * @returns {CKEDITOR.dom.element} The `<select>` element of this UI element. - */ - getInputElement: function() { - return this._.select.getElement(); - }, - - /** - * Adds an option to the select box. - * - * @param {String} label Option label. - * @param {String} value (Optional) Option value, if not defined it'll be - * assumed to be the same as the label. - * @param {Number} index (Optional) Position of the option to be inserted - * to. If not defined the new option will be inserted to the end of list. - * @returns {CKEDITOR.ui.dialog.select} The current select UI element. - */ - add: function( label, value, index ) { - var option = new CKEDITOR.dom.element( 'option', this.getDialog().getParentEditor().document ), - selectElement = this.getInputElement().$; - option.$.text = label; - option.$.value = ( value === undefined || value === null ) ? label : value; - if ( index === undefined || index === null ) { - if ( CKEDITOR.env.ie ) - selectElement.add( option.$ ); - else - selectElement.add( option.$, null ); - } else - selectElement.add( option.$, index ); - return this; - }, - - /** - * Removes an option from the selection list. - * - * @param {Number} index Index of the option to be removed. - * @returns {CKEDITOR.ui.dialog.select} The current select UI element. - */ - remove: function( index ) { - var selectElement = this.getInputElement().$; - selectElement.remove( index ); - return this; - }, - - /** - * Clears all options out of the selection list. - * - * @returns {CKEDITOR.ui.dialog.select} The current select UI element. - */ - clear: function() { - var selectElement = this.getInputElement().$; - while ( selectElement.length > 0 ) - selectElement.remove( 0 ); - return this; - }, - - keyboardFocusable: true - }, commonPrototype, true ); - - /** @class CKEDITOR.ui.dialog.checkbox */ - CKEDITOR.ui.dialog.checkbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, { - /** - * Gets the checkbox DOM element. - * - * @returns {CKEDITOR.dom.element} The DOM element of the checkbox. - */ - getInputElement: function() { - return this._.checkbox.getElement(); - }, - - /** - * Sets the state of the checkbox. - * - * @param {Boolean} `true` to tick the checkbox, `false` to untick it. - * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element. - */ - setValue: function( checked, noChangeEvent ) { - this.getInputElement().$.checked = checked; - !noChangeEvent && this.fire( 'change', { value: checked } ); - }, - - /** - * Gets the state of the checkbox. - * - * @returns {Boolean} true means the checkbox is ticked, false means it's not ticked. - */ - getValue: function() { - return this.getInputElement().$.checked; - }, - - /** - * Handler for the access key up event. Toggles the checkbox. - */ - accessKeyUp: function() { - this.setValue( !this.getValue() ); - }, - - /** - * Defines the onChange event for UI element definitions. - * - * @property {Object} - */ - eventProcessors: { - onChange: function( dialog, func ) { - if ( !CKEDITOR.env.ie || ( CKEDITOR.env.version > 8 ) ) - return commonEventProcessors.onChange.apply( this, arguments ); - else { - dialog.on( 'load', function() { - var element = this._.checkbox.getElement(); - element.on( 'propertychange', function( evt ) { - evt = evt.data.$; - if ( evt.propertyName == 'checked' ) - this.fire( 'change', { value: element.$.checked } ); - }, this ); - }, this ); - this.on( 'change', func ); - } - return null; - } - }, - - keyboardFocusable: true - }, commonPrototype, true ); - - /** @class CKEDITOR.ui.dialog.radio */ - CKEDITOR.ui.dialog.radio.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, { - /** - * Checks one of the radio buttons in this button group. - * - * @param {String} value The value of the button to be chcked. - * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element. - */ - setValue: function( value, noChangeEvent ) { - var children = this._.children, - item; - for ( var i = 0; - ( i < children.length ) && ( item = children[ i ] ); i++ ) - item.getElement().$.checked = ( item.getValue() == value ); - !noChangeEvent && this.fire( 'change', { value: value } ); - }, - - /** - * Gets the value of the currently checked radio button. - * - * @returns {String} The currently checked button's value. - */ - getValue: function() { - var children = this._.children; - for ( var i = 0; i < children.length; i++ ) { - if ( children[ i ].getElement().$.checked ) - return children[ i ].getValue(); - } - return null; - }, - - /** - * Handler for the access key up event. Focuses the currently - * selected radio button, or the first radio button if none is selected. - */ - accessKeyUp: function() { - var children = this._.children, - i; - for ( i = 0; i < children.length; i++ ) { - if ( children[ i ].getElement().$.checked ) { - children[ i ].getElement().focus(); - return; - } - } - children[ 0 ].getElement().focus(); - }, - - /** - * Defines the onChange event for UI element definitions. - * - * @property {Object} - */ - eventProcessors: { - onChange: function( dialog, func ) { - if ( !CKEDITOR.env.ie ) - return commonEventProcessors.onChange.apply( this, arguments ); - else { - dialog.on( 'load', function() { - var children = this._.children, - me = this; - for ( var i = 0; i < children.length; i++ ) { - var element = children[ i ].getElement(); - element.on( 'propertychange', function( evt ) { - evt = evt.data.$; - if ( evt.propertyName == 'checked' && this.$.checked ) - me.fire( 'change', { value: this.getAttribute( 'value' ) } ); - }); - } - }, this ); - this.on( 'change', func ); - } - return null; - } - }, - - keyboardFocusable: true - }, commonPrototype, true ); - - /** @class CKEDITOR.ui.dialog.file */ - CKEDITOR.ui.dialog.file.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, commonPrototype, { - /** - * Gets the `<input>` element of this file input. - * - * @returns {CKEDITOR.dom.element} The file input element. - */ - getInputElement: function() { - var frameDocument = CKEDITOR.document.getById( this._.frameId ).getFrameDocument(); - return frameDocument.$.forms.length > 0 ? new CKEDITOR.dom.element( frameDocument.$.forms[ 0 ].elements[ 0 ] ) : this.getElement(); - }, - - /** - * Uploads the file in the file input. - * - * @returns {CKEDITOR.ui.dialog.file} This object. - */ - submit: function() { - this.getInputElement().getParent().$.submit(); - return this; - }, - - /** - * Get the action assigned to the form. - * - * @returns {String} The value of the action. - */ - getAction: function() { - return this.getInputElement().getParent().$.action; - }, - - /** - * The events must be applied on the inner input element, and - * that must be done when the iframe & form has been loaded. - */ - registerEvents: function( definition ) { - var regex = /^on([A-Z]\w+)/, - match; - - var registerDomEvent = function( uiElement, dialog, eventName, func ) { - uiElement.on( 'formLoaded', function() { - uiElement.getInputElement().on( eventName, func, uiElement ); - }); - }; - - for ( var i in definition ) { - if ( !( match = i.match( regex ) ) ) - continue; - - if ( this.eventProcessors[ i ] ) - this.eventProcessors[ i ].call( this, this._.dialog, definition[ i ] ); - else - registerDomEvent( this, this._.dialog, match[ 1 ].toLowerCase(), definition[ i ] ); - } - - return this; - }, - - /** - * Redraws the file input and resets the file path in the file input. - * The redraw logic is necessary because non-IE browsers tend to clear - * the `<iframe>` containing the file input after closing the dialog. - */ - reset: function() { - var _ = this._, - frameElement = CKEDITOR.document.getById( _.frameId ), - frameDocument = frameElement.getFrameDocument(), - elementDefinition = _.definition, - buttons = _.buttons, - callNumber = this.formLoadedNumber, - unloadNumber = this.formUnloadNumber, - langDir = _.dialog._.editor.lang.dir, - langCode = _.dialog._.editor.langCode; - - // The callback function for the iframe, but we must call tools.addFunction only once - // so we store the function number in this.formLoadedNumber - if ( !callNumber ) { - callNumber = this.formLoadedNumber = CKEDITOR.tools.addFunction( function() { - // Now we can apply the events to the input type=file - this.fire( 'formLoaded' ); - }, this ); - - // Remove listeners attached to the content of the iframe (the file input) - unloadNumber = this.formUnloadNumber = CKEDITOR.tools.addFunction( function() { - this.getInputElement().clearCustomData(); - }, this ); - - this.getDialog()._.editor.on( 'destroy', function() { - CKEDITOR.tools.removeFunction( callNumber ); - CKEDITOR.tools.removeFunction( unloadNumber ); - }); - } - - function generateFormField() { - frameDocument.$.open(); - - var size = ''; - if ( elementDefinition.size ) - size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE. - - var inputId = _.frameId + '_input'; - - frameDocument.$.write( [ - '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">', - '<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="', - CKEDITOR.tools.htmlEncode( elementDefinition.action ), - '">', - // Replicate the field label inside of iframe. - '<label id="', _.labelId, '" for="', inputId, '" style="display:none">', - CKEDITOR.tools.htmlEncode( elementDefinition.label ), - '</label>', - '<input id="', inputId, '" aria-labelledby="', _.labelId, '" type="file" name="', - CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ), - '" size="', - CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ), - '" />', - '</form>', - '</body></html>', - '<script>', - // Support for custom document.domain in IE. - CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '', - - 'window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');', - 'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}', - '</script>' - ].join( '' ) ); - - frameDocument.$.close(); - - for ( var i = 0; i < buttons.length; i++ ) - buttons[ i ].enable(); - } - - // #3465: Wait for the browser to finish rendering the dialog first. - if ( CKEDITOR.env.gecko ) - setTimeout( generateFormField, 500 ); - else - generateFormField(); - }, - - getValue: function() { - return this.getInputElement().$.value || ''; - }, - - /*** - * The default value of input `type="file"` is an empty string, but during initialization - * of this UI element, the iframe still isn't ready so it can't be read from that object - * Setting it manually prevents later issues about the current value (`''`) being different - * of the initial value (undefined as it asked for `.value` of a div). - */ - setInitValue: function() { - this._.initValue = ''; - }, - - /** - * Defines the onChange event for UI element definitions. - * - * @property {Object} - */ - eventProcessors: { - onChange: function( dialog, func ) { - // If this method is called several times (I'm not sure about how this can happen but the default - // onChange processor includes this protection) - // In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method - if ( !this._.domOnChangeRegistered ) { - // By listening for the formLoaded event, this handler will get reapplied when a new - // form is created - this.on( 'formLoaded', function() { - this.getInputElement().on( 'change', function() { - this.fire( 'change', { value: this.getValue() } ); - }, this ); - }, this ); - this._.domOnChangeRegistered = true; - } - - this.on( 'change', func ); - } - }, - - keyboardFocusable: true - }, true ); - - CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button; - - CKEDITOR.ui.dialog.fieldset.prototype = CKEDITOR.tools.clone( CKEDITOR.ui.dialog.hbox.prototype ); - - CKEDITOR.dialog.addUIElement( 'text', textBuilder ); - CKEDITOR.dialog.addUIElement( 'password', textBuilder ); - CKEDITOR.dialog.addUIElement( 'textarea', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'checkbox', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'radio', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'button', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'select', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'file', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'fileButton', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'html', commonBuilder ); - CKEDITOR.dialog.addUIElement( 'fieldset', containerBuilder ); - } -}); - -/** - * Fired when the value of the uiElement is changed. - * - * @event change - * @member CKEDITOR.ui.dialog.uiElement - */ - -/** - * Fired when the inner frame created by the element is ready. - * Each time the button is used or the dialog is loaded a new - * form might be created. - * - * @event formLoaded - * @member CKEDITOR.ui.dialog.fileButton - */ diff --git a/addons/website/static/lib/ckeditor/plugins/div/dialogs/div.js b/addons/website/static/lib/ckeditor/plugins/div/dialogs/div.js deleted file mode 100644 index 1bd9b6c120c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/div/dialogs/div.js +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - - // Add to collection with DUP examination. - // @param {Object} collection - // @param {Object} element - // @param {Object} database - function addSafely( collection, element, database ) { - // 1. IE doesn't support customData on text nodes; - // 2. Text nodes never get chance to appear twice; - if ( !element.is || !element.getCustomData( 'block_processed' ) ) { - element.is && CKEDITOR.dom.element.setMarker( database, element, 'block_processed', true ); - collection.push( element ); - } - } - - function getNonEmptyChildren( element ) { - var retval = []; - var children = element.getChildren(); - for ( var i = 0; i < children.count(); i++ ) { - var child = children.getItem( i ); - if ( !( child.type === CKEDITOR.NODE_TEXT && ( /^[ \t\n\r]+$/ ).test( child.getText() ) ) ) - retval.push( child ); - } - return retval; - } - - // Dialog reused by both 'creatediv' and 'editdiv' commands. - // @param {Object} editor - // @param {String} command The command name which indicate what the current command is. - function divDialog( editor, command ) { - // Definition of elements at which div operation should stopped. - var divLimitDefinition = (function() { - - // Customzie from specialize blockLimit elements - var definition = CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$blockLimit ); - - if ( editor.config.div_wrapTable ) { - delete definition.td; - delete definition.th; - } - return definition; - })(); - - // DTD of 'div' element - var dtd = CKEDITOR.dtd.div; - - // Get the first div limit element on the element's path. - // @param {Object} element - function getDivContainer( element ) { - var container = editor.elementPath( element ).blockLimit; - - // Dont stop at 'td' and 'th' when div should wrap entire table. - if ( editor.config.div_wrapTable && container.is( [ 'td', 'th' ] ) ) { - var parentPath = editor.elementPath( container.getParent() ); - container = parentPath.blockLimit; - } - - return container; - } - - // Init all fields' setup/commit function. - // @memberof divDialog - function setupFields() { - this.foreach( function( field ) { - // Exclude layout container elements - if ( /^(?!vbox|hbox)/.test( field.type ) ) { - if ( !field.setup ) { - // Read the dialog fields values from the specified - // element attributes. - field.setup = function( element ) { - field.setValue( element.getAttribute( field.id ) || '', 1 ); - }; - } - if ( !field.commit ) { - // Set element attributes assigned by the dialog - // fields. - field.commit = function( element ) { - var fieldValue = this.getValue(); - // ignore default element attribute values - if ( 'dir' == field.id && element.getComputedStyle( 'direction' ) == fieldValue ) - return; - - if ( fieldValue ) - element.setAttribute( field.id, fieldValue ); - else - element.removeAttribute( field.id ); - }; - } - } - }); - } - - // Wrapping 'div' element around appropriate blocks among the selected ranges. - // @param {Object} editor - function createDiv( editor ) { - // new adding containers OR detected pre-existed containers. - var containers = []; - // node markers store. - var database = {}; - // All block level elements which contained by the ranges. - var containedBlocks = [], - block; - - // Get all ranges from the selection. - var selection = editor.getSelection(), - ranges = selection.getRanges(); - var bookmarks = selection.createBookmarks(); - var i, iterator; - - // Calcualte a default block tag if we need to create blocks. - var blockTag = editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'; - - // collect all included elements from dom-iterator - for ( i = 0; i < ranges.length; i++ ) { - iterator = ranges[ i ].createIterator(); - while ( ( block = iterator.getNextParagraph() ) ) { - // include contents of blockLimit elements. - if ( block.getName() in divLimitDefinition ) { - var j, - childNodes = block.getChildren(); - for ( j = 0; j < childNodes.count(); j++ ) - addSafely( containedBlocks, childNodes.getItem( j ), database ); - } else { - while ( !dtd[ block.getName() ] && !block.equals( ranges[ i ].root ) ) - block = block.getParent(); - addSafely( containedBlocks, block, database ); - } - } - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - var blockGroups = groupByDivLimit( containedBlocks ); - var ancestor, blockEl, divElement; - - for ( i = 0; i < blockGroups.length; i++ ) { - var currentNode = blockGroups[ i ][ 0 ]; - - // Calculate the common parent node of all contained elements. - ancestor = currentNode.getParent(); - for ( j = 1; j < blockGroups[ i ].length; j++ ) - ancestor = ancestor.getCommonAncestor( blockGroups[ i ][ j ] ); - - divElement = new CKEDITOR.dom.element( 'div', editor.document ); - - // Normalize the blocks in each group to a common parent. - for ( j = 0; j < blockGroups[ i ].length; j++ ) { - currentNode = blockGroups[ i ][ j ]; - - while ( !currentNode.getParent().equals( ancestor ) ) - currentNode = currentNode.getParent(); - - // This could introduce some duplicated elements in array. - blockGroups[ i ][ j ] = currentNode; - } - - // Wrapped blocks counting - var fixedBlock = null; - for ( j = 0; j < blockGroups[ i ].length; j++ ) { - currentNode = blockGroups[ i ][ j ]; - - // Avoid DUP elements introduced by grouping. - if ( !( currentNode.getCustomData && currentNode.getCustomData( 'block_processed' ) ) ) { - currentNode.is && CKEDITOR.dom.element.setMarker( database, currentNode, 'block_processed', true ); - - // Establish new container, wrapping all elements in this group. - if ( !j ) - divElement.insertBefore( currentNode ); - - divElement.append( currentNode ); - } - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - containers.push( divElement ); - } - - selection.selectBookmarks( bookmarks ); - return containers; - } - - // Divide a set of nodes to different groups by their path's blocklimit element. - // Note: the specified nodes should be in source order naturally, which mean they are supposed to producea by following class: - // * CKEDITOR.dom.range.Iterator - // * CKEDITOR.dom.domWalker - // @returns {Array[]} the grouped nodes - function groupByDivLimit( nodes ) { - var groups = [], - lastDivLimit = null, - path, block; - for ( var i = 0; i < nodes.length; i++ ) { - block = nodes[ i ]; - var limit = getDivContainer( block ); - if ( !limit.equals( lastDivLimit ) ) { - lastDivLimit = limit; - groups.push( [] ); - } - groups[ groups.length - 1 ].push( block ); - } - return groups; - } - - // Synchronous field values to other impacted fields is required, e.g. div styles - // change should also alter inline-style text. - function commitInternally( targetFields ) { - var dialog = this.getDialog(), - element = dialog._element && dialog._element.clone() || new CKEDITOR.dom.element( 'div', editor.document ); - - // Commit this field and broadcast to target fields. - this.commit( element, true ); - - targetFields = [].concat( targetFields ); - var length = targetFields.length, - field; - for ( var i = 0; i < length; i++ ) { - field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) ); - field && field.setup && field.setup( element, true ); - } - } - - - // Registered 'CKEDITOR.style' instances. - var styles = {}; - - // Hold a collection of created block container elements. - var containers = []; - - // @type divDialog - return { - title: editor.lang.div.title, - minWidth: 400, - minHeight: 165, - contents: [ - { - id: 'info', - label: editor.lang.common.generalTab, - title: editor.lang.common.generalTab, - elements: [ - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'elementStyle', - type: 'select', - style: 'width: 100%;', - label: editor.lang.div.styleSelectLabel, - 'default': '', - // Options are loaded dynamically. - items: [ - [ editor.lang.common.notSet, '' ] - ], - onChange: function() { - commitInternally.call( this, [ 'info:elementStyle', 'info:class', 'advanced:dir', 'advanced:style' ] ); - }, - setup: function( element ) { - for ( var name in styles ) - styles[ name ].checkElementRemovable( element, true ) && this.setValue( name, 1 ); - }, - commit: function( element ) { - var styleName; - if ( ( styleName = this.getValue() ) ) { - var style = styles[ styleName ]; - style.applyToObject( element ); - } - else - element.removeAttribute( 'style' ); - } - }, - { - id: 'class', - type: 'text', - requiredContent: 'div(cke-xyz)', // Random text like 'xyz' will check if all are allowed. - label: editor.lang.common.cssClass, - 'default': '' - } - ] - } - ] - }, - { - id: 'advanced', - label: editor.lang.common.advancedTab, - title: editor.lang.common.advancedTab, - elements: [ - { - type: 'vbox', - padding: 1, - children: [ - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - type: 'text', - id: 'id', - requiredContent: 'div[id]', - label: editor.lang.common.id, - 'default': '' - }, - { - type: 'text', - id: 'lang', - requiredContent: 'div[lang]', - label: editor.lang.common.langCode, - 'default': '' - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'text', - id: 'style', - requiredContent: 'div{cke-xyz}', // Random text like 'xyz' will check if all are allowed. - style: 'width: 100%;', - label: editor.lang.common.cssStyle, - 'default': '', - commit: function( element ) { - element.setAttribute( 'style', this.getValue() ); - } - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'text', - id: 'title', - requiredContent: 'div[title]', - style: 'width: 100%;', - label: editor.lang.common.advisoryTitle, - 'default': '' - } - ] - }, - { - type: 'select', - id: 'dir', - requiredContent: 'div[dir]', - style: 'width: 100%;', - label: editor.lang.common.langDir, - 'default': '', - items: [ - [ editor.lang.common.notSet, '' ], - [ - editor.lang.common.langDirLtr, - 'ltr' - ], - [ - editor.lang.common.langDirRtl, - 'rtl' - ] - ] - } - ] - } - ] - } - ], - onLoad: function() { - setupFields.call( this ); - - // Preparing for the 'elementStyle' field. - var dialog = this, - stylesField = this.getContentElement( 'info', 'elementStyle' ); - - // Reuse the 'stylescombo' plugin's styles definition. - editor.getStylesSet( function( stylesDefinitions ) { - var styleName, style; - - if ( stylesDefinitions ) { - // Digg only those styles that apply to 'div'. - for ( var i = 0; i < stylesDefinitions.length; i++ ) { - var styleDefinition = stylesDefinitions[ i ]; - if ( styleDefinition.element && styleDefinition.element == 'div' ) { - styleName = styleDefinition.name; - styles[ styleName ] = style = new CKEDITOR.style( styleDefinition ); - - if ( editor.filter.check( style ) ) { - // Populate the styles field options with style name. - stylesField.items.push( [ styleName, styleName ] ); - stylesField.add( styleName, styleName ); - } - } - } - } - - // We should disable the content element - // it if no options are available at all. - stylesField[ stylesField.items.length > 1 ? 'enable' : 'disable' ](); - - // Now setup the field value manually if dialog was opened on element. (#9689) - setTimeout( function() { - dialog._element && stylesField.setup( dialog._element ); - }, 0 ); - }); - }, - onShow: function() { - // Whether always create new container regardless of existed - // ones. - if ( command == 'editdiv' ) { - // Try to discover the containers that already existed in - // ranges - // update dialog field values - this.setupContent( this._element = CKEDITOR.plugins.div.getSurroundDiv( editor ) ); - } - }, - onOk: function() { - if ( command == 'editdiv' ) - containers = [ this._element ]; - else - containers = createDiv( editor, true ); - - // Update elements attributes - var size = containers.length; - for ( var i = 0; i < size; i++ ) { - this.commitContent( containers[ i ] ); - - // Remove empty 'style' attribute. - !containers[ i ].getAttribute( 'style' ) && containers[ i ].removeAttribute( 'style' ); - } - - this.hide(); - }, - onHide: function() { - // Remove style only when editing existing DIV. (#6315) - if ( command == 'editdiv' ) - this._element.removeCustomData( 'elementStyle' ); - delete this._element; - } - }; - } - - CKEDITOR.dialog.add( 'creatediv', function( editor ) { - return divDialog( editor, 'creatediv' ); - }); - CKEDITOR.dialog.add( 'editdiv', function( editor ) { - return divDialog( editor, 'editdiv' ); - }); -})(); - -/** - * Whether to wrap the whole table instead of indivisual cells when created `<div>` in table cell. - * - * config.div_wrapTable = true; - * - * @cfg {Boolean} [div_wrapTable=false] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/div/icons/creatediv.png b/addons/website/static/lib/ckeditor/plugins/div/icons/creatediv.png Binary files differdeleted file mode 100644 index 6cca564d205..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/div/icons/creatediv.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/div/icons/hidpi/creatediv.png b/addons/website/static/lib/ckeditor/plugins/div/icons/hidpi/creatediv.png Binary files differdeleted file mode 100644 index f0ca49fdf8b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/div/icons/hidpi/creatediv.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/div/lang/en.js b/addons/website/static/lib/ckeditor/plugins/div/lang/en.js deleted file mode 100644 index 1a24ee4f431..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/div/lang/en.js +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'div', 'en', { - IdInputLabel: 'Id', - advisoryTitleInputLabel: 'Advisory Title', - cssClassInputLabel: 'Stylesheet Classes', - edit: 'Edit Div', - inlineStyleInputLabel: 'Inline Style', - langDirLTRLabel: 'Left to Right (LTR)', - langDirLabel: 'Language Direction', - langDirRTLLabel: 'Right to Left (RTL)', - languageCodeInputLabel: ' Language Code', - remove: 'Remove Div', - styleSelectLabel: 'Style', - title: 'Create Div Container', - toolbar: 'Create Div Container' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/div/plugin.js b/addons/website/static/lib/ckeditor/plugins/div/plugin.js deleted file mode 100644 index 19a036c72f1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/div/plugin.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "div" plugin. It wraps the selected block level elements with a 'div' element with specified styles and attributes. - * - */ - -(function() { - CKEDITOR.plugins.add( 'div', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'creatediv', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - var lang = editor.lang.div, - allowed = 'div(*)'; - - if ( CKEDITOR.dialog.isTabEnabled( editor, 'editdiv', 'advanced' ) ) - allowed += ';div[dir,id,lang,title]{*}'; - - editor.addCommand( 'creatediv', new CKEDITOR.dialogCommand( 'creatediv', { - allowedContent: allowed, - requiredContent: 'div', - contextSensitive: true, - refresh: function( editor, path ) { - var context = editor.config.div_wrapTable ? path.root : path.blockLimit; - this.setState( 'div' in context.getDtd() ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - } - })); - - editor.addCommand( 'editdiv', new CKEDITOR.dialogCommand( 'editdiv', { requiredContent: 'div' } ) ); - editor.addCommand( 'removediv', { - requiredContent: 'div', - exec: function( editor ) { - var selection = editor.getSelection(), - ranges = selection && selection.getRanges(), - range, - bookmarks = selection.createBookmarks(), - walker, - toRemove = []; - - function findDiv( node ) { - var div = CKEDITOR.plugins.div.getSurroundDiv( editor, node ); - if ( div && !div.data( 'cke-div-added' ) ) { - toRemove.push( div ); - div.data( 'cke-div-added' ); - } - } - - for ( var i = 0; i < ranges.length; i++ ) { - range = ranges[ i ]; - if ( range.collapsed ) - findDiv( selection.getStartElement() ); - else { - walker = new CKEDITOR.dom.walker( range ); - walker.evaluator = findDiv; - walker.lastForward(); - } - } - - for ( i = 0; i < toRemove.length; i++ ) - toRemove[ i ].remove( true ); - - selection.selectBookmarks( bookmarks ); - } - }); - - editor.ui.addButton && editor.ui.addButton( 'CreateDiv', { - label: lang.toolbar, - command: 'creatediv', - toolbar: 'blocks,50' - }); - - if ( editor.addMenuItems ) { - editor.addMenuItems({ - editdiv: { - label: lang.edit, - command: 'editdiv', - group: 'div', - order: 1 - }, - - removediv: { - label: lang.remove, - command: 'removediv', - group: 'div', - order: 5 - } - }); - - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element ) { - if ( !element || element.isReadOnly() ) - return null; - - - if ( CKEDITOR.plugins.div.getSurroundDiv( editor ) ) { - return { - editdiv: CKEDITOR.TRISTATE_OFF, - removediv: CKEDITOR.TRISTATE_OFF - }; - } - - return null; - }); - } - } - - CKEDITOR.dialog.add( 'creatediv', this.path + 'dialogs/div.js' ); - CKEDITOR.dialog.add( 'editdiv', this.path + 'dialogs/div.js' ); - } - }); - - CKEDITOR.plugins.div = { - getSurroundDiv: function( editor, start ) { - var path = editor.elementPath( start ); - return editor.elementPath( path.blockLimit ).contains( 'div', 1 ); - } - }; -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/divarea/plugin.js b/addons/website/static/lib/ckeditor/plugins/divarea/plugin.js deleted file mode 100644 index bf47eccb925..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/divarea/plugin.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "divarea" plugin. It registers the "wysiwyg" editing - * mode using a DIV element. - */ - -CKEDITOR.plugins.add( 'divarea', { - afterInit: function( editor ) { - // Add the "wysiwyg" mode. - // Do that in the afterInit function, so it'll eventually overwrite - // the mode defined by the wysiwygarea plugin. - editor.addMode( 'wysiwyg', function( callback ) { - var editingBlock = CKEDITOR.dom.element.createFromHtml( '<div class="cke_wysiwyg_div cke_reset" hidefocus="true"></div>' ); - - var contentSpace = editor.ui.space( 'contents' ); - contentSpace.append( editingBlock ); - - editingBlock = editor.editable( editingBlock ); - - editingBlock.detach = CKEDITOR.tools.override( editingBlock.detach, - function( org ) { - return function() { - org.apply( this, arguments ); - this.remove(); - }; - }); - - editor.setData( editor.getData( 1 ), callback ); - editor.fire( 'contentDom' ); - }); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/dialogs/docprops.js b/addons/website/static/lib/ckeditor/plugins/docprops/dialogs/docprops.js deleted file mode 100644 index 0dc1ea80b11..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/dialogs/docprops.js +++ /dev/null @@ -1,608 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'docProps', function( editor ) { - var lang = editor.lang.docprops, - langCommon = editor.lang.common, - metaHash = {}; - - function getDialogValue( dialogName, callback ) { - var onOk = function() { - releaseHandlers( this ); - callback( this, this._.parentDialog ); - }; - var releaseHandlers = function( dialog ) { - dialog.removeListener( 'ok', onOk ); - dialog.removeListener( 'cancel', releaseHandlers ); - }; - var bindToDialog = function( dialog ) { - dialog.on( 'ok', onOk ); - dialog.on( 'cancel', releaseHandlers ); - }; - editor.execCommand( dialogName ); - if ( editor._.storedDialogs.colordialog ) - bindToDialog( editor._.storedDialogs.colordialog ); - else { - CKEDITOR.on( 'dialogDefinition', function( e ) { - if ( e.data.name != dialogName ) - return; - - var definition = e.data.definition; - - e.removeListener(); - definition.onLoad = CKEDITOR.tools.override( definition.onLoad, function( orginal ) { - return function() { - bindToDialog( this ); - definition.onLoad = orginal; - if ( typeof orginal == 'function' ) - orginal.call( this ); - }; - }); - }); - } - } - - function handleOther() { - var dialog = this.getDialog(), - other = dialog.getContentElement( 'general', this.id + 'Other' ); - if ( !other ) - return; - if ( this.getValue() == 'other' ) { - other.getInputElement().removeAttribute( 'readOnly' ); - other.focus(); - other.getElement().removeClass( 'cke_disabled' ); - } else { - other.getInputElement().setAttribute( 'readOnly', true ); - other.getElement().addClass( 'cke_disabled' ); - } - } - - function commitMeta( name, isHttp, value ) { - return function( doc, html, head ) { - var hash = metaHash, - val = typeof value != 'undefined' ? value : this.getValue(); - if ( !val && ( name in hash ) ) - hash[ name ].remove(); - else if ( val && ( name in hash ) ) - hash[ name ].setAttribute( 'content', val ); - else if ( val ) { - var meta = new CKEDITOR.dom.element( 'meta', editor.document ); - meta.setAttribute( isHttp ? 'http-equiv' : 'name', name ); - meta.setAttribute( 'content', val ); - head.append( meta ); - } - }; - } - - function setupMeta( name, ret ) { - return function() { - var hash = metaHash, - result = ( name in hash ) ? hash[ name ].getAttribute( 'content' ) || '' : ''; - if ( ret ) - return result; - this.setValue( result ); - return null; - }; - } - - function commitMargin( name ) { - return function( doc, html, head, body ) { - body.removeAttribute( 'margin' + name ); - var val = this.getValue(); - if ( val !== '' ) - body.setStyle( 'margin-' + name, CKEDITOR.tools.cssLength( val ) ); - else - body.removeStyle( 'margin-' + name ); - }; - } - - function createMetaHash( doc ) { - var hash = {}, - metas = doc.getElementsByTag( 'meta' ), - count = metas.count(); - - for ( var i = 0; i < count; i++ ) { - var meta = metas.getItem( i ); - hash[ meta.getAttribute( meta.hasAttribute( 'http-equiv' ) ? 'http-equiv' : 'name' ).toLowerCase() ] = meta; - } - return hash; - } - // We cannot just remove the style from the element, as it might be affected from non-inline stylesheets. - // To get the proper result, we should manually set the inline style to its default value. - function resetStyle( element, prop, resetVal ) { - element.removeStyle( prop ); - if ( element.getComputedStyle( prop ) != resetVal ) - element.setStyle( prop, resetVal ); - } - - // Utilty to shorten the creation of color fields in the dialog. - var colorField = function( id, label, fieldProps ) { - return { - type: 'hbox', - padding: 0, - widths: [ '60%', '40%' ], - children: [ - CKEDITOR.tools.extend({ - type: 'text', - id: id, - label: lang[ label ] - }, fieldProps || {}, 1 ), - { - type: 'button', - id: id + 'Choose', - label: lang.chooseColor, - className: 'colorChooser', - onClick: function() { - var self = this; - getDialogValue( 'colordialog', function( colorDialog ) { - var dialog = self.getDialog(); - dialog.getContentElement( dialog._.currentTabId, id ).setValue( colorDialog.getContentElement( 'picker', 'selectedColor' ).getValue() ); - }); - } - } - ] - }; - }; - var previewSrc = 'javascript:' + - 'void((function(){' + encodeURIComponent( - 'document.open();' + - ( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) + - 'document.write( \'<html style="background-color: #ffffff; height: 100%"><head></head><body style="width: 100%; height: 100%; margin: 0px">' + lang.previewHtml + '</body></html>\' );' + - 'document.close();' - ) + '})())'; - - return { - title: lang.title, - minHeight: 330, - minWidth: 500, - onShow: function() { - var doc = editor.document, - html = doc.getElementsByTag( 'html' ).getItem( 0 ), - head = doc.getHead(), - body = doc.getBody(); - metaHash = createMetaHash( doc ); - this.setupContent( doc, html, head, body ); - }, - onHide: function() { - metaHash = {}; - }, - onOk: function() { - var doc = editor.document, - html = doc.getElementsByTag( 'html' ).getItem( 0 ), - head = doc.getHead(), - body = doc.getBody(); - this.commitContent( doc, html, head, body ); - }, - contents: [ - { - id: 'general', - label: langCommon.generalTab, - elements: [ - { - type: 'text', - id: 'title', - label: lang.docTitle, - setup: function( doc ) { - this.setValue( doc.getElementsByTag( 'title' ).getItem( 0 ).data( 'cke-title' ) ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( isPreview ) - return; - doc.getElementsByTag( 'title' ).getItem( 0 ).data( 'cke-title', this.getValue() ); - } - }, - { - type: 'hbox', - children: [ - { - type: 'select', - id: 'dir', - label: langCommon.langDir, - style: 'width: 100%', - items: [ - [ langCommon.notSet, '' ], - [ langCommon.langDirLtr, 'ltr' ], - [ langCommon.langDirRtl, 'rtl' ] - ], - setup: function( doc, html, head, body ) { - this.setValue( body.getDirection() || '' ); - }, - commit: function( doc, html, head, body ) { - var val = this.getValue(); - if ( val ) - body.setAttribute( 'dir', val ); - else - body.removeAttribute( 'dir' ); - body.removeStyle( 'direction' ); - } - }, - { - type: 'text', - id: 'langCode', - label: langCommon.langCode, - setup: function( doc, html ) { - this.setValue( html.getAttribute( 'xml:lang' ) || html.getAttribute( 'lang' ) || '' ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( isPreview ) - return; - var val = this.getValue(); - if ( val ) - html.setAttributes({ 'xml:lang': val, lang: val } ); - else - html.removeAttributes( { 'xml:lang':1,lang:1 } ); - } - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'select', - id: 'charset', - label: lang.charset, - style: 'width: 100%', - items: [ - [ langCommon.notSet, '' ], - [ lang.charsetASCII, 'us-ascii' ], - [ lang.charsetCE, 'iso-8859-2' ], - [ lang.charsetCT, 'big5' ], - [ lang.charsetCR, 'iso-8859-5' ], - [ lang.charsetGR, 'iso-8859-7' ], - [ lang.charsetJP, 'iso-2022-jp' ], - [ lang.charsetKR, 'iso-2022-kr' ], - [ lang.charsetTR, 'iso-8859-9' ], - [ lang.charsetUN, 'utf-8' ], - [ lang.charsetWE, 'iso-8859-1' ], - [ lang.other, 'other' ] - ], - 'default': '', - onChange: function() { - this.getDialog().selectedCharset = this.getValue() != 'other' ? this.getValue() : ''; - handleOther.call( this ); - }, - setup: function() { - this.metaCharset = ( 'charset' in metaHash ); - - var func = setupMeta( this.metaCharset ? 'charset' : 'content-type', 1, 1 ), - val = func.call( this ); - - !this.metaCharset && val.match( /charset=[^=]+$/ ) && ( val = val.substring( val.indexOf( '=' ) + 1 ) ); - - if ( val ) { - this.setValue( val.toLowerCase() ); - if ( !this.getValue() ) { - this.setValue( 'other' ); - var other = this.getDialog().getContentElement( 'general', 'charsetOther' ); - other && other.setValue( val ); - } - this.getDialog().selectedCharset = val; - } - - handleOther.call( this ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( isPreview ) - return; - var value = this.getValue(), - other = this.getDialog().getContentElement( 'general', 'charsetOther' ); - - value == 'other' && ( value = other ? other.getValue() : '' ); - - value && !this.metaCharset && ( value = ( metaHash[ 'content-type' ] ? metaHash[ 'content-type' ].getAttribute( 'content' ).split( ';' )[ 0 ] : 'text/html' ) + '; charset=' + value ); - - var func = commitMeta( this.metaCharset ? 'charset' : 'content-type', 1, value ); - func.call( this, doc, html, head ); - } - }, - { - type: 'text', - id: 'charsetOther', - label: lang.charsetOther, - onChange: function() { - this.getDialog().selectedCharset = this.getValue(); - } - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'select', - id: 'docType', - label: lang.docType, - style: 'width: 100%', - items: [ - [ langCommon.notSet, '' ], - [ 'XHTML 1.1', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' ], - [ 'XHTML 1.0 Transitional', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' ], - [ 'XHTML 1.0 Strict', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' ], - [ 'XHTML 1.0 Frameset', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">' ], - [ 'HTML 5', '<!DOCTYPE html>' ], - [ 'HTML 4.01 Transitional', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' ], - [ 'HTML 4.01 Strict', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' ], - [ 'HTML 4.01 Frameset', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">' ], - [ 'HTML 3.2', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">' ], - [ 'HTML 2.0', '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">' ], - [ lang.other, 'other' ] - ], - onChange: handleOther, - setup: function() { - if ( editor.docType ) { - this.setValue( editor.docType ); - if ( !this.getValue() ) { - this.setValue( 'other' ); - var other = this.getDialog().getContentElement( 'general', 'docTypeOther' ); - other && other.setValue( editor.docType ); - } - } - handleOther.call( this ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( isPreview ) - return; - var value = this.getValue(), - other = this.getDialog().getContentElement( 'general', 'docTypeOther' ); - editor.docType = value == 'other' ? ( other ? other.getValue() : '' ) : value; - } - }, - { - type: 'text', - id: 'docTypeOther', - label: lang.docTypeOther - } - ] - }, - { - type: 'checkbox', - id: 'xhtmlDec', - label: lang.xhtmlDec, - setup: function() { - this.setValue( !!editor.xmlDeclaration ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( isPreview ) - return; - if ( this.getValue() ) { - editor.xmlDeclaration = '<?xml version="1.0" encoding="' + ( this.getDialog().selectedCharset || 'utf-8' ) + '"?>'; - html.setAttribute( 'xmlns', 'http://www.w3.org/1999/xhtml' ); - } else { - editor.xmlDeclaration = ''; - html.removeAttribute( 'xmlns' ); - } - } - } - ] - }, - { - id: 'design', - label: lang.design, - elements: [ - { - type: 'hbox', - widths: [ '60%', '40%' ], - children: [ - { - type: 'vbox', - children: [ - colorField( 'txtColor', 'txtColor', { - setup: function( doc, html, head, body ) { - this.setValue( body.getComputedStyle( 'color' ) ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( this.isChanged() || isPreview ) { - body.removeAttribute( 'text' ); - var val = this.getValue(); - if ( val ) - body.setStyle( 'color', val ); - else - body.removeStyle( 'color' ); - } - } - }), - colorField( 'bgColor', 'bgColor', { - setup: function( doc, html, head, body ) { - var val = body.getComputedStyle( 'background-color' ) || ''; - this.setValue( val == 'transparent' ? '' : val ); - }, - commit: function( doc, html, head, body, isPreview ) { - if ( this.isChanged() || isPreview ) { - body.removeAttribute( 'bgcolor' ); - var val = this.getValue(); - if ( val ) - body.setStyle( 'background-color', val ); - else - resetStyle( body, 'background-color', 'transparent' ); - } - } - }), - { - type: 'hbox', - widths: [ '60%', '40%' ], - padding: 1, - children: [ - { - type: 'text', - id: 'bgImage', - label: lang.bgImage, - setup: function( doc, html, head, body ) { - var val = body.getComputedStyle( 'background-image' ) || ''; - if ( val == 'none' ) - val = ''; - else { - val = val.replace( /url\(\s*(["']?)\s*([^\)]*)\s*\1\s*\)/i, function( match, quote, url ) { - return url; - }); - } - this.setValue( val ); - }, - commit: function( doc, html, head, body ) { - body.removeAttribute( 'background' ); - var val = this.getValue(); - if ( val ) - body.setStyle( 'background-image', 'url(' + val + ')' ); - else - resetStyle( body, 'background-image', 'none' ); - } - }, - { - type: 'button', - id: 'bgImageChoose', - label: langCommon.browseServer, - style: 'display:inline-block;margin-top:10px;', - hidden: true, - filebrowser: 'design:bgImage' - } - ] - }, - { - type: 'checkbox', - id: 'bgFixed', - label: lang.bgFixed, - setup: function( doc, html, head, body ) { - this.setValue( body.getComputedStyle( 'background-attachment' ) == 'fixed' ); - }, - commit: function( doc, html, head, body ) { - if ( this.getValue() ) - body.setStyle( 'background-attachment', 'fixed' ); - else - resetStyle( body, 'background-attachment', 'scroll' ); - } - } - ] - }, - { - type: 'vbox', - children: [ - { - type: 'html', - id: 'marginTitle', - html: '<div style="text-align: center; margin: 0px auto; font-weight: bold">' + lang.margin + '</div>' - }, - { - type: 'text', - id: 'marginTop', - label: lang.marginTop, - style: 'width: 80px; text-align: center', - align: 'center', - inputStyle: 'text-align: center', - setup: function( doc, html, head, body ) { - this.setValue( body.getStyle( 'margin-top' ) || body.getAttribute( 'margintop' ) || '' ); - }, - commit: commitMargin( 'top' ) - }, - { - type: 'hbox', - children: [ - { - type: 'text', - id: 'marginLeft', - label: lang.marginLeft, - style: 'width: 80px; text-align: center', - align: 'center', - inputStyle: 'text-align: center', - setup: function( doc, html, head, body ) { - this.setValue( body.getStyle( 'margin-left' ) || body.getAttribute( 'marginleft' ) || '' ); - }, - commit: commitMargin( 'left' ) - }, - { - type: 'text', - id: 'marginRight', - label: lang.marginRight, - style: 'width: 80px; text-align: center', - align: 'center', - inputStyle: 'text-align: center', - setup: function( doc, html, head, body ) { - this.setValue( body.getStyle( 'margin-right' ) || body.getAttribute( 'marginright' ) || '' ); - }, - commit: commitMargin( 'right' ) - } - ] - }, - { - type: 'text', - id: 'marginBottom', - label: lang.marginBottom, - style: 'width: 80px; text-align: center', - align: 'center', - inputStyle: 'text-align: center', - setup: function( doc, html, head, body ) { - this.setValue( body.getStyle( 'margin-bottom' ) || body.getAttribute( 'marginbottom' ) || '' ); - }, - commit: commitMargin( 'bottom' ) - } - ] - } - ] - } - ] - }, - { - id: 'meta', - label: lang.meta, - elements: [ - { - type: 'textarea', - id: 'metaKeywords', - label: lang.metaKeywords, - setup: setupMeta( 'keywords' ), - commit: commitMeta( 'keywords' ) - }, - { - type: 'textarea', - id: 'metaDescription', - label: lang.metaDescription, - setup: setupMeta( 'description' ), - commit: commitMeta( 'description' ) - }, - { - type: 'text', - id: 'metaAuthor', - label: lang.metaAuthor, - setup: setupMeta( 'author' ), - commit: commitMeta( 'author' ) - }, - { - type: 'text', - id: 'metaCopyright', - label: lang.metaCopyright, - setup: setupMeta( 'copyright' ), - commit: commitMeta( 'copyright' ) - } - ] - }, - { - id: 'preview', - label: langCommon.preview, - elements: [ - { - type: 'html', - id: 'previewHtml', - html: '<iframe src="' + previewSrc + '" style="width: 100%; height: 310px" hidefocus="true" frameborder="0" ' + - 'id="cke_docProps_preview_iframe"></iframe>', - onLoad: function() { - this.getDialog().on( 'selectPage', function( ev ) { - if ( ev.data.page == 'preview' ) { - var self = this; - setTimeout( function() { - var doc = CKEDITOR.document.getById( 'cke_docProps_preview_iframe' ).getFrameDocument(), - html = doc.getElementsByTag( 'html' ).getItem( 0 ), - head = doc.getHead(), - body = doc.getBody(); - self.commitContent( doc, html, head, body, 1 ); - }, 50 ); - } - }); - CKEDITOR.document.getById( 'cke_docProps_preview_iframe' ).getAscendant( 'table' ).setStyle( 'height', '100%' ); - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops-rtl.png b/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops-rtl.png Binary files differdeleted file mode 100644 index ed286a2587b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops.png b/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops.png Binary files differdeleted file mode 100644 index 8bfdcb914d5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/icons/docprops.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops-rtl.png b/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops-rtl.png Binary files differdeleted file mode 100644 index 4a966da0391..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops.png b/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops.png Binary files differdeleted file mode 100644 index a66c8697606..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/icons/hidpi/docprops.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/lang/en.js b/addons/website/static/lib/ckeditor/plugins/docprops/lang/en.js deleted file mode 100644 index 2f522be4c17..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/lang/en.js +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'docprops', 'en', { - bgColor: 'Background Color', - bgFixed: 'Non-scrolling (Fixed) Background', - bgImage: 'Background Image URL', - charset: 'Character Set Encoding', - charsetASCII: 'ASCII', - charsetCE: 'Central European', - charsetCR: 'Cyrillic', - charsetCT: 'Chinese Traditional (Big5)', - charsetGR: 'Greek', - charsetJP: 'Japanese', - charsetKR: 'Korean', - charsetOther: 'Other Character Set Encoding', - charsetTR: 'Turkish', - charsetUN: 'Unicode (UTF-8)', - charsetWE: 'Western European', - chooseColor: 'Choose', - design: 'Design', - docTitle: 'Page Title', - docType: 'Document Type Heading', - docTypeOther: 'Other Document Type Heading', - label: 'Document Properties', - margin: 'Page Margins', - marginBottom: 'Bottom', - marginLeft: 'Left', - marginRight: 'Right', - marginTop: 'Top', - meta: 'Meta Tags', - metaAuthor: 'Author', - metaCopyright: 'Copyright', - metaDescription: 'Document Description', - metaKeywords: 'Document Indexing Keywords (comma separated)', - other: 'Other...', - previewHtml: '<p>This is some <strong>sample text</strong>. You are using <a href="javascript:void(0)">CKEditor</a>.</p>', - title: 'Document Properties', - txtColor: 'Text Color', - xhtmlDec: 'Include XHTML Declarations' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/docprops/plugin.js b/addons/website/static/lib/ckeditor/plugins/docprops/plugin.js deleted file mode 100644 index 898739ffbdf..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/docprops/plugin.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'docprops', { - requires: 'wysiwygarea,dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'docprops,docprops-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var cmd = new CKEDITOR.dialogCommand( 'docProps' ); - // Only applicable on full page mode. - cmd.modes = { wysiwyg: editor.config.fullPage }; - cmd.allowedContent = { - body: { - styles: '*', - attributes: 'dir' - }, - html: { - attributes: 'lang,xml:lang' - } - }; - cmd.requiredContent = 'body'; - - editor.addCommand( 'docProps', cmd ); - CKEDITOR.dialog.add( 'docProps', this.path + 'dialogs/docprops.js' ); - - editor.ui.addButton && editor.ui.addButton( 'DocProps', { - label: editor.lang.docprops.label, - command: 'docProps', - toolbar: 'document,30' - }); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/elementspath/lang/en.js b/addons/website/static/lib/ckeditor/plugins/elementspath/lang/en.js deleted file mode 100644 index efce8a3a92d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/elementspath/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'elementspath', 'en', { - eleLabel: 'Elements path', - eleTitle: '%1 element' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/elementspath/plugin.js b/addons/website/static/lib/ckeditor/plugins/elementspath/plugin.js deleted file mode 100644 index c2a30c28786..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/elementspath/plugin.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "elementspath" plugin. It shows all elements in the DOM - * parent tree relative to the current selection in the editing area. - */ - -(function() { - var commands = { - toolbarFocus: { - editorFocus: false, - readOnly: 1, - exec: function( editor ) { - var idBase = editor._.elementsPath.idBase; - var element = CKEDITOR.document.getById( idBase + '0' ); - - // Make the first button focus accessible for IE. (#3417) - // Adobe AIR instead need while of delay. - element && element.focus( CKEDITOR.env.ie || CKEDITOR.env.air ); - } - } - }; - - var emptyHtml = '<span class="cke_path_empty"> </span>'; - - var extra = ''; - - // Some browsers don't cancel key events in the keydown but in the - // keypress. - // TODO: Check if really needed for Gecko+Mac. - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - extra += ' onkeypress="return false;"'; - - // With Firefox, we need to force the button to redraw, otherwise it - // will remain in the focus state. - if ( CKEDITOR.env.gecko ) - extra += ' onblur="this.style.cssText = this.style.cssText;"'; - - var pathItemTpl = CKEDITOR.addTemplate( 'pathItem', '<a' + - ' id="{id}"' + - ' href="{jsTitle}"' + - ' tabindex="-1"' + - ' class="cke_path_item"' + - ' title="{label}"' + - ( ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) ? ' onfocus="event.preventBubble();"' : '' ) + - extra + - ' hidefocus="true" ' + - ' onkeydown="return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );"' + - ' onclick="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' + - ' role="button" aria-label="{label}">' + - '{text}' + - '</a>' ); - - CKEDITOR.plugins.add( 'elementspath', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.on( 'uiSpace', function( event ) { - if ( event.data.space == 'bottom' ) - initElementsPath( editor, event.data ); - } ); - } - } ); - - function initElementsPath( editor, bottomSpaceData ) { - var spaceId = editor.ui.spaceId( 'path' ); - var spaceElement; - var getSpaceElement = function() { - if ( !spaceElement ) - spaceElement = CKEDITOR.document.getById( spaceId ); - return spaceElement; - }; - - var idBase = 'cke_elementspath_' + CKEDITOR.tools.getNextNumber() + '_'; - - editor._.elementsPath = { idBase: idBase, filters: [] }; - - bottomSpaceData.html += '<span id="' + spaceId + '_label" class="cke_voice_label">' + editor.lang.elementspath.eleLabel + '</span>' + - '<span id="' + spaceId + '" class="cke_path" role="group" aria-labelledby="' + spaceId + '_label">' + emptyHtml + '</span>'; - - // Register the ui element to the focus manager. - editor.on( 'uiReady', function() { - var element = editor.ui.space( 'path' ); - element && editor.focusManager.add( element, 1 ); - } ); - - function onClick( elementIndex ) { - var element = editor._.elementsPath.list[ elementIndex ]; - if ( element.equals( editor.editable() ) ) { - var range = editor.createRange(); - range.selectNodeContents( element ); - range.select(); - } else - editor.getSelection().selectElement( element ); - - // It is important to focus() *after* the above selection - // manipulation, otherwise Firefox will have troubles. #10119 - editor.focus(); - } - - var onClickHanlder = CKEDITOR.tools.addFunction( onClick ); - - var onKeyDownHandler = CKEDITOR.tools.addFunction( function( elementIndex, ev ) { - var idBase = editor._.elementsPath.idBase, - element; - - ev = new CKEDITOR.dom.event( ev ); - - var rtl = editor.lang.dir == 'rtl'; - switch ( ev.getKeystroke() ) { - case rtl ? 39: - 37 : // LEFT-ARROW - case 9: // TAB - element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) ); - if ( !element ) - element = CKEDITOR.document.getById( idBase + '0' ); - element.focus(); - return false; - - case rtl ? 37: - 39 : // RIGHT-ARROW - case CKEDITOR.SHIFT + 9: // SHIFT + TAB - element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) ); - if ( !element ) - element = CKEDITOR.document.getById( idBase + ( editor._.elementsPath.list.length - 1 ) ); - element.focus(); - return false; - - case 27: // ESC - editor.focus(); - return false; - - case 13: // ENTER // Opera - case 32: // SPACE - onClick( elementIndex ); - return false; - } - return true; - } ); - - editor.on( 'selectionChange', function( ev ) { - var env = CKEDITOR.env, - editable = editor.editable(), - selection = ev.data.selection, - element = selection.getStartElement(), - html = [], - elementsList = editor._.elementsPath.list = [], - filters = editor._.elementsPath.filters; - - while ( element ) { - var ignore = 0, - name; - - if ( element.data( 'cke-display-name' ) ) - name = element.data( 'cke-display-name' ); - else if ( element.data( 'cke-real-element-type' ) ) - name = element.data( 'cke-real-element-type' ); - else - name = element.getName(); - - for ( var i = 0; i < filters.length; i++ ) { - var ret = filters[ i ]( element, name ); - if ( ret === false ) { - ignore = 1; - break; - } - name = ret || name; - } - - if ( !ignore ) { - var index = elementsList.push( element ) - 1, - label = editor.lang.elementspath.eleTitle.replace( /%1/, name ); - - var item = pathItemTpl.output({ - id: idBase + index, - label: label, - text: name, - jsTitle: 'javascript:void(\'' + name + '\')', - index: index, - keyDownFn: onKeyDownHandler, - clickFn: onClickHanlder - } ); - html.unshift( item ); - - } - - if ( element.equals( editable ) ) - break; - - element = element.getParent(); - } - - var space = getSpaceElement(); - space.setHtml( html.join( '' ) + emptyHtml ); - editor.fire( 'elementsPathUpdate', { space: space } ); - } ); - - function empty() { - spaceElement && spaceElement.setHtml( emptyHtml ); - delete editor._.elementsPath.list; - } - - editor.on( 'readOnly', empty ); - editor.on( 'contentDomUnload', empty ); - - editor.addCommand( 'elementsPathFocus', commands.toolbarFocus ); - editor.setKeystroke( CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ); - } -})(); - -/** - * Fired when the contents of the elementsPath are changed. - * - * @event elementsPathUpdate - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {CKEDITOR.dom.element} data.space The elementsPath container. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/enterkey/plugin.js b/addons/website/static/lib/ckeditor/plugins/enterkey/plugin.js deleted file mode 100644 index 50e1b6fe971..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/enterkey/plugin.js +++ /dev/null @@ -1,531 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.add( 'enterkey', { - init: function( editor ) { - editor.addCommand( 'enter', { - modes: { wysiwyg:1 }, - editorFocus: false, - exec: function( editor ) { - enter( editor ); - } - } ); - - editor.addCommand( 'shiftEnter', { - modes: { wysiwyg:1 }, - editorFocus: false, - exec: function( editor ) { - shiftEnter( editor ); - } - } ); - - editor.setKeystroke( [ - [ 13, 'enter' ], - [ CKEDITOR.SHIFT + 13, 'shiftEnter' ] - ] ); - } - } ); - - var whitespaces = CKEDITOR.dom.walker.whitespaces(), - bookmark = CKEDITOR.dom.walker.bookmark(); - - CKEDITOR.plugins.enterkey = { - enterBlock: function( editor, mode, range, forceMode ) { - // Get the range for the current selection. - range = range || getRange( editor ); - - // We may not have valid ranges to work on, like when inside a - // contenteditable=false element. - if ( !range ) - return; - - var doc = range.document; - - var atBlockStart = range.checkStartOfBlock(), - atBlockEnd = range.checkEndOfBlock(), - path = editor.elementPath( range.startContainer ), - block = path.block, - - // Determine the block element to be used. - blockTag = ( mode == CKEDITOR.ENTER_DIV ? 'div' : 'p' ), - - newBlock; - - // Exit the list when we're inside an empty list item block. (#5376) - if ( atBlockStart && atBlockEnd ) { - // Exit the list when we're inside an empty list item block. (#5376) - if ( block && ( block.is( 'li' ) || block.getParent().is( 'li' ) ) ) { - var blockParent = block.getParent(), - blockGrandParent = blockParent.getParent(), - - firstChild = !block.hasPrevious(), - lastChild = !block.hasNext(), - - selection = editor.getSelection(), - bookmarks = selection.createBookmarks(), - - orgDir = block.getDirection( 1 ), - className = block.getAttribute( 'class' ), - style = block.getAttribute( 'style' ), - dirLoose = blockGrandParent.getDirection( 1 ) != orgDir, - - enterMode = editor.enterMode, - needsBlock = enterMode != CKEDITOR.ENTER_BR || dirLoose || style || className, - - child; - - if ( blockGrandParent.is( 'li' ) ) { - - // If block is the first or the last child of the parent - // list, degrade it and move to the outer list: - // before the parent list if block is first child and after - // the parent list if block is the last child, respectively. - // - // <ul> => <ul> - // <li> => <li> - // <ul> => <ul> - // <li>x</li> => <li>x</li> - // <li>^</li> => </ul> - // </ul> => </li> - // </li> => <li>^</li> - // </ul> => </ul> - // - // AND - // - // <ul> => <ul> - // <li> => <li>^</li> - // <ul> => <li> - // <li>^</li> => <ul> - // <li>x</li> => <li>x</li> - // </ul> => </ul> - // </li> => </li> - // </ul> => </ul> - - if ( firstChild || lastChild ) - block[ firstChild ? 'insertBefore' : 'insertAfter' ]( blockGrandParent ); - - // If the empty block is neither first nor last child - // then split the list and the block as an element - // of outer list. - // - // => <ul> - // => <li> - // <ul> => <ul> - // <li> => <li>x</li> - // <ul> => </ul> - // <li>x</li> => </li> - // <li>^</li> => <li>^</li> - // <li>y</li> => <li> - // </ul> => <ul> - // </li> => <li>y</li> - // </ul> => </ul> - // => </li> - // => </ul> - - else - block.breakParent( blockGrandParent ); - } - - else if ( !needsBlock ) { - block.appendBogus(); - - // If block is the first or last child of the parent - // list, move all block's children out of the list: - // before the list if block is first child and after the list - // if block is the last child, respectively. - // - // <ul> => <ul> - // <li>x</li> => <li>x</li> - // <li>^</li> => </ul> - // </ul> => ^ - // - // AND - // - // <ul> => ^ - // <li>^</li> => <ul> - // <li>x</li> => <li>x</li> - // </ul> => </ul> - - if ( firstChild || lastChild ) { - while ( ( child = block[ firstChild ? 'getFirst' : 'getLast' ]() ) ) - child[ firstChild ? 'insertBefore' : 'insertAfter' ]( blockParent ); - } - - // If the empty block is neither first nor last child - // then split the list and put all the block contents - // between two lists. - // - // <ul> => <ul> - // <li>x</li> => <li>x</li> - // <li>^</li> => </ul> - // <li>y</li> => ^ - // </ul> => <ul> - // => <li>y</li> - // => </ul> - - else { - block.breakParent( blockParent ); - - while ( ( child = block.getLast() ) ) - child.insertAfter( blockParent ); - } - - block.remove(); - } else { - // Use <div> block for ENTER_BR and ENTER_DIV. - newBlock = doc.createElement( mode == CKEDITOR.ENTER_P ? 'p' : 'div' ); - - if ( dirLoose ) - newBlock.setAttribute( 'dir', orgDir ); - - style && newBlock.setAttribute( 'style', style ); - className && newBlock.setAttribute( 'class', className ); - - // Move all the child nodes to the new block. - block.moveChildren( newBlock ); - - // If block is the first or last child of the parent - // list, move it out of the list: - // before the list if block is first child and after the list - // if block is the last child, respectively. - // - // <ul> => <ul> - // <li>x</li> => <li>x</li> - // <li>^</li> => </ul> - // </ul> => <p>^</p> - // - // AND - // - // <ul> => <p>^</p> - // <li>^</li> => <ul> - // <li>x</li> => <li>x</li> - // </ul> => </ul> - - if ( firstChild || lastChild ) - newBlock[ firstChild ? 'insertBefore' : 'insertAfter' ]( blockParent ); - - // If the empty block is neither first nor last child - // then split the list and put the new block between - // two lists. - // - // => <ul> - // <ul> => <li>x</li> - // <li>x</li> => </ul> - // <li>^</li> => <p>^</p> - // <li>y</li> => <ul> - // </ul> => <li>y</li> - // => </ul> - - else { - block.breakParent( blockParent ); - newBlock.insertAfter( blockParent ); - } - - block.remove(); - } - - selection.selectBookmarks( bookmarks ); - - return; - } - - if ( block && block.getParent().is( 'blockquote' ) ) { - block.breakParent( block.getParent() ); - - // If we were at the start of <blockquote>, there will be an empty element before it now. - if ( !block.getPrevious().getFirst( CKEDITOR.dom.walker.invisible( 1 ) ) ) - block.getPrevious().remove(); - - // If we were at the end of <blockquote>, there will be an empty element after it now. - if ( !block.getNext().getFirst( CKEDITOR.dom.walker.invisible( 1 ) ) ) - block.getNext().remove(); - - range.moveToElementEditStart( block ); - range.select(); - return; - } - } - // Don't split <pre> if we're in the middle of it, act as shift enter key. - else if ( block && block.is( 'pre' ) ) { - if ( !atBlockEnd ) { - enterBr( editor, mode, range, forceMode ); - return; - } - } - - // Split the range. - var splitInfo = range.splitBlock( blockTag ); - - if ( !splitInfo ) - return; - - // Get the current blocks. - var previousBlock = splitInfo.previousBlock, - nextBlock = splitInfo.nextBlock; - - var isStartOfBlock = splitInfo.wasStartOfBlock, - isEndOfBlock = splitInfo.wasEndOfBlock; - - var node; - - // If this is a block under a list item, split it as well. (#1647) - if ( nextBlock ) { - node = nextBlock.getParent(); - if ( node.is( 'li' ) ) { - nextBlock.breakParent( node ); - nextBlock.move( nextBlock.getNext(), 1 ); - } - } else if ( previousBlock && ( node = previousBlock.getParent() ) && node.is( 'li' ) ) { - previousBlock.breakParent( node ); - node = previousBlock.getNext(); - range.moveToElementEditStart( node ); - previousBlock.move( previousBlock.getPrevious() ); - } - - // If we have both the previous and next blocks, it means that the - // boundaries were on separated blocks, or none of them where on the - // block limits (start/end). - if ( !isStartOfBlock && !isEndOfBlock ) { - // If the next block is an <li> with another list tree as the first - // child, we'll need to append a filler (<br>/NBSP) or the list item - // wouldn't be editable. (#1420) - if ( nextBlock.is( 'li' ) ) { - var walkerRange = range.clone(); - walkerRange.selectNodeContents( nextBlock ); - var walker = new CKEDITOR.dom.walker( walkerRange ); - walker.evaluator = function( node ) { - return !( bookmark( node ) || whitespaces( node ) || node.type == CKEDITOR.NODE_ELEMENT && node.getName() in CKEDITOR.dtd.$inline && !( node.getName() in CKEDITOR.dtd.$empty ) ); - }; - - node = walker.next(); - if ( node && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'ul', 'ol' ) ) { - ( CKEDITOR.env.ie ? doc.createText( '\xa0' ) : doc.createElement( 'br' ) ).insertBefore( node ); - } - } - - // Move the selection to the end block. - if ( nextBlock ) - range.moveToElementEditStart( nextBlock ); - } else { - var newBlockDir; - - if ( previousBlock ) { - // Do not enter this block if it's a header tag, or we are in - // a Shift+Enter (#77). Create a new block element instead - // (later in the code). - if ( previousBlock.is( 'li' ) || !( headerTagRegex.test( previousBlock.getName() ) || previousBlock.is( 'pre' ) ) ) { - // Otherwise, duplicate the previous block. - newBlock = previousBlock.clone(); - } - } else if ( nextBlock ) - newBlock = nextBlock.clone(); - - if ( !newBlock ) { - // We have already created a new list item. (#6849) - if ( node && node.is( 'li' ) ) - newBlock = node; - else { - newBlock = doc.createElement( blockTag ); - if ( previousBlock && ( newBlockDir = previousBlock.getDirection() ) ) - newBlock.setAttribute( 'dir', newBlockDir ); - } - } - // Force the enter block unless we're talking of a list item. - else if ( forceMode && !newBlock.is( 'li' ) ) - newBlock.renameNode( blockTag ); - - // Recreate the inline elements tree, which was available - // before hitting enter, so the same styles will be available in - // the new block. - var elementPath = splitInfo.elementPath; - if ( elementPath ) { - for ( var i = 0, len = elementPath.elements.length; i < len; i++ ) { - var element = elementPath.elements[ i ]; - - if ( element.equals( elementPath.block ) || element.equals( elementPath.blockLimit ) ) - break; - - if ( CKEDITOR.dtd.$removeEmpty[ element.getName() ] ) { - element = element.clone(); - newBlock.moveChildren( element ); - newBlock.append( element ); - } - } - } - - if ( !CKEDITOR.env.ie ) - newBlock.appendBogus(); - - if ( !newBlock.getParent() ) - range.insertNode( newBlock ); - - // list item start number should not be duplicated (#7330), but we need - // to remove the attribute after it's onto the DOM tree because of old IEs (#7581). - newBlock.is( 'li' ) && newBlock.removeAttribute( 'value' ); - - // This is tricky, but to make the new block visible correctly - // we must select it. - // The previousBlock check has been included because it may be - // empty if we have fixed a block-less space (like ENTER into an - // empty table cell). - if ( CKEDITOR.env.ie && isStartOfBlock && ( !isEndOfBlock || !previousBlock.getChildCount() ) ) { - // Move the selection to the new block. - range.moveToElementEditStart( isEndOfBlock ? previousBlock : newBlock ); - range.select(); - } - - // Move the selection to the new block. - range.moveToElementEditStart( isStartOfBlock && !isEndOfBlock ? nextBlock : newBlock ); - } - - range.select(); - range.scrollIntoView(); - }, - - enterBr: function( editor, mode, range, forceMode ) { - // Get the range for the current selection. - range = range || getRange( editor ); - - // We may not have valid ranges to work on, like when inside a - // contenteditable=false element. - if ( !range ) - return; - - var doc = range.document; - - // Determine the block element to be used. - var blockTag = ( mode == CKEDITOR.ENTER_DIV ? 'div' : 'p' ); - - var isEndOfBlock = range.checkEndOfBlock(); - - var elementPath = new CKEDITOR.dom.elementPath( editor.getSelection().getStartElement() ); - - var startBlock = elementPath.block, - startBlockTag = startBlock && elementPath.block.getName(); - - var isPre = false; - - if ( !forceMode && startBlockTag == 'li' ) { - enterBlock( editor, mode, range, forceMode ); - return; - } - - // If we are at the end of a header block. - if ( !forceMode && isEndOfBlock && headerTagRegex.test( startBlockTag ) ) { - var newBlock, newBlockDir; - - if ( ( newBlockDir = startBlock.getDirection() ) ) { - newBlock = doc.createElement( 'div' ); - newBlock.setAttribute( 'dir', newBlockDir ); - newBlock.insertAfter( startBlock ); - range.setStart( newBlock, 0 ); - } else { - // Insert a <br> after the current paragraph. - doc.createElement( 'br' ).insertAfter( startBlock ); - - // A text node is required by Gecko only to make the cursor blink. - if ( CKEDITOR.env.gecko ) - doc.createText( '' ).insertAfter( startBlock ); - - // IE has different behaviors regarding position. - range.setStartAt( startBlock.getNext(), CKEDITOR.env.ie ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_START ); - } - } else { - var lineBreak; - - // IE<8 prefers text node as line-break inside of <pre> (#4711). - if ( startBlockTag == 'pre' && CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) - lineBreak = doc.createText( '\r' ); - else - lineBreak = doc.createElement( 'br' ); - - range.deleteContents(); - range.insertNode( lineBreak ); - - // IE has different behavior regarding position. - if ( CKEDITOR.env.ie ) - range.setStartAt( lineBreak, CKEDITOR.POSITION_AFTER_END ); - else { - // A text node is required by Gecko only to make the cursor blink. - // We need some text inside of it, so the bogus <br> is properly - // created. - doc.createText( '\ufeff' ).insertAfter( lineBreak ); - - // If we are at the end of a block, we must be sure the bogus node is available in that block. - if ( isEndOfBlock ) - lineBreak.getParent().appendBogus(); - - // Now we can remove the text node contents, so the caret doesn't - // stop on it. - lineBreak.getNext().$.nodeValue = ''; - - range.setStartAt( lineBreak.getNext(), CKEDITOR.POSITION_AFTER_START ); - - } - } - - // This collapse guarantees the cursor will be blinking. - range.collapse( true ); - - range.select(); - range.scrollIntoView(); - } - }; - - var plugin = CKEDITOR.plugins.enterkey, - enterBr = plugin.enterBr, - enterBlock = plugin.enterBlock, - headerTagRegex = /^h[1-6]$/; - - function shiftEnter( editor ) { - // On SHIFT+ENTER: - // 1. We want to enforce the mode to be respected, instead - // of cloning the current block. (#77) - return enter( editor, editor.activeShiftEnterMode, 1 ); - } - - function enter( editor, mode, forceMode ) { - forceMode = editor.config.forceEnterMode || forceMode; - - // Only effective within document. - if ( editor.mode != 'wysiwyg' ) - return; - - if ( !mode ) - mode = editor.activeEnterMode; - - // TODO this should be handled by setting editor.activeEnterMode on selection change. - // Check path block specialities: - // 1. Cannot be a un-splittable element, e.g. table caption; - var path = editor.elementPath(); - if ( !path.isContextFor( 'p' ) ) { - mode = CKEDITOR.ENTER_BR; - forceMode = 1; - } - - editor.fire( 'saveSnapshot' ); // Save undo step. - - if ( mode == CKEDITOR.ENTER_BR ) - enterBr( editor, mode, null, forceMode ); - else - enterBlock( editor, mode, null, forceMode ); - - editor.fire( 'saveSnapshot' ); - } - - function getRange( editor ) { - // Get the selection ranges. - var ranges = editor.getSelection().getRanges( true ); - - // Delete the contents of all ranges except the first one. - for ( var i = ranges.length - 1; i > 0; i-- ) { - ranges[ i ].deleteContents(); - } - - // Return the first range. - return ranges[ 0 ]; - } -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/entities/plugin.js b/addons/website/static/lib/ckeditor/plugins/entities/plugin.js deleted file mode 100644 index 3c92e0c8162..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/entities/plugin.js +++ /dev/null @@ -1,236 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - // Base HTML entities. - var htmlbase = 'nbsp,gt,lt,amp'; - - var entities = - // Latin-1 Entities - 'quot,iexcl,cent,pound,curren,yen,brvbar,sect,uml,copy,ordf,laquo,' + - 'not,shy,reg,macr,deg,plusmn,sup2,sup3,acute,micro,para,middot,' + - 'cedil,sup1,ordm,raquo,frac14,frac12,frac34,iquest,times,divide,' + - - // Symbols - 'fnof,bull,hellip,prime,Prime,oline,frasl,weierp,image,real,trade,' + - 'alefsym,larr,uarr,rarr,darr,harr,crarr,lArr,uArr,rArr,dArr,hArr,' + - 'forall,part,exist,empty,nabla,isin,notin,ni,prod,sum,minus,lowast,' + - 'radic,prop,infin,ang,and,or,cap,cup,int,there4,sim,cong,asymp,ne,' + - 'equiv,le,ge,sub,sup,nsub,sube,supe,oplus,otimes,perp,sdot,lceil,' + - 'rceil,lfloor,rfloor,lang,rang,loz,spades,clubs,hearts,diams,' + - - // Other Special Characters - 'circ,tilde,ensp,emsp,thinsp,zwnj,zwj,lrm,rlm,ndash,mdash,lsquo,' + - 'rsquo,sbquo,ldquo,rdquo,bdquo,dagger,Dagger,permil,lsaquo,rsaquo,' + - 'euro'; - - // Latin Letters Entities - var latin = 'Agrave,Aacute,Acirc,Atilde,Auml,Aring,AElig,Ccedil,Egrave,Eacute,' + - 'Ecirc,Euml,Igrave,Iacute,Icirc,Iuml,ETH,Ntilde,Ograve,Oacute,Ocirc,' + - 'Otilde,Ouml,Oslash,Ugrave,Uacute,Ucirc,Uuml,Yacute,THORN,szlig,' + - 'agrave,aacute,acirc,atilde,auml,aring,aelig,ccedil,egrave,eacute,' + - 'ecirc,euml,igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute,ocirc,' + - 'otilde,ouml,oslash,ugrave,uacute,ucirc,uuml,yacute,thorn,yuml,' + - 'OElig,oelig,Scaron,scaron,Yuml'; - - // Greek Letters Entities. - var greek = 'Alpha,Beta,Gamma,Delta,Epsilon,Zeta,Eta,Theta,Iota,Kappa,Lambda,Mu,' + - 'Nu,Xi,Omicron,Pi,Rho,Sigma,Tau,Upsilon,Phi,Chi,Psi,Omega,alpha,' + - 'beta,gamma,delta,epsilon,zeta,eta,theta,iota,kappa,lambda,mu,nu,xi,' + - 'omicron,pi,rho,sigmaf,sigma,tau,upsilon,phi,chi,psi,omega,thetasym,' + - 'upsih,piv'; - - // Create a mapping table between one character and its entity form from a list of entity names. - // @param reverse {Boolean} Whether to create a reverse map from the entity string form to an actual character. - function buildTable( entities, reverse ) { - var table = {}, - regex = []; - - // Entities that the browsers DOM don't transform to the final char - // automatically. - var specialTable = { - nbsp: '\u00A0', // IE | FF - shy: '\u00AD', // IE - gt: '\u003E', // IE | FF | -- | Opera - lt: '\u003C', // IE | FF | Safari | Opera - amp: '\u0026', // ALL - apos: '\u0027', // IE - quot: '\u0022' // IE - }; - - entities = entities.replace( /\b(nbsp|shy|gt|lt|amp|apos|quot)(?:,|$)/g, function( match, entity ) { - var org = reverse ? '&' + entity + ';' : specialTable[ entity ], - result = reverse ? specialTable[ entity ] : '&' + entity + ';'; - - table[ org ] = result; - regex.push( org ); - return ''; - }); - - if ( !reverse && entities ) { - // Transforms the entities string into an array. - entities = entities.split( ',' ); - - // Put all entities inside a DOM element, transforming them to their - // final chars. - var div = document.createElement( 'div' ), - chars; - div.innerHTML = '&' + entities.join( ';&' ) + ';'; - chars = div.innerHTML; - div = null; - - // Add all chars to the table. - for ( var i = 0; i < chars.length; i++ ) { - var charAt = chars.charAt( i ); - table[ charAt ] = '&' + entities[ i ] + ';'; - regex.push( charAt ); - } - } - - table.regex = regex.join( reverse ? '|' : '' ); - - return table; - } - - CKEDITOR.plugins.add( 'entities', { - afterInit: function( editor ) { - var config = editor.config; - - var dataProcessor = editor.dataProcessor, - htmlFilter = dataProcessor && dataProcessor.htmlFilter; - - if ( htmlFilter ) { - // Mandatory HTML base entities. - var selectedEntities = []; - - if ( config.basicEntities !== false ) - selectedEntities.push( htmlbase ); - - if ( config.entities ) { - if ( selectedEntities.length ) - selectedEntities.push( entities ); - - if ( config.entities_latin ) - selectedEntities.push( latin ); - - if ( config.entities_greek ) - selectedEntities.push( greek ); - - if ( config.entities_additional ) - selectedEntities.push( config.entities_additional ); - } - - var entitiesTable = buildTable( selectedEntities.join( ',' ) ); - - // Create the Regex used to find entities in the text, leave it matches nothing if entities are empty. - var entitiesRegex = entitiesTable.regex ? '[' + entitiesTable.regex + ']' : 'a^'; - delete entitiesTable.regex; - - if ( config.entities && config.entities_processNumerical ) - entitiesRegex = '[^ -~]|' + entitiesRegex; - - entitiesRegex = new RegExp( entitiesRegex, 'g' ); - - function getEntity( character ) { - return config.entities_processNumerical == 'force' || !entitiesTable[ character ] ? '&#' + character.charCodeAt( 0 ) + ';' - : entitiesTable[ character ]; - } - - // Decode entities that the browsers has transformed - // at first place. - var baseEntitiesTable = buildTable( [ htmlbase, 'shy' ].join( ',' ), true ), - baseEntitiesRegex = new RegExp( baseEntitiesTable.regex, 'g' ); - - function getChar( character ) { - return baseEntitiesTable[ character ]; - } - - htmlFilter.addRules({ - text: function( text ) { - return text.replace( baseEntitiesRegex, getChar ).replace( entitiesRegex, getEntity ); - } - }); - } - } - }); -})(); - -/** - * Whether to escape basic HTML entities in the document, including: - * - * * `nbsp` - * * `gt` - * * `lt` - * * `amp` - * - * **Note:** It should not be subject to change unless when outputting a non-HTML data format like BBCode. - * - * config.basicEntities = false; - * - * @cfg {Boolean} [basicEntities=true] - * @member CKEDITOR.config - */ -CKEDITOR.config.basicEntities = true; - -/** - * Whether to use HTML entities in the output. - * - * config.entities = false; - * - * @cfg {Boolean} [entities=true] - * @member CKEDITOR.config - */ -CKEDITOR.config.entities = true; - -/** - * Whether to convert some Latin characters (Latin alphabet No. 1, ISO 8859-1) - * to HTML entities. The list of entities can be found in the - * [W3C HTML 4.01 Specification, section 24.2.1](http://www.w3.org/TR/html4/sgml/entities.html#h-24.2.1). - * - * config.entities_latin = false; - * - * @cfg {Boolean} [entities_latin=true] - * @member CKEDITOR.config - */ -CKEDITOR.config.entities_latin = true; - -/** - * Whether to convert some symbols, mathematical symbols, and Greek letters to - * HTML entities. This may be more relevant for users typing text written in Greek. - * The list of entities can be found in the - * [W3C HTML 4.01 Specification, section 24.3.1(http://www.w3.org/TR/html4/sgml/entities.html#h-24.3.1). - * - * config.entities_greek = false; - * - * @cfg {Boolean} [entities_greek=true] - * @member CKEDITOR.config - */ -CKEDITOR.config.entities_greek = true; - -/** - * Whether to convert all remaining characters not included in the ASCII - * character table to their relative decimal numeric representation of HTML entity. - * When set to `force`, it will convert all entities into this format. - * - * For example the phrase `'This is Chinese: 汉语.'` is output - * as `'This is Chinese: 汉语.'` - * - * config.entities_processNumerical = true; - * config.entities_processNumerical = 'force'; // Converts from ' ' into ' '; - * - * @cfg {Boolean/String} [entities_processNumerical=false] - * @member CKEDITOR.config - */ - -/** - * A comma separated list of additional entities to be used. Entity names - * or numbers must be used in a form that excludes the `'&'` prefix and the `';'` ending. - * - * config.entities_additional = '#1049'; // Adds Cyrillic capital letter Short I (Й). - * - * @cfg {String} [entities_additional='#39' (The single quote (') character)] - * @member CKEDITOR.config - */ -CKEDITOR.config.entities_additional = '#39'; diff --git a/addons/website/static/lib/ckeditor/plugins/fakeobjects/lang/en.js b/addons/website/static/lib/ckeditor/plugins/fakeobjects/lang/en.js deleted file mode 100644 index b5897509d93..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/fakeobjects/lang/en.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'fakeobjects', 'en', { - anchor: 'Anchor', - flash: 'Flash Animation', - hiddenfield: 'Hidden Field', - iframe: 'IFrame', - unknown: 'Unknown Object' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/fakeobjects/plugin.js b/addons/website/static/lib/ckeditor/plugins/fakeobjects/plugin.js deleted file mode 100644 index 254434af869..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/fakeobjects/plugin.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var cssStyle = CKEDITOR.htmlParser.cssStyle, - cssLength = CKEDITOR.tools.cssLength; - - var cssLengthRegex = /^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i; - - // Replacing the former CSS length value with the later one, with - // adjustment to the length unit. - function replaceCssLength( length1, length2 ) { - var parts1 = cssLengthRegex.exec( length1 ), - parts2 = cssLengthRegex.exec( length2 ); - - // Omit pixel length unit when necessary, - // e.g. replaceCssLength( 10, '20px' ) -> 20 - if ( parts1 ) { - if ( !parts1[ 2 ] && parts2[ 2 ] == 'px' ) - return parts2[ 1 ]; - if ( parts1[ 2 ] == 'px' && !parts2[ 2 ] ) - return parts2[ 1 ] + 'px'; - } - - return length2; - } - - var htmlFilterRules = { - elements: { - $: function( element ) { - var attributes = element.attributes, - realHtml = attributes && attributes[ 'data-cke-realelement' ], - realFragment = realHtml && new CKEDITOR.htmlParser.fragment.fromHtml( decodeURIComponent( realHtml ) ), - realElement = realFragment && realFragment.children[ 0 ]; - - // Width/height in the fake object are subjected to clone into the real element. - if ( realElement && element.attributes[ 'data-cke-resizable' ] ) { - var styles = new cssStyle( element ).rules, - realAttrs = realElement.attributes, - width = styles.width, - height = styles.height; - - width && ( realAttrs.width = replaceCssLength( realAttrs.width, width ) ); - height && ( realAttrs.height = replaceCssLength( realAttrs.height, height ) ); - } - - return realElement; - } - } - }; - - var plugin = CKEDITOR.plugins.add( 'fakeobjects', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - htmlFilter = dataProcessor && dataProcessor.htmlFilter; - - if ( htmlFilter ) - htmlFilter.addRules( htmlFilterRules ); - } - }); - - /** - * @member CKEDITOR.editor - * @todo - */ - CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable ) { - var lang = this.lang.fakeobjects, - label = lang[ realElementType ] || lang.unknown; - - var attributes = { - 'class': className, - 'data-cke-realelement': encodeURIComponent( realElement.getOuterHtml() ), - 'data-cke-real-node-type': realElement.type, - alt: label, - title: label, - align: realElement.getAttribute( 'align' ) || '' - }; - - // Do not set "src" on high-contrast so the alt text is displayed. (#8945) - if ( !CKEDITOR.env.hc ) - attributes.src = CKEDITOR.getUrl( plugin.path + 'images/spacer.gif' ); - - if ( realElementType ) - attributes[ 'data-cke-real-element-type' ] = realElementType; - - if ( isResizable ) { - attributes[ 'data-cke-resizable' ] = isResizable; - - var fakeStyle = new cssStyle(); - - var width = realElement.getAttribute( 'width' ), - height = realElement.getAttribute( 'height' ); - - width && ( fakeStyle.rules.width = cssLength( width ) ); - height && ( fakeStyle.rules.height = cssLength( height ) ); - fakeStyle.populate( attributes ); - } - - return this.document.createElement( 'img', { attributes: attributes } ); - }; - - /** - * @member CKEDITOR.editor - * @todo - */ - CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable ) { - var lang = this.lang.fakeobjects, - label = lang[ realElementType ] || lang.unknown, - html; - - var writer = new CKEDITOR.htmlParser.basicWriter(); - realElement.writeHtml( writer ); - html = writer.getHtml(); - - var attributes = { - 'class': className, - 'data-cke-realelement': encodeURIComponent( html ), - 'data-cke-real-node-type': realElement.type, - alt: label, - title: label, - align: realElement.attributes.align || '' - }; - - // Do not set "src" on high-contrast so the alt text is displayed. (#8945) - if ( !CKEDITOR.env.hc ) - attributes.src = CKEDITOR.getUrl( plugin.path + 'images/spacer.gif' ); - - if ( realElementType ) - attributes[ 'data-cke-real-element-type' ] = realElementType; - - if ( isResizable ) { - attributes[ 'data-cke-resizable' ] = isResizable; - var realAttrs = realElement.attributes, - fakeStyle = new cssStyle(); - - var width = realAttrs.width, - height = realAttrs.height; - - width != undefined && ( fakeStyle.rules.width = cssLength( width ) ); - height != undefined && ( fakeStyle.rules.height = cssLength( height ) ); - fakeStyle.populate( attributes ); - } - - return new CKEDITOR.htmlParser.element( 'img', attributes ); - }; - - /** - * @member CKEDITOR.editor - * @todo - */ - CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) { - if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT ) - return null; - - var element = CKEDITOR.dom.element.createFromHtml( decodeURIComponent( fakeElement.data( 'cke-realelement' ) ), this.document ); - - if ( fakeElement.data( 'cke-resizable' ) ) { - var width = fakeElement.getStyle( 'width' ), - height = fakeElement.getStyle( 'height' ); - - width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) ); - height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) ); - } - - return element; - }; - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/filebrowser/plugin.js b/addons/website/static/lib/ckeditor/plugins/filebrowser/plugin.js deleted file mode 100644 index 0a24ef98798..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/filebrowser/plugin.js +++ /dev/null @@ -1,497 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "filebrowser" plugin that adds support for file uploads and - * browsing. - * - * When a file is uploaded or selected inside the file browser, its URL is - * inserted automatically into a field defined in the <code>filebrowser</code> - * attribute. In order to specify a field that should be updated, pass the tab ID and - * the element ID, separated with a colon.<br /><br /> - * - * <strong>Example 1: (Browse)</strong> - * - * <pre> - * { - * type : 'button', - * id : 'browse', - * filebrowser : 'tabId:elementId', - * label : editor.lang.common.browseServer - * } - * </pre> - * - * If you set the <code>filebrowser</code> attribute for an element other than - * the <code>fileButton</code>, the <code>Browse</code> action will be triggered.<br /><br /> - * - * <strong>Example 2: (Quick Upload)</strong> - * - * <pre> - * { - * type : 'fileButton', - * id : 'uploadButton', - * filebrowser : 'tabId:elementId', - * label : editor.lang.common.uploadSubmit, - * 'for' : [ 'upload', 'upload' ] - * } - * </pre> - * - * If you set the <code>filebrowser</code> attribute for a <code>fileButton</code> - * element, the <code>QuickUpload</code> action will be executed.<br /><br /> - * - * The filebrowser plugin also supports more advanced configuration performed through - * a JavaScript object. - * - * The following settings are supported: - * - * <ul> - * <li><code>action</code> – <code>Browse</code> or <code>QuickUpload</code>.</li> - * <li><code>target</code> – the field to update in the <code><em>tabId:elementId</em></code> format.</li> - * <li><code>params</code> – additional arguments to be passed to the server connector (optional).</li> - * <li><code>onSelect</code> – a function to execute when the file is selected/uploaded (optional).</li> - * <li><code>url</code> – the URL to be called (optional).</li> - * </ul> - * - * <strong>Example 3: (Quick Upload)</strong> - * - * <pre> - * { - * type : 'fileButton', - * label : editor.lang.common.uploadSubmit, - * id : 'buttonId', - * filebrowser : - * { - * action : 'QuickUpload', // required - * target : 'tab1:elementId', // required - * params : // optional - * { - * type : 'Files', - * currentFolder : '/folder/' - * }, - * onSelect : function( fileUrl, errorMessage ) // optional - * { - * // Do not call the built-in selectFuntion. - * // return false; - * } - * }, - * 'for' : [ 'tab1', 'myFile' ] - * } - * </pre> - * - * Suppose you have a file element with an ID of <code>myFile</code>, a text - * field with an ID of <code>elementId</code> and a <code>fileButton</code>. - * If the <code>filebowser.url</code> attribute is not specified explicitly, - * the form action will be set to <code>filebrowser[<em>DialogWindowName</em>]UploadUrl</code> - * or, if not specified, to <code>filebrowserUploadUrl</code>. Additional parameters - * from the <code>params</code> object will be added to the query string. It is - * possible to create your own <code>uploadHandler</code> and cancel the built-in - * <code>updateTargetElement</code> command.<br /><br /> - * - * <strong>Example 4: (Browse)</strong> - * - * <pre> - * { - * type : 'button', - * id : 'buttonId', - * label : editor.lang.common.browseServer, - * filebrowser : - * { - * action : 'Browse', - * url : '/ckfinder/ckfinder.html&type=Images', - * target : 'tab1:elementId' - * } - * } - * </pre> - * - * In this example, when the button is pressed, the file browser will be opened in a - * popup window. If you do not specify the <code>filebrowser.url</code> attribute, - * <code>filebrowser[<em>DialogName</em>]BrowseUrl</code> or - * <code>filebrowserBrowseUrl</code> will be used. After selecting a file in the file - * browser, an element with an ID of <code>elementId</code> will be updated. Just - * like in the third example, a custom <code>onSelect</code> function may be defined. - */ - -(function() { - // Adds (additional) arguments to given url. - // - // @param {String} - // url The url. - // @param {Object} - // params Additional parameters. - function addQueryString( url, params ) { - var queryString = []; - - if ( !params ) - return url; - else { - for ( var i in params ) - queryString.push( i + "=" + encodeURIComponent( params[ i ] ) ); - } - - return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" ); - } - - // Make a string's first character uppercase. - // - // @param {String} - // str String. - function ucFirst( str ) { - str += ''; - var f = str.charAt( 0 ).toUpperCase(); - return f + str.substr( 1 ); - } - - // The onlick function assigned to the 'Browse Server' button. Opens the - // file browser and updates target field when file is selected. - // - // @param {CKEDITOR.event} - // evt The event object. - function browseServer( evt ) { - var dialog = this.getDialog(); - var editor = dialog.getParentEditor(); - - editor._.filebrowserSe = this; - - var width = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowWidth' ] || editor.config.filebrowserWindowWidth || '80%'; - var height = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowHeight' ] || editor.config.filebrowserWindowHeight || '70%'; - - var params = this.filebrowser.params || {}; - params.CKEditor = editor.name; - params.CKEditorFuncNum = editor._.filebrowserFn; - if ( !params.langCode ) - params.langCode = editor.langCode; - - var url = addQueryString( this.filebrowser.url, params ); - // TODO: V4: Remove backward compatibility (#8163). - editor.popup( url, width, height, editor.config.filebrowserWindowFeatures || editor.config.fileBrowserWindowFeatures ); - } - - // The onlick function assigned to the 'Upload' button. Makes the final - // decision whether form is really submitted and updates target field when - // file is uploaded. - // - // @param {CKEDITOR.event} - // evt The event object. - function uploadFile( evt ) { - var dialog = this.getDialog(); - var editor = dialog.getParentEditor(); - - editor._.filebrowserSe = this; - - // If user didn't select the file, stop the upload. - if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getInputElement().$.value ) - return false; - - if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getAction() ) - return false; - - return true; - } - - // Setups the file element. - // - // @param {CKEDITOR.ui.dialog.file} - // fileInput The file element used during file upload. - // @param {Object} - // filebrowser Object containing filebrowser settings assigned to - // the fileButton associated with this file element. - function setupFileElement( editor, fileInput, filebrowser ) { - var params = filebrowser.params || {}; - params.CKEditor = editor.name; - params.CKEditorFuncNum = editor._.filebrowserFn; - if ( !params.langCode ) - params.langCode = editor.langCode; - - fileInput.action = addQueryString( filebrowser.url, params ); - fileInput.filebrowser = filebrowser; - } - - // Traverse through the content definition and attach filebrowser to - // elements with 'filebrowser' attribute. - // - // @param String - // dialogName Dialog name. - // @param {CKEDITOR.dialog.definitionObject} - // definition Dialog definition. - // @param {Array} - // elements Array of {@link CKEDITOR.dialog.definition.content} - // objects. - function attachFileBrowser( editor, dialogName, definition, elements ) { - if ( !elements || !elements.length ) - return; - - var element, fileInput; - - for ( var i = elements.length; i--; ) { - element = elements[ i ]; - - if ( element.type == 'hbox' || element.type == 'vbox' || element.type == 'fieldset' ) - attachFileBrowser( editor, dialogName, definition, element.children ); - - if ( !element.filebrowser ) - continue; - - if ( typeof element.filebrowser == 'string' ) { - var fb = { - action: ( element.type == 'fileButton' ) ? 'QuickUpload' : 'Browse', - target: element.filebrowser - }; - element.filebrowser = fb; - } - - if ( element.filebrowser.action == 'Browse' ) { - var url = element.filebrowser.url; - if ( url === undefined ) { - url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'BrowseUrl' ]; - if ( url === undefined ) - url = editor.config.filebrowserBrowseUrl; - } - - if ( url ) { - element.onClick = browseServer; - element.filebrowser.url = url; - element.hidden = false; - } - } else if ( element.filebrowser.action == 'QuickUpload' && element[ 'for' ] ) { - url = element.filebrowser.url; - if ( url === undefined ) { - url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'UploadUrl' ]; - if ( url === undefined ) - url = editor.config.filebrowserUploadUrl; - } - - if ( url ) { - var onClick = element.onClick; - element.onClick = function( evt ) { - // "element" here means the definition object, so we need to find the correct - // button to scope the event call - var sender = evt.sender; - if ( onClick && onClick.call( sender, evt ) === false ) - return false; - - return uploadFile.call( sender, evt ); - }; - - element.filebrowser.url = url; - element.hidden = false; - setupFileElement( editor, definition.getContents( element[ 'for' ][ 0 ] ).get( element[ 'for' ][ 1 ] ), element.filebrowser ); - } - } - } - } - - // Updates the target element with the url of uploaded/selected file. - // - // @param {String} - // url The url of a file. - function updateTargetElement( url, sourceElement ) { - var dialog = sourceElement.getDialog(); - var targetElement = sourceElement.filebrowser.target || null; - - // If there is a reference to targetElement, update it. - if ( targetElement ) { - var target = targetElement.split( ':' ); - var element = dialog.getContentElement( target[ 0 ], target[ 1 ] ); - if ( element ) { - element.setValue( url ); - dialog.selectPage( target[ 0 ] ); - } - } - } - - // Returns true if filebrowser is configured in one of the elements. - // - // @param {CKEDITOR.dialog.definitionObject} - // definition Dialog definition. - // @param String - // tabId The tab id where element(s) can be found. - // @param String - // elementId The element id (or ids, separated with a semicolon) to check. - function isConfigured( definition, tabId, elementId ) { - if ( elementId.indexOf( ";" ) !== -1 ) { - var ids = elementId.split( ";" ); - for ( var i = 0; i < ids.length; i++ ) { - if ( isConfigured( definition, tabId, ids[ i ] ) ) - return true; - } - return false; - } - - var elementFileBrowser = definition.getContents( tabId ).get( elementId ).filebrowser; - return ( elementFileBrowser && elementFileBrowser.url ); - } - - function setUrl( fileUrl, data ) { - var dialog = this._.filebrowserSe.getDialog(), - targetInput = this._.filebrowserSe[ 'for' ], - onSelect = this._.filebrowserSe.filebrowser.onSelect; - - if ( targetInput ) - dialog.getContentElement( targetInput[ 0 ], targetInput[ 1 ] ).reset(); - - if ( typeof data == 'function' && data.call( this._.filebrowserSe ) === false ) - return; - - if ( onSelect && onSelect.call( this._.filebrowserSe, fileUrl, data ) === false ) - return; - - // The "data" argument may be used to pass the error message to the editor. - if ( typeof data == 'string' && data ) - alert( data ); - - if ( fileUrl ) - updateTargetElement( fileUrl, this._.filebrowserSe ); - } - - CKEDITOR.plugins.add( 'filebrowser', { - requires: 'popup', - init: function( editor, pluginPath ) { - editor._.filebrowserFn = CKEDITOR.tools.addFunction( setUrl, editor ); - editor.on( 'destroy', function() { - CKEDITOR.tools.removeFunction( this._.filebrowserFn ); - }); - } - }); - - CKEDITOR.on( 'dialogDefinition', function( evt ) { - var definition = evt.data.definition, - element; - // Associate filebrowser to elements with 'filebrowser' attribute. - for ( var i = 0; i < definition.contents.length; ++i ) { - if ( ( element = definition.contents[ i ] ) ) { - attachFileBrowser( evt.editor, evt.data.name, definition, element.elements ); - if ( element.hidden && element.filebrowser ) { - element.hidden = !isConfigured( definition, element[ 'id' ], element.filebrowser ); - } - } - } - }); - -})(); - -/** - * The location of an external file browser that should be launched when the **Browse Server** - * button is pressed. If configured, the **Browse Server** button will appear in the - * **Link**, **Image**, and **Flash** dialog windows. - * - * See the [File Browser/Uploader](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_(Uploader\)) documentation. - * - * config.filebrowserBrowseUrl = '/browser/browse.php'; - * - * @since 3.0 - * @cfg {String} [filebrowserBrowseUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of the script that handles file uploads. - * If set, the **Upload** tab will appear in the **Link**, **Image**, - * and **Flash** dialog windows. - * - * See the [File Browser/Uploader](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_(Uploader\)) documentation. - * - * config.filebrowserUploadUrl = '/uploader/upload.php'; - * - * @since 3.0 - * @cfg {String} [filebrowserUploadUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of an external file browser that should be launched when the **Browse Server** - * button is pressed in the **Image** dialog window. - * - * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}. - * - * config.filebrowserImageBrowseUrl = '/browser/browse.php?type=Images'; - * - * @since 3.0 - * @cfg {String} [filebrowserImageBrowseUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of an external file browser that should be launched when the **Browse Server** - * button is pressed in the **Flash** dialog window. - * - * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}. - * - * config.filebrowserFlashBrowseUrl = '/browser/browse.php?type=Flash'; - * - * @since 3.0 - * @cfg {String} [filebrowserFlashBrowseUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of the script that handles file uploads in the **Image** dialog window. - * - * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserUploadUrl}. - * - * config.filebrowserImageUploadUrl = '/uploader/upload.php?type=Images'; - * - * @since 3.0 - * @cfg {String} [filebrowserImageUploadUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of the script that handles file uploads in the **Flash** dialog window. - * - * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserUploadUrl}. - * - * config.filebrowserFlashUploadUrl = '/uploader/upload.php?type=Flash'; - * - * @since 3.0 - * @cfg {String} filebrowserFlashUploadUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The location of an external file browser that should be launched when the **Browse Server** - * button is pressed in the **Link** tab of the **Image** dialog window. - * - * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}. - * - * config.filebrowserImageBrowseLinkUrl = '/browser/browse.php'; - * - * @since 3.2 - * @cfg {String} [filebrowserImageBrowseLinkUrl='' (empty string = disabled)] - * @member CKEDITOR.config - */ - -/** - * The features to use in the file browser popup window. - * - * config.filebrowserWindowFeatures = 'resizable=yes,scrollbars=no'; - * - * @since 3.4.1 - * @cfg {String} [filebrowserWindowFeatures='location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes'] - * @member CKEDITOR.config - */ - -/** - * The width of the file browser popup window. It can be a number denoting a value in - * pixels or a percent string. - * - * config.filebrowserWindowWidth = 750; - * - * config.filebrowserWindowWidth = '50%'; - * - * @cfg {Number/String} [filebrowserWindowWidth='80%'] - * @member CKEDITOR.config - */ - -/** - * The height of the file browser popup window. It can be a number denoting a value in - * pixels or a percent string. - * - * config.filebrowserWindowHeight = 580; - * - * config.filebrowserWindowHeight = '50%'; - * - * @cfg {Number/String} [filebrowserWindowHeight='70%'] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/find/dialogs/find.js b/addons/website/static/lib/ckeditor/plugins/find/dialogs/find.js deleted file mode 100755 index cc2fe031b6b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/dialogs/find.js +++ /dev/null @@ -1,790 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var isReplace; - - function findEvaluator( node ) { - return node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 && ( !isReplace || !node.isReadOnly() ); - } - - // Elements which break characters been considered as sequence. - function nonCharactersBoundary( node ) { - return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$empty, CKEDITOR.dtd.$nonEditable ) ) ); - } - - // Get the cursor object which represent both current character and it's dom - // position thing. - var cursorStep = function() { - return { - textNode: this.textNode, - offset: this.offset, - character: this.textNode ? this.textNode.getText().charAt( this.offset ) : null, - hitMatchBoundary: this._.matchBoundary - }; - }; - - var pages = [ 'find', 'replace' ], - fieldsMapping = [ - [ 'txtFindFind', 'txtFindReplace' ], - [ 'txtFindCaseChk', 'txtReplaceCaseChk' ], - [ 'txtFindWordChk', 'txtReplaceWordChk' ], - [ 'txtFindCyclic', 'txtReplaceCyclic' ] ]; - - // Synchronize corresponding filed values between 'replace' and 'find' pages. - // @param {String} currentPageId The page id which receive values. - function syncFieldsBetweenTabs( currentPageId ) { - var sourceIndex, targetIndex, sourceField, targetField; - - sourceIndex = currentPageId === 'find' ? 1 : 0; - targetIndex = 1 - sourceIndex; - var i, - l = fieldsMapping.length; - for ( i = 0; i < l; i++ ) { - sourceField = this.getContentElement( pages[ sourceIndex ], fieldsMapping[ i ][ sourceIndex ] ); - targetField = this.getContentElement( pages[ targetIndex ], fieldsMapping[ i ][ targetIndex ] ); - - targetField.setValue( sourceField.getValue() ); - } - } - - var findDialog = function( editor, startupPage ) { - // Style object for highlights: (#5018) - // 1. Defined as full match style to avoid compromising ordinary text color styles. - // 2. Must be apply onto inner-most text to avoid conflicting with ordinary text color styles visually. - var highlightStyle = new CKEDITOR.style( CKEDITOR.tools.extend({ - attributes: { 'data-cke-highlight':1 }, - fullMatch: 1, ignoreReadonly: 1, childRule: function() { - return 0; - } }, editor.config.find_highlight, true ) ); - - // Iterator which walk through the specified range char by char. By - // default the walking will not stop at the character boundaries, until - // the end of the range is encountered. - // @param { CKEDITOR.dom.range } range - // @param {Boolean} matchWord Whether the walking will stop at character boundary. - var characterWalker = function( range, matchWord ) { - var self = this; - var walker = new CKEDITOR.dom.walker( range ); - walker.guard = matchWord ? nonCharactersBoundary : function( node ) { - !nonCharactersBoundary( node ) && ( self._.matchBoundary = true ); - }; - walker[ 'evaluator' ] = findEvaluator; - walker.breakOnFalse = 1; - - if ( range.startContainer.type == CKEDITOR.NODE_TEXT ) { - this.textNode = range.startContainer; - this.offset = range.startOffset - 1; - } - - this._ = { - matchWord: matchWord, - walker: walker, - matchBoundary: false - }; - }; - - characterWalker.prototype = { - next: function() { - return this.move(); - }, - - back: function() { - return this.move( true ); - }, - - move: function( rtl ) { - var currentTextNode = this.textNode; - // Already at the end of document, no more character available. - if ( currentTextNode === null ) - return cursorStep.call( this ); - - this._.matchBoundary = false; - - // There are more characters in the text node, step forward. - if ( currentTextNode && rtl && this.offset > 0 ) { - this.offset--; - return cursorStep.call( this ); - } else if ( currentTextNode && this.offset < currentTextNode.getLength() - 1 ) { - this.offset++; - return cursorStep.call( this ); - } else { - currentTextNode = null; - // At the end of the text node, walking foward for the next. - while ( !currentTextNode ) { - currentTextNode = this._.walker[ rtl ? 'previous' : 'next' ].call( this._.walker ); - - // Stop searching if we're need full word match OR - // already reach document end. - if ( this._.matchWord && !currentTextNode || this._.walker._.end ) - break; - } - // Found a fresh text node. - this.textNode = currentTextNode; - if ( currentTextNode ) - this.offset = rtl ? currentTextNode.getLength() - 1 : 0; - else - this.offset = 0; - } - - return cursorStep.call( this ); - } - - }; - - /** - * A range of cursors which represent a trunk of characters which try to - * match, it has the same length as the pattern string. - * - * **Note:** This class isn't accessible from global scope. - * - * @private - * @class CKEDITOR.plugins.find.characterRange - * @constructor Creates a characterRange class instance. - */ - var characterRange = function( characterWalker, rangeLength ) { - this._ = { - walker: characterWalker, - cursors: [], - rangeLength: rangeLength, - highlightRange: null, - isMatched: 0 - }; - }; - - characterRange.prototype = { - /** - * Translate this range to {@link CKEDITOR.dom.range}. - */ - toDomRange: function() { - var range = editor.createRange(); - var cursors = this._.cursors; - if ( cursors.length < 1 ) { - var textNode = this._.walker.textNode; - if ( textNode ) - range.setStartAfter( textNode ); - else - return null; - } else { - var first = cursors[ 0 ], - last = cursors[ cursors.length - 1 ]; - - range.setStart( first.textNode, first.offset ); - range.setEnd( last.textNode, last.offset + 1 ); - } - - return range; - }, - - /** - * Reflect the latest changes from dom range. - */ - updateFromDomRange: function( domRange ) { - var cursor, - walker = new characterWalker( domRange ); - this._.cursors = []; - do { - cursor = walker.next(); - if ( cursor.character ) this._.cursors.push( cursor ); - } - while ( cursor.character ); - this._.rangeLength = this._.cursors.length; - }, - - setMatched: function() { - this._.isMatched = true; - }, - - clearMatched: function() { - this._.isMatched = false; - }, - - isMatched: function() { - return this._.isMatched; - }, - - /** - * Hightlight the current matched chunk of text. - */ - highlight: function() { - // Do not apply if nothing is found. - if ( this._.cursors.length < 1 ) - return; - - // Remove the previous highlight if there's one. - if ( this._.highlightRange ) - this.removeHighlight(); - - // Apply the highlight. - var range = this.toDomRange(), - bookmark = range.createBookmark(); - highlightStyle.applyToRange( range ); - range.moveToBookmark( bookmark ); - this._.highlightRange = range; - - // Scroll the editor to the highlighted area. - var element = range.startContainer; - if ( element.type != CKEDITOR.NODE_ELEMENT ) - element = element.getParent(); - element.scrollIntoView(); - - // Update the character cursors. - this.updateFromDomRange( range ); - }, - - /** - * Remove highlighted find result. - */ - removeHighlight: function() { - if ( !this._.highlightRange ) - return; - - var bookmark = this._.highlightRange.createBookmark(); - highlightStyle.removeFromRange( this._.highlightRange ); - this._.highlightRange.moveToBookmark( bookmark ); - this.updateFromDomRange( this._.highlightRange ); - this._.highlightRange = null; - }, - - isReadOnly: function() { - if ( !this._.highlightRange ) - return 0; - - return this._.highlightRange.startContainer.isReadOnly(); - }, - - moveBack: function() { - var retval = this._.walker.back(), - cursors = this._.cursors; - - if ( retval.hitMatchBoundary ) - this._.cursors = cursors = []; - - cursors.unshift( retval ); - if ( cursors.length > this._.rangeLength ) - cursors.pop(); - - return retval; - }, - - moveNext: function() { - var retval = this._.walker.next(), - cursors = this._.cursors; - - // Clear the cursors queue if we've crossed a match boundary. - if ( retval.hitMatchBoundary ) - this._.cursors = cursors = []; - - cursors.push( retval ); - if ( cursors.length > this._.rangeLength ) - cursors.shift(); - - return retval; - }, - - getEndCharacter: function() { - var cursors = this._.cursors; - if ( cursors.length < 1 ) - return null; - - return cursors[ cursors.length - 1 ].character; - }, - - getNextCharacterRange: function( maxLength ) { - var lastCursor, nextRangeWalker, - cursors = this._.cursors; - - if ( ( lastCursor = cursors[ cursors.length - 1 ] ) && lastCursor.textNode ) - nextRangeWalker = new characterWalker( getRangeAfterCursor( lastCursor ) ); - // In case it's an empty range (no cursors), figure out next range from walker (#4951). - else - nextRangeWalker = this._.walker; - - return new characterRange( nextRangeWalker, maxLength ); - }, - - getCursors: function() { - return this._.cursors; - } - }; - - - // The remaining document range after the character cursor. - function getRangeAfterCursor( cursor, inclusive ) { - var range = editor.createRange(); - range.setStart( cursor.textNode, ( inclusive ? cursor.offset : cursor.offset + 1 ) ); - range.setEndAt( editor.editable(), CKEDITOR.POSITION_BEFORE_END ); - return range; - } - - // The document range before the character cursor. - function getRangeBeforeCursor( cursor ) { - var range = editor.createRange(); - range.setStartAt( editor.editable(), CKEDITOR.POSITION_AFTER_START ); - range.setEnd( cursor.textNode, cursor.offset ); - return range; - } - - var KMP_NOMATCH = 0, - KMP_ADVANCED = 1, - KMP_MATCHED = 2; - - // Examination the occurrence of a word which implement KMP algorithm. - var kmpMatcher = function( pattern, ignoreCase ) { - var overlap = [ -1 ]; - if ( ignoreCase ) - pattern = pattern.toLowerCase(); - for ( var i = 0; i < pattern.length; i++ ) { - overlap.push( overlap[ i ] + 1 ); - while ( overlap[ i + 1 ] > 0 && pattern.charAt( i ) != pattern.charAt( overlap[ i + 1 ] - 1 ) ) - overlap[ i + 1 ] = overlap[ overlap[ i + 1 ] - 1 ] + 1; - } - - this._ = { - overlap: overlap, - state: 0, - ignoreCase: !!ignoreCase, - pattern: pattern - }; - }; - - kmpMatcher.prototype = { - feedCharacter: function( c ) { - if ( this._.ignoreCase ) - c = c.toLowerCase(); - - while ( true ) { - if ( c == this._.pattern.charAt( this._.state ) ) { - this._.state++; - if ( this._.state == this._.pattern.length ) { - this._.state = 0; - return KMP_MATCHED; - } - return KMP_ADVANCED; - } else if ( !this._.state ) - return KMP_NOMATCH; - else - this._.state = this._.overlap[ this._.state ]; - } - - return null; - }, - - reset: function() { - this._.state = 0; - } - }; - - var wordSeparatorRegex = /[.,"'?!;: \u0085\u00a0\u1680\u280e\u2028\u2029\u202f\u205f\u3000]/; - - var isWordSeparator = function( c ) { - if ( !c ) - return true; - var code = c.charCodeAt( 0 ); - return ( code >= 9 && code <= 0xd ) || ( code >= 0x2000 && code <= 0x200a ) || wordSeparatorRegex.test( c ); - }; - - var finder = { - searchRange: null, - matchRange: null, - find: function( pattern, matchCase, matchWord, matchCyclic, highlightMatched, cyclicRerun ) { - if ( !this.matchRange ) - this.matchRange = new characterRange( new characterWalker( this.searchRange ), pattern.length ); - else { - this.matchRange.removeHighlight(); - this.matchRange = this.matchRange.getNextCharacterRange( pattern.length ); - } - - var matcher = new kmpMatcher( pattern, !matchCase ), - matchState = KMP_NOMATCH, - character = '%'; - - while ( character !== null ) { - this.matchRange.moveNext(); - while ( ( character = this.matchRange.getEndCharacter() ) ) { - matchState = matcher.feedCharacter( character ); - if ( matchState == KMP_MATCHED ) - break; - if ( this.matchRange.moveNext().hitMatchBoundary ) - matcher.reset(); - } - - if ( matchState == KMP_MATCHED ) { - if ( matchWord ) { - var cursors = this.matchRange.getCursors(), - tail = cursors[ cursors.length - 1 ], - head = cursors[ 0 ]; - - var rangeBefore = getRangeBeforeCursor( head ), - rangeAfter = getRangeAfterCursor( tail ); - - // The word boundary checks requires to trim the text nodes. (#9036) - rangeBefore.trim(); - rangeAfter.trim(); - - var headWalker = new characterWalker( rangeBefore, true ), - tailWalker = new characterWalker( rangeAfter, true ); - - if ( !( isWordSeparator( headWalker.back().character ) && isWordSeparator( tailWalker.next().character ) ) ) - continue; - } - this.matchRange.setMatched(); - if ( highlightMatched !== false ) - this.matchRange.highlight(); - return true; - } - } - - this.matchRange.clearMatched(); - this.matchRange.removeHighlight(); - // Clear current session and restart with the default search - // range. - // Re-run the finding once for cyclic.(#3517) - if ( matchCyclic && !cyclicRerun ) { - this.searchRange = getSearchRange( 1 ); - this.matchRange = null; - return arguments.callee.apply( this, Array.prototype.slice.call( arguments ).concat( [ true ] ) ); - } - - return false; - }, - - // Record how much replacement occurred toward one replacing. - replaceCounter: 0, - - replace: function( dialog, pattern, newString, matchCase, matchWord, matchCyclic, isReplaceAll ) { - isReplace = 1; - - // Successiveness of current replace/find. - var result = 0; - - // 1. Perform the replace when there's already a match here. - // 2. Otherwise perform the find but don't replace it immediately. - if ( this.matchRange && this.matchRange.isMatched() && !this.matchRange._.isReplaced && !this.matchRange.isReadOnly() ) { - // Turn off highlight for a while when saving snapshots. - this.matchRange.removeHighlight(); - var domRange = this.matchRange.toDomRange(); - var text = editor.document.createText( newString ); - if ( !isReplaceAll ) { - // Save undo snaps before and after the replacement. - var selection = editor.getSelection(); - selection.selectRanges( [ domRange ] ); - editor.fire( 'saveSnapshot' ); - } - domRange.deleteContents(); - domRange.insertNode( text ); - if ( !isReplaceAll ) { - selection.selectRanges( [ domRange ] ); - editor.fire( 'saveSnapshot' ); - } - this.matchRange.updateFromDomRange( domRange ); - if ( !isReplaceAll ) - this.matchRange.highlight(); - this.matchRange._.isReplaced = true; - this.replaceCounter++; - result = 1; - } else - result = this.find( pattern, matchCase, matchWord, matchCyclic, !isReplaceAll ); - - isReplace = 0; - - return result; - } - }; - - // The range in which find/replace happened, receive from user - // selection prior. - function getSearchRange( isDefault ) { - var searchRange, - sel = editor.getSelection(), - editable = editor.editable(); - - if ( sel && !isDefault ) { - searchRange = sel.getRanges()[ 0 ].clone(); - searchRange.collapse( true ); - } else { - searchRange = editor.createRange(); - searchRange.setStartAt( editable, CKEDITOR.POSITION_AFTER_START ); - } - searchRange.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END ); - return searchRange; - } - - var lang = editor.lang.find; - return { - title: lang.title, - resizable: CKEDITOR.DIALOG_RESIZE_NONE, - minWidth: 350, - minHeight: 170, - buttons: [ - // Close button only. - CKEDITOR.dialog.cancelButton( editor, { - label: editor.lang.common.close - } ) - ], - contents: [ - { - id: 'find', - label: lang.find, - title: lang.find, - accessKey: '', - elements: [ - { - type: 'hbox', - widths: [ '230px', '90px' ], - children: [ - { - type: 'text', - id: 'txtFindFind', - label: lang.findWhat, - isChanged: false, - labelLayout: 'horizontal', - accessKey: 'F' - }, - { - type: 'button', - id: 'btnFind', - align: 'left', - style: 'width:100%', - label: lang.find, - onClick: function() { - var dialog = this.getDialog(); - if ( !finder.find( dialog.getValueOf( 'find', 'txtFindFind' ), dialog.getValueOf( 'find', 'txtFindCaseChk' ), dialog.getValueOf( 'find', 'txtFindWordChk' ), dialog.getValueOf( 'find', 'txtFindCyclic' ) ) ) - alert( lang.notFoundMsg ); - } - } - ] - }, - { - type: 'fieldset', - label: CKEDITOR.tools.htmlEncode( lang.findOptions ), - style: 'margin-top:29px', - children: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'checkbox', - id: 'txtFindCaseChk', - isChanged: false, - label: lang.matchCase - }, - { - type: 'checkbox', - id: 'txtFindWordChk', - isChanged: false, - label: lang.matchWord - }, - { - type: 'checkbox', - id: 'txtFindCyclic', - isChanged: false, - 'default': true, - label: lang.matchCyclic - } - ] - } - ] - } - ] - }, - { - id: 'replace', - label: lang.replace, - accessKey: 'M', - elements: [ - { - type: 'hbox', - widths: [ '230px', '90px' ], - children: [ - { - type: 'text', - id: 'txtFindReplace', - label: lang.findWhat, - isChanged: false, - labelLayout: 'horizontal', - accessKey: 'F' - }, - { - type: 'button', - id: 'btnFindReplace', - align: 'left', - style: 'width:100%', - label: lang.replace, - onClick: function() { - var dialog = this.getDialog(); - if ( !finder.replace( dialog, dialog.getValueOf( 'replace', 'txtFindReplace' ), dialog.getValueOf( 'replace', 'txtReplace' ), dialog.getValueOf( 'replace', 'txtReplaceCaseChk' ), dialog.getValueOf( 'replace', 'txtReplaceWordChk' ), dialog.getValueOf( 'replace', 'txtReplaceCyclic' ) ) ) - alert( lang.notFoundMsg ); - } - } - ] - }, - { - type: 'hbox', - widths: [ '230px', '90px' ], - children: [ - { - type: 'text', - id: 'txtReplace', - label: lang.replaceWith, - isChanged: false, - labelLayout: 'horizontal', - accessKey: 'R' - }, - { - type: 'button', - id: 'btnReplaceAll', - align: 'left', - style: 'width:100%', - label: lang.replaceAll, - isChanged: false, - onClick: function() { - var dialog = this.getDialog(); - var replaceNums; - - finder.replaceCounter = 0; - - // Scope to full document. - finder.searchRange = getSearchRange( 1 ); - if ( finder.matchRange ) { - finder.matchRange.removeHighlight(); - finder.matchRange = null; - } - editor.fire( 'saveSnapshot' ); - while ( finder.replace( dialog, dialog.getValueOf( 'replace', 'txtFindReplace' ), dialog.getValueOf( 'replace', 'txtReplace' ), dialog.getValueOf( 'replace', 'txtReplaceCaseChk' ), dialog.getValueOf( 'replace', 'txtReplaceWordChk' ), false, true ) ) { - /*jsl:pass*/ - } - - if ( finder.replaceCounter ) { - alert( lang.replaceSuccessMsg.replace( /%1/, finder.replaceCounter ) ); - editor.fire( 'saveSnapshot' ); - } else - alert( lang.notFoundMsg ); - } - } - ] - }, - { - type: 'fieldset', - label: CKEDITOR.tools.htmlEncode( lang.findOptions ), - children: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'checkbox', - id: 'txtReplaceCaseChk', - isChanged: false, - label: lang.matchCase - }, - { - type: 'checkbox', - id: 'txtReplaceWordChk', - isChanged: false, - label: lang.matchWord - }, - { - type: 'checkbox', - id: 'txtReplaceCyclic', - isChanged: false, - 'default': true, - label: lang.matchCyclic - } - ] - } - ] - } - ] - } - ], - onLoad: function() { - var dialog = this; - - // Keep track of the current pattern field in use. - var patternField, wholeWordChkField; - - // Ignore initial page select on dialog show - var isUserSelect = 0; - this.on( 'hide', function() { - isUserSelect = 0; - }); - this.on( 'show', function() { - isUserSelect = 1; - }); - - this.selectPage = CKEDITOR.tools.override( this.selectPage, function( originalFunc ) { - return function( pageId ) { - originalFunc.call( dialog, pageId ); - - var currPage = dialog._.tabs[ pageId ]; - var patternFieldInput, patternFieldId, wholeWordChkFieldId; - patternFieldId = pageId === 'find' ? 'txtFindFind' : 'txtFindReplace'; - wholeWordChkFieldId = pageId === 'find' ? 'txtFindWordChk' : 'txtReplaceWordChk'; - - patternField = dialog.getContentElement( pageId, patternFieldId ); - wholeWordChkField = dialog.getContentElement( pageId, wholeWordChkFieldId ); - - // Prepare for check pattern text filed 'keyup' event - if ( !currPage.initialized ) { - patternFieldInput = CKEDITOR.document.getById( patternField._.inputId ); - currPage.initialized = true; - } - - // Synchronize fields on tab switch. - if ( isUserSelect ) - syncFieldsBetweenTabs.call( this, pageId ); - }; - }); - - }, - onShow: function() { - // Establish initial searching start position. - finder.searchRange = getSearchRange(); - - // Fill in the find field with selected text. - var selectedText = this.getParentEditor().getSelection().getSelectedText(), - patternFieldId = ( startupPage == 'find' ? 'txtFindFind' : 'txtFindReplace' ); - - var field = this.getContentElement( startupPage, patternFieldId ); - field.setValue( selectedText ); - field.select(); - - this.selectPage( startupPage ); - - this[ ( startupPage == 'find' && this._.editor.readOnly ? 'hide' : 'show' ) + 'Page' ]( 'replace' ); - }, - onHide: function() { - var range; - if ( finder.matchRange && finder.matchRange.isMatched() ) { - finder.matchRange.removeHighlight(); - editor.focus(); - - range = finder.matchRange.toDomRange(); - if ( range ) - editor.getSelection().selectRanges( [ range ] ); - } - - // Clear current session before dialog close - delete finder.matchRange; - }, - onFocus: function() { - if ( startupPage == 'replace' ) - return this.getContentElement( 'replace', 'txtFindReplace' ); - else - return this.getContentElement( 'find', 'txtFindFind' ); - } - }; - }; - - CKEDITOR.dialog.add( 'find', function( editor ) { - return findDialog( editor, 'find' ); - }); - - CKEDITOR.dialog.add( 'replace', function( editor ) { - return findDialog( editor, 'replace' ); - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/find-rtl.png b/addons/website/static/lib/ckeditor/plugins/find/icons/find-rtl.png Binary files differdeleted file mode 100644 index 02f40cb2f99..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/find-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/find.png b/addons/website/static/lib/ckeditor/plugins/find/icons/find.png Binary files differdeleted file mode 100644 index 02f40cb2f99..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/find.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find-rtl.png b/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find-rtl.png Binary files differdeleted file mode 100644 index cbf9ced23a0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find.png b/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find.png Binary files differdeleted file mode 100644 index cbf9ced23a0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/find.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/replace.png b/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/replace.png Binary files differdeleted file mode 100644 index 9efd8bbdd99..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/hidpi/replace.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/icons/replace.png b/addons/website/static/lib/ckeditor/plugins/find/icons/replace.png Binary files differdeleted file mode 100644 index e68afcbe204..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/icons/replace.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/find/lang/en.js b/addons/website/static/lib/ckeditor/plugins/find/lang/en.js deleted file mode 100644 index 383654895a3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/lang/en.js +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'find', 'en', { - find: 'Find', - findOptions: 'Find Options', - findWhat: 'Find what:', - matchCase: 'Match case', - matchCyclic: 'Match cyclic', - matchWord: 'Match whole word', - notFoundMsg: 'The specified text was not found.', - replace: 'Replace', - replaceAll: 'Replace All', - replaceSuccessMsg: '%1 occurrence(s) replaced.', - replaceWith: 'Replace with:', - title: 'Find and Replace' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/find/plugin.js b/addons/website/static/lib/ckeditor/plugins/find/plugin.js deleted file mode 100755 index a1ad9f88114..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/find/plugin.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'find', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'find,find-rtl,replace', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var findCommand = editor.addCommand( 'find', new CKEDITOR.dialogCommand( 'find' ) ); - findCommand.canUndo = false; - findCommand.readOnly = 1; - - var replaceCommand = editor.addCommand( 'replace', new CKEDITOR.dialogCommand( 'replace' ) ); - replaceCommand.canUndo = false; - - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Find', { - label: editor.lang.find.find, - command: 'find', - toolbar: 'find,10' - }); - - editor.ui.addButton( 'Replace', { - label: editor.lang.find.replace, - command: 'replace', - toolbar: 'find,20' - }); - } - - CKEDITOR.dialog.add( 'find', this.path + 'dialogs/find.js' ); - CKEDITOR.dialog.add( 'replace', this.path + 'dialogs/find.js' ); - } -}); - -/** - * Defines the style to be used to highlight results with the find dialog. - * - * // Highlight search results with blue on yellow. - * config.find_highlight = { - * element: 'span', - * styles: { 'background-color': '#ff0', color: '#00f' } - * }; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.find_highlight = { - element: 'span', styles: { 'background-color': '#004', color: '#fff' } }; diff --git a/addons/website/static/lib/ckeditor/plugins/flash/dialogs/flash.js b/addons/website/static/lib/ckeditor/plugins/flash/dialogs/flash.js deleted file mode 100644 index 083097cb4d6..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/flash/dialogs/flash.js +++ /dev/null @@ -1,668 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - // It is possible to set things in three different places. - // 1. As attributes in the object tag. - // 2. As param tags under the object tag. - // 3. As attributes in the embed tag. - // It is possible for a single attribute to be present in more than one place. - // So let's define a mapping between a sementic attribute and its syntactic - // equivalents. - // Then we'll set and retrieve attribute values according to the mapping, - // instead of having to check and set each syntactic attribute every time. - // - // Reference: http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_12701 - var ATTRTYPE_OBJECT = 1, - ATTRTYPE_PARAM = 2, - ATTRTYPE_EMBED = 4; - - var attributesMap = { - id: [ { - type: ATTRTYPE_OBJECT, name: 'id' - }], - classid: [ { - type: ATTRTYPE_OBJECT, name: 'classid' - }], - codebase: [ { - type: ATTRTYPE_OBJECT, name: 'codebase' - }], - pluginspage: [ { - type: ATTRTYPE_EMBED, name: 'pluginspage' - }], - src: [ { - type: ATTRTYPE_PARAM, name: 'movie' - }, { - type: ATTRTYPE_EMBED, name: 'src' - }, { - type: ATTRTYPE_OBJECT, name: 'data' - }], - name: [ { - type: ATTRTYPE_EMBED, name: 'name' - }], - align: [ { - type: ATTRTYPE_OBJECT, name: 'align' - }], - 'class': [ { - type: ATTRTYPE_OBJECT, name: 'class' - }, { - type: ATTRTYPE_EMBED, name: 'class' - }], - width: [ { - type: ATTRTYPE_OBJECT, name: 'width' - }, { - type: ATTRTYPE_EMBED, name: 'width' - }], - height: [ { - type: ATTRTYPE_OBJECT, name: 'height' - }, { - type: ATTRTYPE_EMBED, name: 'height' - }], - hSpace: [ { - type: ATTRTYPE_OBJECT, name: 'hSpace' - }, { - type: ATTRTYPE_EMBED, name: 'hSpace' - }], - vSpace: [ { - type: ATTRTYPE_OBJECT, name: 'vSpace' - }, { - type: ATTRTYPE_EMBED, name: 'vSpace' - }], - style: [ { - type: ATTRTYPE_OBJECT, name: 'style' - }, { - type: ATTRTYPE_EMBED, name: 'style' - }], - type: [ { - type: ATTRTYPE_EMBED, name: 'type' - }] - }; - - var names = [ 'play', 'loop', 'menu', 'quality', 'scale', 'salign', 'wmode', 'bgcolor', 'base', 'flashvars', 'allowScriptAccess', 'allowFullScreen' ]; - for ( var i = 0; i < names.length; i++ ) - attributesMap[ names[ i ] ] = [ { - type: ATTRTYPE_EMBED, name: names[ i ] - }, { - type: ATTRTYPE_PARAM, name: names[ i ] - }]; - names = [ 'allowFullScreen', 'play', 'loop', 'menu' ]; - for ( i = 0; i < names.length; i++ ) - attributesMap[ names[ i ] ][ 0 ][ 'default' ] = attributesMap[ names[ i ] ][ 1 ][ 'default' ] = true; - - var defaultToPixel = CKEDITOR.tools.cssLength; - - function loadValue( objectNode, embedNode, paramMap ) { - var attributes = attributesMap[ this.id ]; - if ( !attributes ) - return; - - var isCheckbox = ( this instanceof CKEDITOR.ui.dialog.checkbox ); - for ( var i = 0; i < attributes.length; i++ ) { - var attrDef = attributes[ i ]; - switch ( attrDef.type ) { - case ATTRTYPE_OBJECT: - if ( !objectNode ) - continue; - if ( objectNode.getAttribute( attrDef.name ) !== null ) { - var value = objectNode.getAttribute( attrDef.name ); - if ( isCheckbox ) - this.setValue( value.toLowerCase() == 'true' ); - else - this.setValue( value ); - return; - } else if ( isCheckbox ) - this.setValue( !!attrDef[ 'default' ] ); - break; - case ATTRTYPE_PARAM: - if ( !objectNode ) - continue; - if ( attrDef.name in paramMap ) { - value = paramMap[ attrDef.name ]; - if ( isCheckbox ) - this.setValue( value.toLowerCase() == 'true' ); - else - this.setValue( value ); - return; - } else if ( isCheckbox ) - this.setValue( !!attrDef[ 'default' ] ); - break; - case ATTRTYPE_EMBED: - if ( !embedNode ) - continue; - if ( embedNode.getAttribute( attrDef.name ) ) { - value = embedNode.getAttribute( attrDef.name ); - if ( isCheckbox ) - this.setValue( value.toLowerCase() == 'true' ); - else - this.setValue( value ); - return; - } else if ( isCheckbox ) - this.setValue( !!attrDef[ 'default' ] ); - } - } - } - - function commitValue( objectNode, embedNode, paramMap ) { - var attributes = attributesMap[ this.id ]; - if ( !attributes ) - return; - - var isRemove = ( this.getValue() === '' ), - isCheckbox = ( this instanceof CKEDITOR.ui.dialog.checkbox ); - - for ( var i = 0; i < attributes.length; i++ ) { - var attrDef = attributes[ i ]; - switch ( attrDef.type ) { - case ATTRTYPE_OBJECT: - // Avoid applying the data attribute when not needed (#7733) - if ( !objectNode || ( attrDef.name == 'data' && embedNode && !objectNode.hasAttribute( 'data' ) ) ) - continue; - var value = this.getValue(); - if ( isRemove || isCheckbox && value === attrDef[ 'default' ] ) - objectNode.removeAttribute( attrDef.name ); - else - objectNode.setAttribute( attrDef.name, value ); - break; - case ATTRTYPE_PARAM: - if ( !objectNode ) - continue; - value = this.getValue(); - if ( isRemove || isCheckbox && value === attrDef[ 'default' ] ) { - if ( attrDef.name in paramMap ) - paramMap[ attrDef.name ].remove(); - } else { - if ( attrDef.name in paramMap ) - paramMap[ attrDef.name ].setAttribute( 'value', value ); - else { - var param = CKEDITOR.dom.element.createFromHtml( '<cke:param></cke:param>', objectNode.getDocument() ); - param.setAttributes({ name: attrDef.name, value: value } ); - if ( objectNode.getChildCount() < 1 ) - param.appendTo( objectNode ); - else - param.insertBefore( objectNode.getFirst() ); - } - } - break; - case ATTRTYPE_EMBED: - if ( !embedNode ) - continue; - value = this.getValue(); - if ( isRemove || isCheckbox && value === attrDef[ 'default' ] ) - embedNode.removeAttribute( attrDef.name ); - else - embedNode.setAttribute( attrDef.name, value ); - } - } - } - - CKEDITOR.dialog.add( 'flash', function( editor ) { - var makeObjectTag = !editor.config.flashEmbedTagOnly, - makeEmbedTag = editor.config.flashAddEmbedTag || editor.config.flashEmbedTagOnly; - - var previewPreloader, - previewAreaHtml = '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) + '<br>' + - '<div id="cke_FlashPreviewLoader' + CKEDITOR.tools.getNextNumber() + '" style="display:none"><div class="loading"> </div></div>' + - '<div id="cke_FlashPreviewBox' + CKEDITOR.tools.getNextNumber() + '" class="FlashPreviewBox"></div></div>'; - - return { - title: editor.lang.flash.title, - minWidth: 420, - minHeight: 310, - onShow: function() { - // Clear previously saved elements. - this.fakeImage = this.objectNode = this.embedNode = null; - previewPreloader = new CKEDITOR.dom.element( 'embed', editor.document ); - - // Try to detect any embed or object tag that has Flash parameters. - var fakeImage = this.getSelectedElement(); - if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'flash' ) { - this.fakeImage = fakeImage; - - var realElement = editor.restoreRealElement( fakeImage ), - objectNode = null, - embedNode = null, - paramMap = {}; - if ( realElement.getName() == 'cke:object' ) { - objectNode = realElement; - var embedList = objectNode.getElementsByTag( 'embed', 'cke' ); - if ( embedList.count() > 0 ) - embedNode = embedList.getItem( 0 ); - var paramList = objectNode.getElementsByTag( 'param', 'cke' ); - for ( var i = 0, length = paramList.count(); i < length; i++ ) { - var item = paramList.getItem( i ), - name = item.getAttribute( 'name' ), - value = item.getAttribute( 'value' ); - paramMap[ name ] = value; - } - } else if ( realElement.getName() == 'cke:embed' ) - embedNode = realElement; - - this.objectNode = objectNode; - this.embedNode = embedNode; - - this.setupContent( objectNode, embedNode, paramMap, fakeImage ); - } - }, - onOk: function() { - // If there's no selected object or embed, create one. Otherwise, reuse the - // selected object and embed nodes. - var objectNode = null, - embedNode = null, - paramMap = null; - if ( !this.fakeImage ) { - if ( makeObjectTag ) { - objectNode = CKEDITOR.dom.element.createFromHtml( '<cke:object></cke:object>', editor.document ); - var attributes = { - classid: 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000', - codebase: 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0' - }; - objectNode.setAttributes( attributes ); - } - if ( makeEmbedTag ) { - embedNode = CKEDITOR.dom.element.createFromHtml( '<cke:embed></cke:embed>', editor.document ); - embedNode.setAttributes({ - type: 'application/x-shockwave-flash', - pluginspage: 'http://www.macromedia.com/go/getflashplayer' - }); - if ( objectNode ) - embedNode.appendTo( objectNode ); - } - } else { - objectNode = this.objectNode; - embedNode = this.embedNode; - } - - // Produce the paramMap if there's an object tag. - if ( objectNode ) { - paramMap = {}; - var paramList = objectNode.getElementsByTag( 'param', 'cke' ); - for ( var i = 0, length = paramList.count(); i < length; i++ ) - paramMap[ paramList.getItem( i ).getAttribute( 'name' ) ] = paramList.getItem( i ); - } - - // A subset of the specified attributes/styles - // should also be applied on the fake element to - // have better visual effect. (#5240) - var extraStyles = {}, - extraAttributes = {}; - this.commitContent( objectNode, embedNode, paramMap, extraStyles, extraAttributes ); - - // Refresh the fake image. - var newFakeImage = editor.createFakeElement( objectNode || embedNode, 'cke_flash', 'flash', true ); - newFakeImage.setAttributes( extraAttributes ); - newFakeImage.setStyles( extraStyles ); - if ( this.fakeImage ) { - newFakeImage.replace( this.fakeImage ); - editor.getSelection().selectElement( newFakeImage ); - } else - editor.insertElement( newFakeImage ); - }, - - onHide: function() { - if ( this.preview ) - this.preview.setHtml( '' ); - }, - - contents: [ - { - id: 'info', - label: editor.lang.common.generalTab, - accessKey: 'I', - elements: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'hbox', - widths: [ '280px', '110px' ], - align: 'right', - children: [ - { - id: 'src', - type: 'text', - label: editor.lang.common.url, - required: true, - validate: CKEDITOR.dialog.validate.notEmpty( editor.lang.flash.validateSrc ), - setup: loadValue, - commit: commitValue, - onLoad: function() { - var dialog = this.getDialog(), - updatePreview = function( src ) { - // Query the preloader to figure out the url impacted by based href. - previewPreloader.setAttribute( 'src', src ); - dialog.preview.setHtml( '<embed height="100%" width="100%" src="' + CKEDITOR.tools.htmlEncode( previewPreloader.getAttribute( 'src' ) ) - + '" type="application/x-shockwave-flash"></embed>' ); - }; - // Preview element - dialog.preview = dialog.getContentElement( 'info', 'preview' ).getElement().getChild( 3 ); - - // Sync on inital value loaded. - this.on( 'change', function( evt ) { - - if ( evt.data && evt.data.value ) - updatePreview( evt.data.value ); - }); - // Sync when input value changed. - this.getInputElement().on( 'change', function( evt ) { - - updatePreview( this.getValue() ); - }, this ); - } - }, - { - type: 'button', - id: 'browse', - filebrowser: 'info:src', - hidden: true, - // v-align with the 'src' field. - // TODO: We need something better than a fixed size here. - style: 'display:inline-block;margin-top:10px;', - label: editor.lang.common.browseServer - } - ] - } - ] - }, - { - type: 'hbox', - widths: [ '25%', '25%', '25%', '25%', '25%' ], - children: [ - { - type: 'text', - id: 'width', - requiredContent: 'embed[width]', - style: 'width:95px', - label: editor.lang.common.width, - validate: CKEDITOR.dialog.validate.htmlLength( editor.lang.common.invalidHtmlLength.replace( '%1', editor.lang.common.width ) ), - setup: loadValue, - commit: commitValue - }, - { - type: 'text', - id: 'height', - requiredContent: 'embed[height]', - style: 'width:95px', - label: editor.lang.common.height, - validate: CKEDITOR.dialog.validate.htmlLength( editor.lang.common.invalidHtmlLength.replace( '%1', editor.lang.common.height ) ), - setup: loadValue, - commit: commitValue - }, - { - type: 'text', - id: 'hSpace', - requiredContent: 'embed[hspace]', - style: 'width:95px', - label: editor.lang.flash.hSpace, - validate: CKEDITOR.dialog.validate.integer( editor.lang.flash.validateHSpace ), - setup: loadValue, - commit: commitValue - }, - { - type: 'text', - id: 'vSpace', - requiredContent: 'embed[vspace]', - style: 'width:95px', - label: editor.lang.flash.vSpace, - validate: CKEDITOR.dialog.validate.integer( editor.lang.flash.validateVSpace ), - setup: loadValue, - commit: commitValue - } - ] - }, - - { - type: 'vbox', - children: [ - { - type: 'html', - id: 'preview', - style: 'width:95%;', - html: previewAreaHtml - } - ] - } - ] - }, - { - id: 'Upload', - hidden: true, - filebrowser: 'uploadButton', - label: editor.lang.common.upload, - elements: [ - { - type: 'file', - id: 'upload', - label: editor.lang.common.upload, - size: 38 - }, - { - type: 'fileButton', - id: 'uploadButton', - label: editor.lang.common.uploadSubmit, - filebrowser: 'info:src', - 'for': [ 'Upload', 'upload' ] - } - ] - }, - { - id: 'properties', - label: editor.lang.flash.propertiesTab, - elements: [ - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'scale', - type: 'select', - requiredContent: 'embed[scale]', - label: editor.lang.flash.scale, - 'default': '', - style: 'width : 100%;', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.flash.scaleAll, 'showall' ], - [ editor.lang.flash.scaleNoBorder, 'noborder' ], - [ editor.lang.flash.scaleFit, 'exactfit' ] - ], - setup: loadValue, - commit: commitValue - }, - { - id: 'allowScriptAccess', - type: 'select', - requiredContent: 'embed[allowscriptaccess]', - label: editor.lang.flash.access, - 'default': '', - style: 'width : 100%;', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.flash.accessAlways, 'always' ], - [ editor.lang.flash.accessSameDomain, 'samedomain' ], - [ editor.lang.flash.accessNever, 'never' ] - ], - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'wmode', - type: 'select', - requiredContent: 'embed[wmode]', - label: editor.lang.flash.windowMode, - 'default': '', - style: 'width : 100%;', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.flash.windowModeWindow, 'window' ], - [ editor.lang.flash.windowModeOpaque, 'opaque' ], - [ editor.lang.flash.windowModeTransparent, 'transparent' ] - ], - setup: loadValue, - commit: commitValue - }, - { - id: 'quality', - type: 'select', - requiredContent: 'embed[quality]', - label: editor.lang.flash.quality, - 'default': 'high', - style: 'width : 100%;', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.flash.qualityBest, 'best' ], - [ editor.lang.flash.qualityHigh, 'high' ], - [ editor.lang.flash.qualityAutoHigh, 'autohigh' ], - [ editor.lang.flash.qualityMedium, 'medium' ], - [ editor.lang.flash.qualityAutoLow, 'autolow' ], - [ editor.lang.flash.qualityLow, 'low' ] - ], - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'align', - type: 'select', - requiredContent: 'object[align]', - label: editor.lang.common.align, - 'default': '', - style: 'width : 100%;', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.alignLeft, 'left' ], - [ editor.lang.flash.alignAbsBottom, 'absBottom' ], - [ editor.lang.flash.alignAbsMiddle, 'absMiddle' ], - [ editor.lang.flash.alignBaseline, 'baseline' ], - [ editor.lang.common.alignBottom, 'bottom' ], - [ editor.lang.common.alignMiddle, 'middle' ], - [ editor.lang.common.alignRight, 'right' ], - [ editor.lang.flash.alignTextTop, 'textTop' ], - [ editor.lang.common.alignTop, 'top' ] - ], - setup: loadValue, - commit: function( objectNode, embedNode, paramMap, extraStyles, extraAttributes ) { - var value = this.getValue(); - commitValue.apply( this, arguments ); - value && ( extraAttributes.align = value ); - } - }, - { - type: 'html', - html: '<div></div>' - } - ] - }, - { - type: 'fieldset', - label: CKEDITOR.tools.htmlEncode( editor.lang.flash.flashvars ), - children: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'checkbox', - id: 'menu', - label: editor.lang.flash.chkMenu, - 'default': true, - setup: loadValue, - commit: commitValue - }, - { - type: 'checkbox', - id: 'play', - label: editor.lang.flash.chkPlay, - 'default': true, - setup: loadValue, - commit: commitValue - }, - { - type: 'checkbox', - id: 'loop', - label: editor.lang.flash.chkLoop, - 'default': true, - setup: loadValue, - commit: commitValue - }, - { - type: 'checkbox', - id: 'allowFullScreen', - label: editor.lang.flash.chkFull, - 'default': true, - setup: loadValue, - commit: commitValue - } - ] - } - ] - } - ] - }, - { - id: 'advanced', - label: editor.lang.common.advancedTab, - elements: [ - { - type: 'hbox', - children: [ - { - type: 'text', - id: 'id', - requiredContent: 'object[id]', - label: editor.lang.common.id, - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - type: 'text', - id: 'bgcolor', - requiredContent: 'embed[bgcolor]', - label: editor.lang.flash.bgcolor, - setup: loadValue, - commit: commitValue - }, - { - type: 'text', - id: 'class', - requiredContent: 'embed(cke-xyz)', // Random text like 'xyz' will check if all are allowed. - label: editor.lang.common.cssClass, - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'text', - id: 'style', - requiredContent: 'embed{cke-xyz}', // Random text like 'xyz' will check if all are allowed. - validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ), - label: editor.lang.common.cssStyle, - setup: loadValue, - commit: commitValue - } - ] - } - ] - }; - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/flash/icons/flash.png b/addons/website/static/lib/ckeditor/plugins/flash/icons/flash.png Binary files differdeleted file mode 100644 index df7b1c60bc2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/flash/icons/flash.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/flash/icons/hidpi/flash.png b/addons/website/static/lib/ckeditor/plugins/flash/icons/hidpi/flash.png Binary files differdeleted file mode 100644 index 7ad0e388924..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/flash/icons/hidpi/flash.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/flash/lang/en.js b/addons/website/static/lib/ckeditor/plugins/flash/lang/en.js deleted file mode 100644 index c228ddb5116..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/flash/lang/en.js +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'flash', 'en', { - access: 'Script Access', - accessAlways: 'Always', - accessNever: 'Never', - accessSameDomain: 'Same domain', - alignAbsBottom: 'Abs Bottom', - alignAbsMiddle: 'Abs Middle', - alignBaseline: 'Baseline', - alignTextTop: 'Text Top', - bgcolor: 'Background color', - chkFull: 'Allow Fullscreen', - chkLoop: 'Loop', - chkMenu: 'Enable Flash Menu', - chkPlay: 'Auto Play', - flashvars: 'Variables for Flash', - hSpace: 'HSpace', - properties: 'Flash Properties', - propertiesTab: 'Properties', - quality: 'Quality', - qualityAutoHigh: 'Auto High', - qualityAutoLow: 'Auto Low', - qualityBest: 'Best', - qualityHigh: 'High', - qualityLow: 'Low', - qualityMedium: 'Medium', - scale: 'Scale', - scaleAll: 'Show all', - scaleFit: 'Exact Fit', - scaleNoBorder: 'No Border', - title: 'Flash Properties', - vSpace: 'VSpace', - validateHSpace: 'HSpace must be a number.', - validateSrc: 'URL must not be empty.', - validateVSpace: 'VSpace must be a number.', - windowMode: 'Window mode', - windowModeOpaque: 'Opaque', - windowModeTransparent: 'Transparent', - windowModeWindow: 'Window' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/flash/plugin.js b/addons/website/static/lib/ckeditor/plugins/flash/plugin.js deleted file mode 100644 index ad0556d8392..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/flash/plugin.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var flashFilenameRegex = /\.swf(?:$|\?)/i; - - function isFlashEmbed( element ) { - var attributes = element.attributes; - - return ( attributes.type == 'application/x-shockwave-flash' || flashFilenameRegex.test( attributes.src || '' ) ); - } - - function createFakeElement( editor, realElement ) { - return editor.createFakeParserElement( realElement, 'cke_flash', 'flash', true ); - } - - CKEDITOR.plugins.add( 'flash', { - requires: 'dialog,fakeobjects', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'flash', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - CKEDITOR.addCss( 'img.cke_flash' + - '{' + - 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/placeholder.png' ) + ');' + - 'background-position: center center;' + - 'background-repeat: no-repeat;' + - 'border: 1px solid #a9a9a9;' + - 'width: 80px;' + - 'height: 80px;' + - '}' - ); - - }, - init: function( editor ) { - var allowed = 'object[classid,codebase,height,hspace,vspace,width];' + - 'param[name,value];' + - 'embed[height,hspace,pluginspage,src,type,vspace,width]'; - - if ( CKEDITOR.dialog.isTabEnabled( editor, 'flash', 'properties' ) ) - allowed += ';object[align]; embed[allowscriptaccess,quality,scale,wmode]'; - if ( CKEDITOR.dialog.isTabEnabled( editor, 'flash', 'advanced' ) ) - allowed += ';object[id]{*}; embed[bgcolor]{*}(*)'; - - editor.addCommand( 'flash', new CKEDITOR.dialogCommand( 'flash', { - allowedContent: allowed, - requiredContent: 'embed' - } ) ); - editor.ui.addButton && editor.ui.addButton( 'Flash', { - label: editor.lang.common.flash, - command: 'flash', - toolbar: 'insert,20' - }); - CKEDITOR.dialog.add( 'flash', this.path + 'dialogs/flash.js' ); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - editor.addMenuItems({ - flash: { - label: editor.lang.flash.properties, - command: 'flash', - group: 'flash' - } - }); - } - - editor.on( 'doubleclick', function( evt ) { - var element = evt.data.element; - - if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'flash' ) - evt.data.dialog = 'flash'; - }); - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - if ( element && element.is( 'img' ) && !element.isReadOnly() && element.data( 'cke-real-element-type' ) == 'flash' ) - return { flash: CKEDITOR.TRISTATE_OFF }; - }); - } - }, - - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter; - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - 'cke:object': function( element ) { - var attributes = element.attributes, - classId = attributes.classid && String( attributes.classid ).toLowerCase(); - - if ( !classId && !isFlashEmbed( element ) ) { - // Look for the inner <embed> - for ( var i = 0; i < element.children.length; i++ ) { - if ( element.children[ i ].name == 'cke:embed' ) { - if ( !isFlashEmbed( element.children[ i ] ) ) - return null; - - return createFakeElement( editor, element ); - } - } - return null; - } - - return createFakeElement( editor, element ); - }, - - 'cke:embed': function( element ) { - if ( !isFlashEmbed( element ) ) - return null; - - return createFakeElement( editor, element ); - } - } - }, 5 ); - } - } - }); -})(); - -CKEDITOR.tools.extend( CKEDITOR.config, { - /** - * Save as `<embed>` tag only. This tag is unrecommended. - * - * @cfg {Boolean} [flashEmbedTagOnly=false] - * @member CKEDITOR.config - */ - flashEmbedTagOnly: false, - - /** - * Add `<embed>` tag as alternative: `<object><embed></embed></object>`. - * - * @cfg {Boolean} [flashAddEmbedTag=false] - * @member CKEDITOR.config - */ - flashAddEmbedTag: true, - - /** - * Use {@link #flashEmbedTagOnly} and {@link #flashAddEmbedTag} values on edit. - * - * @cfg {Boolean} [flashConvertOnEdit=false] - * @member CKEDITOR.config - */ - flashConvertOnEdit: false -}); diff --git a/addons/website/static/lib/ckeditor/plugins/floatingspace/plugin.js b/addons/website/static/lib/ckeditor/plugins/floatingspace/plugin.js deleted file mode 100644 index 328d5aaf311..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/floatingspace/plugin.js +++ /dev/null @@ -1,376 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var floatSpaceTpl = CKEDITOR.addTemplate( 'floatcontainer', '<div' + - ' id="cke_{name}"' + - ' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_float cke_{langDir} ' + CKEDITOR.env.cssClass + '"' + - ' dir="{langDir}"' + - ' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' + - ' lang="{langCode}"' + - ' role="application"' + - ' style="{style}"' + - '>' + - '<div class="cke_inner">' + - '<div id="{topId}" class="cke_top" role="presentation">{content}</div>' + - '</div>' + - '</div>' ), - win = CKEDITOR.document.getWindow(), - pixelate = CKEDITOR.tools.cssLength; - - CKEDITOR.plugins.add( 'floatingspace', { - init: function( editor ) { - // Add listener with lower priority than that in themedui creator. - // Thereby floatingspace will be created only if themedui wasn't used. - editor.on( 'loaded', function() { - attach( this ); - }, null, null, 20 ); - } - } ); - - function scrollOffset( side ) { - var pageOffset = side == 'left' ? 'pageXOffset' : 'pageYOffset', - docScrollOffset = side == 'left' ? 'scrollLeft' : 'scrollTop'; - - return ( pageOffset in win.$ ) ? - win.$[ pageOffset ] - : - CKEDITOR.document.$.documentElement[ docScrollOffset ]; - } - - function attach( editor ) { - var config = editor.config, - - // Get the HTML for the predefined spaces. - topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html, - - // Re-positioning of the space. - layout = (function() { - // Mode indicates the vertical aligning mode. - var mode, editable, - spaceRect, editorRect, viewRect, spaceHeight, pageScrollX, - - // Allow minor adjustments of the float space from custom configs. - dockedOffsetX = config.floatSpaceDockedOffsetX || 0, - dockedOffsetY = config.floatSpaceDockedOffsetY || 0, - pinnedOffsetX = config.floatSpacePinnedOffsetX || 0, - pinnedOffsetY = config.floatSpacePinnedOffsetY || 0; - - // Update the float space position. - function updatePos( pos, prop, val ) { - floatSpace.setStyle( prop, pixelate( val ) ); - floatSpace.setStyle( 'position', pos ); - } - - // Change the current mode and update float space position accordingly. - function changeMode( newMode ) { - var editorPos = editable.getDocumentPosition(); - - switch ( newMode ) { - case 'top': - updatePos( 'absolute', 'top', editorPos.y - spaceHeight - dockedOffsetY ); - break; - case 'pin': - updatePos( 'fixed', 'top', pinnedOffsetY ); - break; - case 'bottom': - updatePos( 'absolute', 'top', editorPos.y + ( editorRect.height || editorRect.bottom - editorRect.top ) + dockedOffsetY ); - break; - } - - mode = newMode; - } - - return function( evt ) { - // #10112 Do not fail on editable-less editor. - if ( !( editable = editor.editable() ) ) - return; - - // Show up the space on focus gain. - evt && evt.name == 'focus' && floatSpace.show(); - - // Reset the horizontal position for below measurement. - floatSpace.removeStyle( 'left' ); - floatSpace.removeStyle( 'right' ); - - // Compute the screen position from the TextRectangle object would - // be very simple, even though the "width"/"height" property is not - // available for all, it's safe to figure that out from the rest. - - // http://help.dottoro.com/ljgupwlp.php - spaceRect = floatSpace.getClientRect(); - editorRect = editable.getClientRect(); - viewRect = win.getViewPaneSize(); - spaceHeight = spaceRect.height; - pageScrollX = scrollOffset( 'left' ); - - // We initialize it as pin mode. - if ( !mode ) { - mode = 'pin'; - changeMode( 'pin' ); - // Call for a refresh to the actual layout. - layout( evt ); - return; - } - - // +------------------------ Viewport -+ \ - // | | |-> floatSpaceDockedOffsetY - // | ................................. | / - // | | - // | +------ Space -+ | - // | | | | - // | +--------------+ | - // | +------------------ Editor -+ | - // | | | | - // - if ( spaceHeight + dockedOffsetY <= editorRect.top ) - changeMode( 'top' ); - - // +- - - - - - - - - Editor -+ - // | | - // +------------------------ Viewport -+ \ - // | | | | |-> floatSpacePinnedOffsetY - // | ................................. | / - // | +------ Space -+ | | - // | | | | | - // | +--------------+ | | - // | | | | - // | +---------------------------+ | - // +-----------------------------------+ - // - else if ( spaceHeight + dockedOffsetY > viewRect.height - editorRect.bottom ) - changeMode( 'pin' ); - - // +- - - - - - - - - Editor -+ - // | | - // +------------------------ Viewport -+ \ - // | | | | |-> floatSpacePinnedOffsetY - // | ................................. | / - // | | | | - // | | | | - // | +---------------------------+ | - // | +------ Space -+ | - // | | | | - // | +--------------+ | - // - else - changeMode( 'bottom' ); - - var mid = viewRect.width / 2, - alignSide = - ( editorRect.left > 0 && editorRect.right < viewRect.width && editorRect.width > spaceRect.width ) ? - ( editor.config.contentsLangDirection == 'rtl' ? 'right' : 'left' ) - : - ( mid - editorRect.left > editorRect.right - mid ? 'left' : 'right' ), - offset; - - // (#9769) If viewport width is less than space width, - // make sure space never cross the left boundary of the viewport. - // In other words: top-left corner of the space is always visible. - if ( spaceRect.width > viewRect.width ) { - alignSide = 'left'; - offset = 0; - } - else { - if ( alignSide == 'left' ) { - // If the space rect fits into viewport, align it - // to the left edge of editor: - // - // +------------------------ Viewport -+ - // | | - // | +------------- Space -+ | - // | | | | - // | +---------------------+ | - // | +------------------ Editor -+ | - // | | | | - // - if ( editorRect.left > 0 ) - offset = editorRect.left; - - // If the left part of the editor is cut off by the left - // edge of the viewport, stick the space to the viewport: - // - // +------------------------ Viewport -+ - // | | - // +---------------- Space -+ | - // | | | - // +------------------------+ | - // +----|------------- Editor -+ | - // | | | | - // - else - offset = 0; - } - else { - // If the space rect fits into viewport, align it - // to the right edge of editor: - // - // +------------------------ Viewport -+ - // | | - // | +------------- Space -+ | - // | | | | - // | +---------------------+ | - // | +------------------ Editor -+ | - // | | | | - // - if ( editorRect.right < viewRect.width ) - offset = viewRect.width - editorRect.right; - - // If the right part of the editor is cut off by the right - // edge of the viewport, stick the space to the viewport: - // - // +------------------------ Viewport -+ - // | | - // | +------------- Space -+ - // | | | - // | +---------------------+ - // | +-----------------|- Editor -+ - // | | | | - // - else - offset = 0; - } - - // (#9769) Finally, stick the space to the opposite side of - // the viewport when it's cut off horizontally on the left/right - // side like below. - // - // This trick reveals cut off space in some edge cases and - // hence it improves accessibility. - // - // +------------------------ Viewport -+ - // | | - // | +--------------------|-- Space -+ - // | | | | - // | +--------------------|----------+ - // | +------- Editor -+ | - // | | | | - // - // becomes: - // - // +------------------------ Viewport -+ - // | | - // | +----------------------- Space -+ - // | | | - // | +-------------------------------+ - // | +------- Editor -+ | - // | | | | - // - if ( offset + spaceRect.width > viewRect.width ) { - alignSide = alignSide == 'left' ? 'right' : 'left'; - offset = 0; - } - } - - // Pin mode is fixed, so don't include scroll-x. - // (#9903) For mode is "top" or "bottom", add opposite scroll-x for right-aligned space. - var scroll = mode == 'pin' ? - 0 - : - alignSide == 'left' ? pageScrollX : -pageScrollX; - - floatSpace.setStyle( alignSide, pixelate( ( mode == 'pin' ? pinnedOffsetX : dockedOffsetX ) + offset + scroll ) ); - }; - })(); - - if ( topHtml ) { - var floatSpace = CKEDITOR.document.getBody().append( CKEDITOR.dom.element.createFromHtml( floatSpaceTpl.output( { - content: topHtml, - id: editor.id, - langDir: editor.lang.dir, - langCode: editor.langCode, - name: editor.name, - style: 'display:none;z-index:' + ( config.baseFloatZIndex - 1 ), - topId: editor.ui.spaceId( 'top' ) - } ) ) ), - - // Use event buffers to reduce CPU load when tons of events are fired. - changeBuffer = CKEDITOR.tools.eventsBuffer( 500, layout ), - uiBuffer = CKEDITOR.tools.eventsBuffer( 100, layout ); - - // There's no need for the floatSpace to be selectable. - floatSpace.unselectable(); - - // Prevent clicking on non-buttons area of the space from blurring editor. - floatSpace.on( 'mousedown', function( evt ) { - evt = evt.data; - if ( !evt.getTarget().hasAscendant( 'a', 1 ) ) - evt.preventDefault(); - } ); - - editor.on( 'focus', function( evt ) { - layout( evt ); - editor.on( 'change', changeBuffer.input ); - win.on( 'scroll', uiBuffer.input ); - win.on( 'resize', uiBuffer.input ); - } ); - - editor.on( 'blur', function() { - floatSpace.hide(); - editor.removeListener( 'change', changeBuffer.input ); - win.removeListener( 'scroll', uiBuffer.input ); - win.removeListener( 'resize', uiBuffer.input ); - } ); - - editor.on( 'destroy', function() { - win.removeListener( 'scroll', uiBuffer.input ); - win.removeListener( 'resize', uiBuffer.input ); - floatSpace.clearCustomData(); - floatSpace.remove(); - } ); - - // Handle initial focus. - if ( editor.focusManager.hasFocus ) - floatSpace.show(); - - // Register this UI space to the focus manager. - editor.focusManager.add( floatSpace, 1 ); - } - } -})(); - -/** - * Along with {@link #floatSpaceDockedOffsetY} it defines the - * amount of offset (in pixels) between float space and the editable left/right - * boundaries when space element is docked at either side of the editable. - * - * config.floatSpaceDockedOffsetX = 10; - * - * @cfg {Number} [floatSpaceDockedOffsetX=0] - * @member CKEDITOR.config - */ - -/** - * Along with {@link #floatSpaceDockedOffsetX} it defines the - * amount of offset (in pixels) between float space and the editable top/bottom - * boundaries when space element is docked at either side of the editable. - * - * config.floatSpaceDockedOffsetY = 10; - * - * @cfg {Number} [floatSpaceDockedOffsetY=0] - * @member CKEDITOR.config - */ - -/** - * Along with {@link #floatSpacePinnedOffsetY} it defines the - * amount of offset (in pixels) between float space and the view port boundaries - * when space element is pinned. - * - * config.floatSpacePinnedOffsetX = 20; - * - * @cfg {Number} [floatSpacePinnedOffsetX=0] - * @member CKEDITOR.config - */ - -/** - * Along with {@link #floatSpacePinnedOffsetX} it defines the - * amount of offset (in pixels) between float space and the view port boundaries - * when space element is pinned. - * - * config.floatSpacePinnedOffsetY = 20; - * - * @cfg {Number} [floatSpacePinnedOffsetY=0] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/floatpanel/plugin.js b/addons/website/static/lib/ckeditor/plugins/floatpanel/plugin.js deleted file mode 100644 index 3e9fd676825..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/floatpanel/plugin.js +++ /dev/null @@ -1,541 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'floatpanel', { - requires: 'panel' -}); - -(function() { - var panels = {}; - - function getPanel( editor, doc, parentElement, definition, level ) { - // Generates the panel key: docId-eleId-skinName-langDir[-uiColor][-CSSs][-level] - var key = CKEDITOR.tools.genKey( doc.getUniqueId(), parentElement.getUniqueId(), editor.lang.dir, editor.uiColor || '', definition.css || '', level || '' ), - panel = panels[ key ]; - - if ( !panel ) { - panel = panels[ key ] = new CKEDITOR.ui.panel( doc, definition ); - panel.element = parentElement.append( CKEDITOR.dom.element.createFromHtml( panel.render( editor ), doc ) ); - - panel.element.setStyles({ - display: 'none', - position: 'absolute' - }); - } - - return panel; - } - - /** - * Represents a floating panel UI element. - * - * It's reused by rich combos, color combos, menus, etc. - * and it renders its content using {@link CKEDITOR.ui.panel}. - * - * @class - * @todo - */ - CKEDITOR.ui.floatPanel = CKEDITOR.tools.createClass({ - /** - * Creates a floatPanel class instance. - * - * @constructor - * @param {CKEDITOR.editor} editor - * @param {CKEDITOR.dom.element} parentElement - * @param {Object} definition Definition of the panel that will be floating. - * @param {Number} level - */ - $: function( editor, parentElement, definition, level ) { - definition.forceIFrame = 1; - - // In case of editor with floating toolbar append panels that should float - // to the main UI element. - if ( definition.toolbarRelated && editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - parentElement = CKEDITOR.document.getById( 'cke_' + editor.name ); - - var doc = parentElement.getDocument(), - panel = getPanel( editor, doc, parentElement, definition, level || 0 ), - element = panel.element, - iframe = element.getFirst(), - that = this; - - // Disable native browser menu. (#4825) - element.disableContextMenu(); - - this.element = element; - - this._ = { - editor: editor, - // The panel that will be floating. - panel: panel, - parentElement: parentElement, - definition: definition, - document: doc, - iframe: iframe, - children: [], - dir: editor.lang.dir - }; - - editor.on( 'mode', hide ); - editor.on( 'resize', hide ); - // Window resize doesn't cause hide on blur. (#9800) - doc.getWindow().on( 'resize', hide ); - - // We need a wrapper because events implementation doesn't allow to attach - // one listener more than once for the same event on the same object. - // Remember that floatPanel#hide is shared between all instances. - function hide() { - that.hide(); - } - }, - - proto: { - /** - * @todo - */ - addBlock: function( name, block ) { - return this._.panel.addBlock( name, block ); - }, - - /** - * @todo - */ - addListBlock: function( name, multiSelect ) { - return this._.panel.addListBlock( name, multiSelect ); - }, - - /** - * @todo - */ - getBlock: function( name ) { - return this._.panel.getBlock( name ); - }, - - /** - * Shows panel block. - * - * @param {String} name - * @param {CKEDITOR.dom.element} offsetParent Positioned parent. - * @param {Number} corner - * - * * For LTR (left to right) oriented editor: - * * `1` = top-left - * * `2` = top-right - * * `3` = bottom-right - * * `4` = bottom-left - * * For RTL (right to left): - * * `1` = top-right - * * `2` = top-left - * * `3` = bottom-left - * * `4` = bottom-right - * - * @param {Number} [offsetX=0] - * @param {Number} [offsetY=0] - * @param {Function} [callback] A callback function executed when block positioning is done. - * @todo what do exactly these params mean (especially corner)? - */ - showBlock: function( name, offsetParent, corner, offsetX, offsetY, callback ) { - var panel = this._.panel, - block = panel.showBlock( name ); - - this.allowBlur( false ); - - // Record from where the focus is when open panel. - var editable = this._.editor.editable(); - this._.returnFocus = editable.hasFocus ? editable : new CKEDITOR.dom.element( CKEDITOR.document.$.activeElement ); - - var element = this.element, - iframe = this._.iframe, - // Non IE prefer the event into a window object. - focused = CKEDITOR.env.ie ? iframe : new CKEDITOR.dom.window( iframe.$.contentWindow ), - doc = element.getDocument(), - positionedAncestor = this._.parentElement.getPositionedAncestor(), - position = offsetParent.getDocumentPosition( doc ), - positionedAncestorPosition = positionedAncestor ? positionedAncestor.getDocumentPosition( doc ) : { x: 0, y: 0 }, - rtl = this._.dir == 'rtl', - left = position.x + ( offsetX || 0 ) - positionedAncestorPosition.x, - top = position.y + ( offsetY || 0 ) - positionedAncestorPosition.y; - - // Floating panels are off by (-1px, 0px) in RTL mode. (#3438) - if ( rtl && ( corner == 1 || corner == 4 ) ) - left += offsetParent.$.offsetWidth; - else if ( !rtl && ( corner == 2 || corner == 3 ) ) - left += offsetParent.$.offsetWidth - 1; - - if ( corner == 3 || corner == 4 ) - top += offsetParent.$.offsetHeight - 1; - - // Memorize offsetParent by it's ID. - this._.panel._.offsetParentId = offsetParent.getId(); - - element.setStyles({ - top: top + 'px', - left: 0, - display: '' - }); - - // Don't use display or visibility style because we need to - // calculate the rendering layout later and focus the element. - element.setOpacity( 0 ); - - // To allow the context menu to decrease back their width - element.getFirst().removeStyle( 'width' ); - - // Report to focus manager. - this._.editor.focusManager.add( focused ); - - // Configure the IFrame blur event. Do that only once. - if ( !this._.blurSet ) { - - // With addEventListener compatible browsers, we must - // useCapture when registering the focus/blur events to - // guarantee they will be firing in all situations. (#3068, #3222 ) - CKEDITOR.event.useCapture = true; - - focused.on( 'blur', function( ev ) { - - // As we are using capture to register the listener, - // the blur event may get fired even when focusing - // inside the window itself, so we must ensure the - // target is out of it. - if ( !this.allowBlur() || ev.data.getPhase() != CKEDITOR.EVENT_PHASE_AT_TARGET ) - return; - - if ( this.visible && !this._.activeChild ) { - // Panel close is caused by user's navigating away the focus, e.g. click outside the panel. - // DO NOT restore focus in this case. - delete this._.returnFocus; - this.hide(); - } - }, this ); - - focused.on( 'focus', function() { - this._.focused = true; - this.hideChild(); - this.allowBlur( true ); - }, this ); - - CKEDITOR.event.useCapture = false; - - this._.blurSet = 1; - } - - panel.onEscape = CKEDITOR.tools.bind( function( keystroke ) { - if ( this.onEscape && this.onEscape( keystroke ) === false ) - return false; - }, this ); - - CKEDITOR.tools.setTimeout( function() { - var panelLoad = CKEDITOR.tools.bind( function() { - var target = element; - - // Reset panel width as the new content can be narrower - // than the old one. (#9355) - target.removeStyle( 'width' ); - - if ( block.autoSize ) { - var panelDoc = block.element.getDocument(); - var width = ( CKEDITOR.env.webkit? block.element : panelDoc.getBody() )[ '$' ].scrollWidth; - - // Account for extra height needed due to IE quirks box model bug: - // http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug - // (#3426) - if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && width > 0 ) - width += ( target.$.offsetWidth || 0 ) - ( target.$.clientWidth || 0 ) + 3; - - // Add some extra pixels to improve the appearance. - width += 10; - - target.setStyle( 'width', width + 'px' ); - - var height = block.element.$.scrollHeight; - - // Account for extra height needed due to IE quirks box model bug: - // http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug - // (#3426) - if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && height > 0 ) - height += ( target.$.offsetHeight || 0 ) - ( target.$.clientHeight || 0 ) + 3; - - target.setStyle( 'height', height + 'px' ); - - // Fix IE < 8 visibility. - panel._.currentBlock.element.setStyle( 'display', 'none' ).removeStyle( 'display' ); - } else - target.removeStyle( 'height' ); - - // Flip panel layout horizontally in RTL with known width. - if ( rtl ) - left -= element.$.offsetWidth; - - // Pop the style now for measurement. - element.setStyle( 'left', left + 'px' ); - - /* panel layout smartly fit the viewport size. */ - var panelElement = panel.element, - panelWindow = panelElement.getWindow(), - rect = element.$.getBoundingClientRect(), - viewportSize = panelWindow.getViewPaneSize(); - - // Compensation for browsers that dont support "width" and "height". - var rectWidth = rect.width || rect.right - rect.left, - rectHeight = rect.height || rect.bottom - rect.top; - - // Check if default horizontal layout is impossible. - var spaceAfter = rtl ? rect.right : viewportSize.width - rect.left, - spaceBefore = rtl ? viewportSize.width - rect.right : rect.left; - - if ( rtl ) { - if ( spaceAfter < rectWidth ) { - // Flip to show on right. - if ( spaceBefore > rectWidth ) - left += rectWidth; - // Align to window left. - else if ( viewportSize.width > rectWidth ) - left = left - rect.left; - // Align to window right, never cutting the panel at right. - else - left = left - rect.right + viewportSize.width; - } - } else if ( spaceAfter < rectWidth ) { - // Flip to show on left. - if ( spaceBefore > rectWidth ) - left -= rectWidth; - // Align to window right. - else if ( viewportSize.width > rectWidth ) - left = left - rect.right + viewportSize.width; - // Align to window left, never cutting the panel at left. - else - left = left - rect.left; - } - - - // Check if the default vertical layout is possible. - var spaceBelow = viewportSize.height - rect.top, - spaceAbove = rect.top; - - if ( spaceBelow < rectHeight ) { - // Flip to show above. - if ( spaceAbove > rectHeight ) - top -= rectHeight; - // Align to window bottom. - else if ( viewportSize.height > rectHeight ) - top = top - rect.bottom + viewportSize.height; - // Align to top, never cutting the panel at top. - else - top = top - rect.top; - } - - // If IE is in RTL, we have troubles with absolute - // position and horizontal scrolls. Here we have a - // series of hacks to workaround it. (#6146) - if ( CKEDITOR.env.ie ) { - var offsetParent = new CKEDITOR.dom.element( element.$.offsetParent ), - scrollParent = offsetParent; - - // Quirks returns <body>, but standards returns <html>. - if ( scrollParent.getName() == 'html' ) - scrollParent = scrollParent.getDocument().getBody(); - - if ( scrollParent.getComputedStyle( 'direction' ) == 'rtl' ) { - // For IE8, there is not much logic on this, but it works. - if ( CKEDITOR.env.ie8Compat ) - left -= element.getDocument().getDocumentElement().$.scrollLeft * 2; - else - left -= ( offsetParent.$.scrollWidth - offsetParent.$.clientWidth ); - } - } - - // Trigger the onHide event of the previously active panel to prevent - // incorrect styles from being applied (#6170) - var innerElement = element.getFirst(), - activePanel; - if ( ( activePanel = innerElement.getCustomData( 'activePanel' ) ) ) - activePanel.onHide && activePanel.onHide.call( this, 1 ); - innerElement.setCustomData( 'activePanel', this ); - - element.setStyles({ - top: top + 'px', - left: left + 'px' - }); - element.setOpacity( 1 ); - - callback && callback(); - }, this ); - - panel.isLoaded ? panelLoad() : panel.onLoad = panelLoad; - - // Set the panel frame focus, so the blur event gets fired. - CKEDITOR.tools.setTimeout( function() { - - this.focus(); - - // We need this get fired manually because of unfired focus() function. - this.allowBlur( true ); - this._.editor.fire( 'panelShow', this ); - }, 0, this ); - }, CKEDITOR.env.air ? 200 : 0, this ); - this.visible = 1; - - if ( this.onShow ) - this.onShow.call( this ); - - }, - - /** - * Restores last focused element or simply focus panel window. - */ - focus: function() { - // Webkit requires to blur any previous focused page element, in - // order to properly fire the "focus" event. - if ( CKEDITOR.env.webkit ) { - var active = CKEDITOR.document.getActive(); - !active.equals( this._.iframe ) && active.$.blur(); - } - - // Restore last focused element or simply focus panel window. - var focus = this._.lastFocused || this._.iframe.getFrameDocument().getWindow(); - focus.focus(); - }, - - /** - * @todo - */ - blur: function() { - var doc = this._.iframe.getFrameDocument(), - active = doc.getActive(); - - active.is( 'a' ) && ( this._.lastFocused = active ); - }, - - /** - * Hides panel. - * - * @todo - */ - hide: function( returnFocus ) { - if ( this.visible && ( !this.onHide || this.onHide.call( this ) !== true ) ) { - this.hideChild(); - // Blur previously focused element. (#6671) - CKEDITOR.env.gecko && this._.iframe.getFrameDocument().$.activeElement.blur(); - this.element.setStyle( 'display', 'none' ); - this.visible = 0; - this.element.getFirst().removeCustomData( 'activePanel' ); - - // Return focus properly. (#6247) - var focusReturn = returnFocus && this._.returnFocus; - if ( focusReturn ) { - // Webkit requires focus moved out panel iframe first. - if ( CKEDITOR.env.webkit && focusReturn.type ) - focusReturn.getWindow().$.focus(); - - focusReturn.focus(); - } - - delete this._.lastFocused; - - this._.editor.fire( 'panelHide', this ); - } - }, - - /** - * @todo - */ - allowBlur: function( allow ) // Prevent editor from hiding the panel. #3222. - { - var panel = this._.panel; - if ( allow != undefined ) - panel.allowBlur = allow; - - return panel.allowBlur; - }, - - /** - * Shows specified panel as a child of one block of this one. - * - * @param {CKEDITOR.ui.floatPanel} panel - * @param {String} blockName - * @param {CKEDITOR.dom.element} offsetParent Positioned parent. - * @param {Number} corner - * - * * For LTR (left to right) oriented editor: - * * `1` = top-left - * * `2` = top-right - * * `3` = bottom-right - * * `4` = bottom-left - * * For RTL (right to left): - * * `1` = top-right - * * `2` = top-left - * * `3` = bottom-left - * * `4` = bottom-right - * - * @param {Number} [offsetX=0] - * @param {Number} [offsetY=0] - * @todo - */ - showAsChild: function( panel, blockName, offsetParent, corner, offsetX, offsetY ) { - // Skip reshowing of child which is already visible. - if ( this._.activeChild == panel && panel._.panel._.offsetParentId == offsetParent.getId() ) - return; - - this.hideChild(); - - panel.onHide = CKEDITOR.tools.bind( function() { - // Use a timeout, so we give time for this menu to get - // potentially focused. - CKEDITOR.tools.setTimeout( function() { - if ( !this._.focused ) - this.hide(); - }, 0, this ); - }, this ); - - this._.activeChild = panel; - this._.focused = false; - - panel.showBlock( blockName, offsetParent, corner, offsetX, offsetY ); - this.blur(); - - /* #3767 IE: Second level menu may not have borders */ - if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) { - setTimeout( function() { - panel.element.getChild( 0 ).$.style.cssText += ''; - }, 100 ); - } - }, - - /** - * @todo - */ - hideChild: function( restoreFocus ) { - var activeChild = this._.activeChild; - - if ( activeChild ) { - delete activeChild.onHide; - delete this._.activeChild; - activeChild.hide(); - - // At this point focus should be moved back to parent panel. - restoreFocus && this.focus(); - } - } - } - }); - - CKEDITOR.on( 'instanceDestroyed', function() { - var isLastInstance = CKEDITOR.tools.isEmpty( CKEDITOR.instances ); - - for ( var i in panels ) { - var panel = panels[ i ]; - // Safe to destroy it since there're no more instances.(#4241) - if ( isLastInstance ) - panel.destroy(); - // Panel might be used by other instances, just hide them.(#4552) - else - panel.element.hide(); - } - // Remove the registration. - isLastInstance && ( panels = {} ); - - } ); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/font/lang/en.js b/addons/website/static/lib/ckeditor/plugins/font/lang/en.js deleted file mode 100644 index f26e1900282..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/font/lang/en.js +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'font', 'en', { - fontSize: { - label: 'Size', - voiceLabel: 'Font Size', - panelTitle: 'Font Size' - }, - label: 'Font', - panelTitle: 'Font Name', - voiceLabel: 'Font' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/font/plugin.js b/addons/website/static/lib/ckeditor/plugins/font/plugin.js deleted file mode 100644 index f4a664882d3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/font/plugin.js +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - function addCombo( editor, comboName, styleType, lang, entries, defaultLabel, styleDefinition, order ) { - var config = editor.config, - style = new CKEDITOR.style( styleDefinition ); - - // Gets the list of fonts from the settings. - var names = entries.split( ';' ), - values = []; - - // Create style objects for all fonts. - var styles = {}; - for ( var i = 0; i < names.length; i++ ) { - var parts = names[ i ]; - - if ( parts ) { - parts = parts.split( '/' ); - - var vars = {}, - name = names[ i ] = parts[ 0 ]; - - vars[ styleType ] = values[ i ] = parts[ 1 ] || name; - - styles[ name ] = new CKEDITOR.style( styleDefinition, vars ); - styles[ name ]._.definition.name = name; - } else - names.splice( i--, 1 ); - } - - editor.ui.addRichCombo( comboName, { - label: lang.label, - title: lang.panelTitle, - toolbar: 'styles,' + order, - allowedContent: style, - requiredContent: style, - - panel: { - css: [ CKEDITOR.skin.getPath( 'editor' ) ].concat( config.contentsCss ), - multiSelect: false, - attributes: { 'aria-label': lang.panelTitle } - }, - - init: function() { - this.startGroup( lang.panelTitle ); - - for ( var i = 0; i < names.length; i++ ) { - var name = names[ i ]; - - // Add the tag entry to the panel list. - this.add( name, styles[ name ].buildPreview(), name ); - } - }, - - onClick: function( value ) { - editor.focus(); - editor.fire( 'saveSnapshot' ); - - var style = styles[ value ]; - - editor[ this.getValue() == value ? 'removeStyle' : 'applyStyle' ]( style ); - editor.fire( 'saveSnapshot' ); - }, - - onRender: function() { - editor.on( 'selectionChange', function( ev ) { - var currentValue = this.getValue(); - - var elementPath = ev.data.path, - elements = elementPath.elements; - - // For each element into the elements path. - for ( var i = 0, element; i < elements.length; i++ ) { - element = elements[ i ]; - - // Check if the element is removable by any of - // the styles. - for ( var value in styles ) { - if ( styles[ value ].checkElementMatch( element, true ) ) { - if ( value != currentValue ) - this.setValue( value ); - return; - } - } - } - - // If no styles match, just empty it. - this.setValue( '', defaultLabel ); - }, this ); - } - }); - } - - CKEDITOR.plugins.add( 'font', { - requires: 'richcombo', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - init: function( editor ) { - var config = editor.config; - - addCombo( editor, 'Font', 'family', editor.lang.font, config.font_names, config.font_defaultLabel, config.font_style, 30 ); - addCombo( editor, 'FontSize', 'size', editor.lang.font.fontSize, config.fontSize_sizes, config.fontSize_defaultLabel, config.fontSize_style, 40 ); - } - }); -})(); - -/** - * The list of fonts names to be displayed in the Font combo in the toolbar. - * Entries are separated by semi-colons (`';'`), while it's possible to have more - * than one font for each entry, in the HTML way (separated by comma). - * - * A display name may be optionally defined by prefixing the entries with the - * name and the slash character. For example, `'Arial/Arial, Helvetica, sans-serif'` - * will be displayed as `'Arial'` in the list, but will be outputted as - * `'Arial, Helvetica, sans-serif'`. - * - * config.font_names = - * 'Arial/Arial, Helvetica, sans-serif;' + - * 'Times New Roman/Times New Roman, Times, serif;' + - * 'Verdana'; - * - * config.font_names = 'Arial;Times New Roman;Verdana'; - * - * @cfg {String} [font_names=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.font_names = 'Arial/Arial, Helvetica, sans-serif;' + - 'Comic Sans MS/Comic Sans MS, cursive;' + - 'Courier New/Courier New, Courier, monospace;' + - 'Georgia/Georgia, serif;' + - 'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' + - 'Tahoma/Tahoma, Geneva, sans-serif;' + - 'Times New Roman/Times New Roman, Times, serif;' + - 'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' + - 'Verdana/Verdana, Geneva, sans-serif'; - -/** - * The text to be displayed in the Font combo is none of the available values - * matches the current cursor position or text selection. - * - * // If the default site font is Arial, we may making it more explicit to the end user. - * config.font_defaultLabel = 'Arial'; - * - * @cfg {String} [font_defaultLabel=''] - * @member CKEDITOR.config - */ -CKEDITOR.config.font_defaultLabel = ''; - -/** - * The style definition to be used to apply the font in the text. - * - * // This is actually the default value for it. - * config.font_style = { - * element: 'span', - * styles: { 'font-family': '#(family)' }, - * overrides: [ { element: 'font', attributes: { 'face': null } } ] - * }; - * - * @cfg {Object} [font_style=see example] - * @member CKEDITOR.config - */ -CKEDITOR.config.font_style = { - element: 'span', - styles: { 'font-family': '#(family)' }, - overrides: [ { - element: 'font', attributes: { 'face': null } - }] -}; - -/** - * The list of fonts size to be displayed in the Font Size combo in the - * toolbar. Entries are separated by semi-colons (`';'`). - * - * Any kind of "CSS like" size can be used, like `'12px'`, `'2.3em'`, `'130%'`, - * `'larger'` or `'x-small'`. - * - * A display name may be optionally defined by prefixing the entries with the - * name and the slash character. For example, `'Bigger Font/14px'` will be - * displayed as `'Bigger Font'` in the list, but will be outputted as `'14px'`. - * - * config.fontSize_sizes = '16/16px;24/24px;48/48px;'; - * - * config.fontSize_sizes = '12px;2.3em;130%;larger;x-small'; - * - * config.fontSize_sizes = '12 Pixels/12px;Big/2.3em;30 Percent More/130%;Bigger/larger;Very Small/x-small'; - * - * @cfg {String} [fontSize_sizes=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.fontSize_sizes = '8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px'; - -/** - * The text to be displayed in the Font Size combo is none of the available - * values matches the current cursor position or text selection. - * - * // If the default site font size is 12px, we may making it more explicit to the end user. - * config.fontSize_defaultLabel = '12px'; - * - * @cfg {String} [fontSize_defaultLabel=''] - * @member CKEDITOR.config - */ -CKEDITOR.config.fontSize_defaultLabel = ''; - -/** - * The style definition to be used to apply the font size in the text. - * - * // This is actually the default value for it. - * config.fontSize_style = { - * element: 'span', - * styles: { 'font-size': '#(size)' }, - * overrides: [ { element :'font', attributes: { 'size': null } } ] - * }; - * - * @cfg {Object} [fontSize_style=see example] - * @member CKEDITOR.config - */ -CKEDITOR.config.fontSize_style = { - element: 'span', - styles: { 'font-size': '#(size)' }, - overrides: [ { - element: 'font', attributes: { 'size': null } - }] -}; diff --git a/addons/website/static/lib/ckeditor/plugins/format/lang/en.js b/addons/website/static/lib/ckeditor/plugins/format/lang/en.js deleted file mode 100644 index 269b21913a4..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/format/lang/en.js +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'format', 'en', { - label: 'Format', - panelTitle: 'Paragraph Format', - tag_address: 'Address', - tag_div: 'Normal (DIV)', - tag_h1: 'Heading 1', - tag_h2: 'Heading 2', - tag_h3: 'Heading 3', - tag_h4: 'Heading 4', - tag_h5: 'Heading 5', - tag_h6: 'Heading 6', - tag_p: 'Normal', - tag_pre: 'Formatted' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/format/plugin.js b/addons/website/static/lib/ckeditor/plugins/format/plugin.js deleted file mode 100644 index 6c416d81746..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/format/plugin.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'format', { - requires: 'richcombo', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - var config = editor.config, - lang = editor.lang.format; - - // Gets the list of tags from the settings. - var tags = config.format_tags.split( ';' ); - - // Create style objects for all defined styles. - var styles = {}, - stylesCount = 0, - allowedContent = []; - for ( var i = 0; i < tags.length; i++ ) { - var tag = tags[ i ]; - var style = new CKEDITOR.style( config[ 'format_' + tag ] ); - if ( !editor.filter.customConfig || editor.filter.check( style ) ) { - stylesCount++; - styles[ tag ] = style; - styles[ tag ]._.enterMode = editor.config.enterMode; - allowedContent.push( style ); - } - } - - // Hide entire combo when all formats are rejected. - if ( stylesCount === 0 ) - return; - - editor.ui.addRichCombo( 'Format', { - label: lang.label, - title: lang.panelTitle, - toolbar: 'styles,20', - allowedContent: allowedContent, - - panel: { - css: [ CKEDITOR.skin.getPath( 'editor' ) ].concat( config.contentsCss ), - multiSelect: false, - attributes: { 'aria-label': lang.panelTitle } - }, - - init: function() { - this.startGroup( lang.panelTitle ); - - for ( var tag in styles ) { - var label = lang[ 'tag_' + tag ]; - - // Add the tag entry to the panel list. - this.add( tag, styles[ tag ].buildPreview( label ), label ); - } - }, - - onClick: function( value ) { - editor.focus(); - editor.fire( 'saveSnapshot' ); - - var style = styles[ value ], - elementPath = editor.elementPath(); - - editor[ style.checkActive( elementPath ) ? 'removeStyle' : 'applyStyle' ]( style ); - - // Save the undo snapshot after all changes are affected. (#4899) - setTimeout( function() { - editor.fire( 'saveSnapshot' ); - }, 0 ); - }, - - onRender: function() { - editor.on( 'selectionChange', function( ev ) { - - var currentTag = this.getValue(), - elementPath = ev.data.path, - isEnabled = !editor.readOnly && elementPath.isContextFor( 'p' ); - - // Disable the command when selection path is "blockless". - this[ isEnabled ? 'enable' : 'disable' ](); - - if ( isEnabled ) { - - for ( var tag in styles ) { - if ( styles[ tag ].checkActive( elementPath ) ) { - if ( tag != currentTag ) - this.setValue( tag, editor.lang.format[ 'tag_' + tag ] ); - return; - } - } - - // If no styles match, just empty it. - this.setValue( '' ); - } - }, this ); - } - }); - } -}); - -/** - * A list of semi colon separated style names (by default tags) representing - * the style definition for each entry to be displayed in the Format combo in - * the toolbar. Each entry must have its relative definition configuration in a - * setting named `'format_(tagName)'`. For example, the `'p'` entry has its - * definition taken from `config.format_p`. - * - * config.format_tags = 'p;h2;h3;pre'; - * - * @cfg {String} [format_tags='p;h1;h2;h3;h4;h5;h6;pre;address;div'] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div'; - -/** - * The style definition to be used to apply the `'Normal'` format. - * - * config.format_p = { element: 'p', attributes: { 'class': 'normalPara' } }; - * - * @cfg {Object} [format_p={ element: 'p' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_p = { element: 'p' }; - -/** - * The style definition to be used to apply the `'Normal (DIV)'` format. - * - * config.format_div = { element: 'div', attributes: { 'class': 'normalDiv' } }; - * - * @cfg {Object} [format_div={ element: 'div' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_div = { element: 'div' }; - -/** - * The style definition to be used to apply the `'Formatted'` format. - * - * config.format_pre = { element: 'pre', attributes: { 'class': 'code' } }; - * - * @cfg {Object} [format_pre={ element: 'pre' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_pre = { element: 'pre' }; - -/** - * The style definition to be used to apply the `'Address'` format. - * - * config.format_address = { element: 'address', attributes: { 'class': 'styledAddress' } }; - * - * @cfg {Object} [format_address={ element: 'address' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_address = { element: 'address' }; - -/** - * The style definition to be used to apply the `'Heading 1'` format. - * - * config.format_h1 = { element: 'h1', attributes: { 'class': 'contentTitle1' } }; - * - * @cfg {Object} [format_h1={ element: 'h1' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h1 = { element: 'h1' }; - -/** - * The style definition to be used to apply the `'Heading 2'` format. - * - * config.format_h2 = { element: 'h2', attributes: { 'class': 'contentTitle2' } }; - * - * @cfg {Object} [format_h2={ element: 'h2' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h2 = { element: 'h2' }; - -/** - * The style definition to be used to apply the `'Heading 3'` format. - * - * config.format_h3 = { element: 'h3', attributes: { 'class': 'contentTitle3' } }; - * - * @cfg {Object} [format_h3={ element: 'h3' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h3 = { element: 'h3' }; - -/** - * The style definition to be used to apply the `'Heading 4'` format. - * - * config.format_h4 = { element: 'h4', attributes: { 'class': 'contentTitle4' } }; - * - * @cfg {Object} [format_h4={ element: 'h4' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h4 = { element: 'h4' }; - -/** - * The style definition to be used to apply the `'Heading 5'` format. - * - * config.format_h5 = { element: 'h5', attributes: { 'class': 'contentTitle5' } }; - * - * @cfg {Object} [format_h5={ element: 'h5' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h5 = { element: 'h5' }; - -/** - * The style definition to be used to apply the `'Heading 6'` format. - * - * config.format_h6 = { element: 'h6', attributes: { 'class': 'contentTitle6' } }; - * - * @cfg {Object} [format_h6={ element: 'h6' }] - * @member CKEDITOR.config - */ -CKEDITOR.config.format_h6 = { element: 'h6' }; diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/button.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/button.js deleted file mode 100644 index 921e7b55b86..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/button.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'button', function( editor ) { - function commitAttributes( element ) { - var val = this.getValue(); - if ( val ) { - element.attributes[ this.id ] = val; - if ( this.id == 'name' ) - element.attributes[ 'data-cke-saved-name' ] = val; - } else { - delete element.attributes[ this.id ]; - if ( this.id == 'name' ) - delete element.attributes[ 'data-cke-saved-name' ]; - } - } - - return { - title: editor.lang.forms.button.title, - minWidth: 350, - minHeight: 150, - onShow: function() { - delete this.button; - var element = this.getParentEditor().getSelection().getSelectedElement(); - if ( element && element.is( 'input' ) ) { - var type = element.getAttribute( 'type' ); - if ( type in { button:1,reset:1,submit:1 } ) { - this.button = element; - this.setupContent( element ); - } - } - }, - onOk: function() { - var editor = this.getParentEditor(), - element = this.button, - isInsertMode = !element; - - var fake = element ? CKEDITOR.htmlParser.fragment.fromHtml( element.getOuterHtml() ).children[ 0 ] : new CKEDITOR.htmlParser.element( 'input' ); - this.commitContent( fake ); - - var writer = new CKEDITOR.htmlParser.basicWriter(); - fake.writeHtml( writer ); - var newElement = CKEDITOR.dom.element.createFromHtml( writer.getHtml(), editor.document ); - - if ( isInsertMode ) - editor.insertElement( newElement ); - else { - newElement.replace( element ); - editor.getSelection().selectElement( newElement ); - } - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.button.title, - title: editor.lang.forms.button.title, - elements: [ - { - id: 'name', - type: 'text', - label: editor.lang.common.name, - 'default': '', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: commitAttributes - }, - { - id: 'value', - type: 'text', - label: editor.lang.forms.button.text, - accessKey: 'V', - 'default': '', - setup: function( element ) { - this.setValue( element.getAttribute( 'value' ) || '' ); - }, - commit: commitAttributes - }, - { - id: 'type', - type: 'select', - label: editor.lang.forms.button.type, - 'default': 'button', - accessKey: 'T', - items: [ - [ editor.lang.forms.button.typeBtn, 'button' ], - [ editor.lang.forms.button.typeSbm, 'submit' ], - [ editor.lang.forms.button.typeRst, 'reset' ] - ], - setup: function( element ) { - this.setValue( element.getAttribute( 'type' ) || '' ); - }, - commit: commitAttributes - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/checkbox.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/checkbox.js deleted file mode 100644 index d5b0a934c50..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/checkbox.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'checkbox', function( editor ) { - return { - title: editor.lang.forms.checkboxAndRadio.checkboxTitle, - minWidth: 350, - minHeight: 140, - onShow: function() { - delete this.checkbox; - - var element = this.getParentEditor().getSelection().getSelectedElement(); - - if ( element && element.getAttribute( 'type' ) == 'checkbox' ) { - this.checkbox = element; - this.setupContent( element ); - } - }, - onOk: function() { - var editor, - element = this.checkbox, - isInsertMode = !element; - - if ( isInsertMode ) { - editor = this.getParentEditor(); - element = editor.document.createElement( 'input' ); - element.setAttribute( 'type', 'checkbox' ); - editor.insertElement( element ); - } - this.commitContent({ element: element } ); - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.checkboxAndRadio.checkboxTitle, - title: editor.lang.forms.checkboxAndRadio.checkboxTitle, - startupFocus: 'txtName', - elements: [ - { - id: 'txtName', - type: 'text', - label: editor.lang.common.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( data ) { - var element = data.element; - - // IE failed to update 'name' property on input elements, protect it now. - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'txtValue', - type: 'text', - label: editor.lang.forms.checkboxAndRadio.value, - 'default': '', - accessKey: 'V', - setup: function( element ) { - var value = element.getAttribute( 'value' ); - // IE Return 'on' as default attr value. - this.setValue( CKEDITOR.env.ie && value == 'on' ? '' : value ); - }, - commit: function( data ) { - var element = data.element, - value = this.getValue(); - - if ( value && !( CKEDITOR.env.ie && value == 'on' ) ) - element.setAttribute( 'value', value ); - else { - if ( CKEDITOR.env.ie ) { - // Remove attribute 'value' of checkbox (#4721). - var checkbox = new CKEDITOR.dom.element( 'input', element.getDocument() ); - element.copyAttributes( checkbox, { value:1 } ); - checkbox.replace( element ); - editor.getSelection().selectElement( checkbox ); - data.element = checkbox; - } else - element.removeAttribute( 'value' ); - } - } - }, - { - id: 'cmbSelected', - type: 'checkbox', - label: editor.lang.forms.checkboxAndRadio.selected, - 'default': '', - accessKey: 'S', - value: "checked", - setup: function( element ) { - this.setValue( element.getAttribute( 'checked' ) ); - }, - commit: function( data ) { - var element = data.element; - - if ( CKEDITOR.env.ie ) { - var isElementChecked = !!element.getAttribute( 'checked' ), - isChecked = !!this.getValue(); - - if ( isElementChecked != isChecked ) { - var replace = CKEDITOR.dom.element.createFromHtml( '<input type="checkbox"' + ( isChecked ? ' checked="checked"' : '' ) - + '/>', editor.document ); - - element.copyAttributes( replace, { type:1,checked:1 } ); - replace.replace( element ); - editor.getSelection().selectElement( replace ); - data.element = replace; - } - } else { - var value = this.getValue(); - if ( value ) - element.setAttribute( 'checked', 'checked' ); - else - element.removeAttribute( 'checked' ); - } - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/form.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/form.js deleted file mode 100644 index 0f2a5adad4f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/form.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'form', function( editor ) { - var autoAttributes = { action:1,id:1,method:1,enctype:1,target:1 }; - - return { - title: editor.lang.forms.form.title, - minWidth: 350, - minHeight: 200, - onShow: function() { - delete this.form; - - var path = this.getParentEditor().elementPath(), - form = path.contains( 'form', 1 ); - - if ( form ) { - this.form = form; - this.setupContent( form ); - } - }, - onOk: function() { - var editor, - element = this.form, - isInsertMode = !element; - - if ( isInsertMode ) { - editor = this.getParentEditor(); - element = editor.document.createElement( 'form' ); - !CKEDITOR.env.ie && element.append( editor.document.createElement( 'br' ) ); - } - - if ( isInsertMode ) - editor.insertElement( element ); - this.commitContent( element ); - }, - onLoad: function() { - function autoSetup( element ) { - this.setValue( element.getAttribute( this.id ) || '' ); - } - - function autoCommit( element ) { - if ( this.getValue() ) - element.setAttribute( this.id, this.getValue() ); - else - element.removeAttribute( this.id ); - } - - this.foreach( function( contentObj ) { - if ( autoAttributes[ contentObj.id ] ) { - contentObj.setup = autoSetup; - contentObj.commit = autoCommit; - } - }); - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.form.title, - title: editor.lang.forms.form.title, - elements: [ - { - id: 'txtName', - type: 'text', - label: editor.lang.common.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'action', - type: 'text', - label: editor.lang.forms.form.action, - 'default': '', - accessKey: 'T' - }, - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - id: 'id', - type: 'text', - label: editor.lang.common.id, - 'default': '', - accessKey: 'I' - }, - { - id: 'enctype', - type: 'select', - label: editor.lang.forms.form.encoding, - style: 'width:100%', - accessKey: 'E', - 'default': '', - items: [ - [ '' ], - [ 'text/plain' ], - [ 'multipart/form-data' ], - [ 'application/x-www-form-urlencoded' ] - ] - } - ] - }, - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - id: 'target', - type: 'select', - label: editor.lang.common.target, - style: 'width:100%', - accessKey: 'M', - 'default': '', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.targetNew, '_blank' ], - [ editor.lang.common.targetTop, '_top' ], - [ editor.lang.common.targetSelf, '_self' ], - [ editor.lang.common.targetParent, '_parent' ] - ] - }, - { - id: 'method', - type: 'select', - label: editor.lang.forms.form.method, - accessKey: 'M', - 'default': 'GET', - items: [ - [ 'GET', 'get' ], - [ 'POST', 'post' ] - ] - } - ] - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/hiddenfield.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/hiddenfield.js deleted file mode 100644 index 736a8b6ee14..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/hiddenfield.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'hiddenfield', function( editor ) { - return { - title: editor.lang.forms.hidden.title, - hiddenField: null, - minWidth: 350, - minHeight: 110, - onShow: function() { - delete this.hiddenField; - - var editor = this.getParentEditor(), - selection = editor.getSelection(), - element = selection.getSelectedElement(); - - if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'hiddenfield' ) { - this.hiddenField = element; - element = editor.restoreRealElement( this.hiddenField ); - this.setupContent( element ); - selection.selectElement( this.hiddenField ); - } - }, - onOk: function() { - var name = this.getValueOf( 'info', '_cke_saved_name' ), - value = this.getValueOf( 'info', 'value' ), - editor = this.getParentEditor(), - element = CKEDITOR.env.ie && !( CKEDITOR.document.$.documentMode >= 8 ) ? editor.document.createElement( '<input name="' + CKEDITOR.tools.htmlEncode( name ) + '">' ) : editor.document.createElement( 'input' ); - - element.setAttribute( 'type', 'hidden' ); - this.commitContent( element ); - var fakeElement = editor.createFakeElement( element, 'cke_hidden', 'hiddenfield' ); - if ( !this.hiddenField ) - editor.insertElement( fakeElement ); - else { - fakeElement.replace( this.hiddenField ); - editor.getSelection().selectElement( fakeElement ); - } - return true; - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.hidden.title, - title: editor.lang.forms.hidden.title, - elements: [ - { - id: '_cke_saved_name', - type: 'text', - label: editor.lang.forms.hidden.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'name', this.getValue() ); - else { - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'value', - type: 'text', - label: editor.lang.forms.hidden.value, - 'default': '', - accessKey: 'V', - setup: function( element ) { - this.setValue( element.getAttribute( 'value' ) || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'value', this.getValue() ); - else - element.removeAttribute( 'value' ); - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/radio.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/radio.js deleted file mode 100644 index b984766e9fc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/radio.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'radio', function( editor ) { - return { - title: editor.lang.forms.checkboxAndRadio.radioTitle, - minWidth: 350, - minHeight: 140, - onShow: function() { - delete this.radioButton; - - var element = this.getParentEditor().getSelection().getSelectedElement(); - if ( element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'radio' ) { - this.radioButton = element; - this.setupContent( element ); - } - }, - onOk: function() { - var editor, - element = this.radioButton, - isInsertMode = !element; - - if ( isInsertMode ) { - editor = this.getParentEditor(); - element = editor.document.createElement( 'input' ); - element.setAttribute( 'type', 'radio' ); - } - - if ( isInsertMode ) - editor.insertElement( element ); - this.commitContent({ element: element } ); - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.checkboxAndRadio.radioTitle, - title: editor.lang.forms.checkboxAndRadio.radioTitle, - elements: [ - { - id: 'name', - type: 'text', - label: editor.lang.common.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( data ) { - var element = data.element; - - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'value', - type: 'text', - label: editor.lang.forms.checkboxAndRadio.value, - 'default': '', - accessKey: 'V', - setup: function( element ) { - this.setValue( element.getAttribute( 'value' ) || '' ); - }, - commit: function( data ) { - var element = data.element; - - if ( this.getValue() ) - element.setAttribute( 'value', this.getValue() ); - else - element.removeAttribute( 'value' ); - } - }, - { - id: 'checked', - type: 'checkbox', - label: editor.lang.forms.checkboxAndRadio.selected, - 'default': '', - accessKey: 'S', - value: "checked", - setup: function( element ) { - this.setValue( element.getAttribute( 'checked' ) ); - }, - commit: function( data ) { - var element = data.element; - - if ( !( CKEDITOR.env.ie || CKEDITOR.env.opera ) ) { - if ( this.getValue() ) - element.setAttribute( 'checked', 'checked' ); - else - element.removeAttribute( 'checked' ); - } else { - var isElementChecked = element.getAttribute( 'checked' ); - var isChecked = !!this.getValue(); - - if ( isElementChecked != isChecked ) { - var replace = CKEDITOR.dom.element.createFromHtml( '<input type="radio"' + ( isChecked ? ' checked="checked"' : '' ) - + '></input>', editor.document ); - element.copyAttributes( replace, { type:1,checked:1 } ); - replace.replace( element ); - editor.getSelection().selectElement( replace ); - data.element = replace; - } - } - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/select.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/select.js deleted file mode 100644 index 8b7fd7b71db..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/select.js +++ /dev/null @@ -1,503 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'select', function( editor ) { - // Add a new option to a SELECT object (combo or list). - function addOption( combo, optionText, optionValue, documentObject, index ) { - combo = getSelect( combo ); - var oOption; - if ( documentObject ) - oOption = documentObject.createElement( "OPTION" ); - else - oOption = document.createElement( "OPTION" ); - - if ( combo && oOption && oOption.getName() == 'option' ) { - if ( CKEDITOR.env.ie ) { - if ( !isNaN( parseInt( index, 10 ) ) ) - combo.$.options.add( oOption.$, index ); - else - combo.$.options.add( oOption.$ ); - - oOption.$.innerHTML = optionText.length > 0 ? optionText : ''; - oOption.$.value = optionValue; - } else { - if ( index !== null && index < combo.getChildCount() ) - combo.getChild( index < 0 ? 0 : index ).insertBeforeMe( oOption ); - else - combo.append( oOption ); - - oOption.setText( optionText.length > 0 ? optionText : '' ); - oOption.setValue( optionValue ); - } - } else - return false; - - return oOption; - } - // Remove all selected options from a SELECT object. - function removeSelectedOptions( combo ) { - combo = getSelect( combo ); - - // Save the selected index - var iSelectedIndex = getSelectedIndex( combo ); - - // Remove all selected options. - for ( var i = combo.getChildren().count() - 1; i >= 0; i-- ) { - if ( combo.getChild( i ).$.selected ) - combo.getChild( i ).remove(); - } - - // Reset the selection based on the original selected index. - setSelectedIndex( combo, iSelectedIndex ); - } - //Modify option from a SELECT object. - function modifyOption( combo, index, title, value ) { - combo = getSelect( combo ); - if ( index < 0 ) - return false; - var child = combo.getChild( index ); - child.setText( title ); - child.setValue( value ); - return child; - } - - function removeAllOptions( combo ) { - combo = getSelect( combo ); - while ( combo.getChild( 0 ) && combo.getChild( 0 ).remove() ) { - /*jsl:pass*/ - } - } - // Moves the selected option by a number of steps (also negative). - function changeOptionPosition( combo, steps, documentObject ) { - combo = getSelect( combo ); - var iActualIndex = getSelectedIndex( combo ); - if ( iActualIndex < 0 ) - return false; - - var iFinalIndex = iActualIndex + steps; - iFinalIndex = ( iFinalIndex < 0 ) ? 0 : iFinalIndex; - iFinalIndex = ( iFinalIndex >= combo.getChildCount() ) ? combo.getChildCount() - 1 : iFinalIndex; - - if ( iActualIndex == iFinalIndex ) - return false; - - var oOption = combo.getChild( iActualIndex ), - sText = oOption.getText(), - sValue = oOption.getValue(); - - oOption.remove(); - - oOption = addOption( combo, sText, sValue, ( !documentObject ) ? null : documentObject, iFinalIndex ); - setSelectedIndex( combo, iFinalIndex ); - return oOption; - } - - function getSelectedIndex( combo ) { - combo = getSelect( combo ); - return combo ? combo.$.selectedIndex : -1; - } - - function setSelectedIndex( combo, index ) { - combo = getSelect( combo ); - if ( index < 0 ) - return null; - var count = combo.getChildren().count(); - combo.$.selectedIndex = ( index >= count ) ? ( count - 1 ) : index; - return combo; - } - - function getOptions( combo ) { - combo = getSelect( combo ); - return combo ? combo.getChildren() : false; - } - - function getSelect( obj ) { - if ( obj && obj.domId && obj.getInputElement().$ ) // Dialog element. - return obj.getInputElement(); - else if ( obj && obj.$ ) - return obj; - return false; - } - - return { - title: editor.lang.forms.select.title, - minWidth: CKEDITOR.env.ie ? 460 : 395, - minHeight: CKEDITOR.env.ie ? 320 : 300, - onShow: function() { - delete this.selectBox; - this.setupContent( 'clear' ); - var element = this.getParentEditor().getSelection().getSelectedElement(); - if ( element && element.getName() == "select" ) { - this.selectBox = element; - this.setupContent( element.getName(), element ); - - // Load Options into dialog. - var objOptions = getOptions( element ); - for ( var i = 0; i < objOptions.count(); i++ ) - this.setupContent( 'option', objOptions.getItem( i ) ); - } - }, - onOk: function() { - var editor = this.getParentEditor(), - element = this.selectBox, - isInsertMode = !element; - - if ( isInsertMode ) - element = editor.document.createElement( 'select' ); - this.commitContent( element ); - - if ( isInsertMode ) { - editor.insertElement( element ); - if ( CKEDITOR.env.ie ) { - var sel = editor.getSelection(), - bms = sel.createBookmarks(); - setTimeout( function() { - sel.selectBookmarks( bms ); - }, 0 ); - } - } - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.select.selectInfo, - title: editor.lang.forms.select.selectInfo, - accessKey: '', - elements: [ - { - id: 'txtName', - type: 'text', - widths: [ '25%', '75%' ], - labelLayout: 'horizontal', - label: editor.lang.common.name, - 'default': '', - accessKey: 'N', - style: 'width:350px', - setup: function( name, element ) { - if ( name == 'clear' ) - this.setValue( this[ 'default' ] || '' ); - else if ( name == 'select' ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - } - }, - commit: function( element ) { - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'txtValue', - type: 'text', - widths: [ '25%', '75%' ], - labelLayout: 'horizontal', - label: editor.lang.forms.select.value, - style: 'width:350px', - 'default': '', - className: 'cke_disabled', - onLoad: function() { - this.getInputElement().setAttribute( 'readOnly', true ); - }, - setup: function( name, element ) { - if ( name == 'clear' ) - this.setValue( '' ); - else if ( name == 'option' && element.getAttribute( 'selected' ) ) - this.setValue( element.$.value ); - } - }, - { - type: 'hbox', - widths: [ '175px', '170px' ], - children: [ - { - id: 'txtSize', - type: 'text', - labelLayout: 'horizontal', - label: editor.lang.forms.select.size, - 'default': '', - accessKey: 'S', - style: 'width:175px', - validate: function() { - var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ); - return ( ( this.getValue() === '' ) || func.apply( this ) ); - }, - setup: function( name, element ) { - if ( name == 'select' ) - this.setValue( element.getAttribute( 'size' ) || '' ); - if ( CKEDITOR.env.webkit ) - this.getInputElement().setStyle( 'width', '86px' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'size', this.getValue() ); - else - element.removeAttribute( 'size' ); - } - }, - { - type: 'html', - html: '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.forms.select.lines ) + '</span>' - } - ] - }, - { - type: 'html', - html: '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.forms.select.opAvail ) + '</span>' - }, - { - type: 'hbox', - widths: [ '115px', '115px', '100px' ], - children: [ - { - type: 'vbox', - children: [ - { - id: 'txtOptName', - type: 'text', - label: editor.lang.forms.select.opText, - style: 'width:115px', - setup: function( name, element ) { - if ( name == 'clear' ) - this.setValue( "" ); - } - }, - { - type: 'select', - id: 'cmbName', - label: '', - title: '', - size: 5, - style: 'width:115px;height:75px', - items: [], - onChange: function() { - var dialog = this.getDialog(), - values = dialog.getContentElement( 'info', 'cmbValue' ), - optName = dialog.getContentElement( 'info', 'txtOptName' ), - optValue = dialog.getContentElement( 'info', 'txtOptValue' ), - iIndex = getSelectedIndex( this ); - - setSelectedIndex( values, iIndex ); - optName.setValue( this.getValue() ); - optValue.setValue( values.getValue() ); - }, - setup: function( name, element ) { - if ( name == 'clear' ) - removeAllOptions( this ); - else if ( name == 'option' ) - addOption( this, element.getText(), element.getText(), this.getDialog().getParentEditor().document ); - }, - commit: function( element ) { - var dialog = this.getDialog(), - optionsNames = getOptions( this ), - optionsValues = getOptions( dialog.getContentElement( 'info', 'cmbValue' ) ), - selectValue = dialog.getContentElement( 'info', 'txtValue' ).getValue(); - - removeAllOptions( element ); - - for ( var i = 0; i < optionsNames.count(); i++ ) { - var oOption = addOption( element, optionsNames.getItem( i ).getValue(), optionsValues.getItem( i ).getValue(), dialog.getParentEditor().document ); - if ( optionsValues.getItem( i ).getValue() == selectValue ) { - oOption.setAttribute( 'selected', 'selected' ); - oOption.selected = true; - } - } - } - } - ] - }, - { - type: 'vbox', - children: [ - { - id: 'txtOptValue', - type: 'text', - label: editor.lang.forms.select.opValue, - style: 'width:115px', - setup: function( name, element ) { - if ( name == 'clear' ) - this.setValue( "" ); - } - }, - { - type: 'select', - id: 'cmbValue', - label: '', - size: 5, - style: 'width:115px;height:75px', - items: [], - onChange: function() { - var dialog = this.getDialog(), - names = dialog.getContentElement( 'info', 'cmbName' ), - optName = dialog.getContentElement( 'info', 'txtOptName' ), - optValue = dialog.getContentElement( 'info', 'txtOptValue' ), - iIndex = getSelectedIndex( this ); - - setSelectedIndex( names, iIndex ); - optName.setValue( names.getValue() ); - optValue.setValue( this.getValue() ); - }, - setup: function( name, element ) { - if ( name == 'clear' ) - removeAllOptions( this ); - else if ( name == 'option' ) { - var oValue = element.getValue(); - addOption( this, oValue, oValue, this.getDialog().getParentEditor().document ); - if ( element.getAttribute( 'selected' ) == 'selected' ) - this.getDialog().getContentElement( 'info', 'txtValue' ).setValue( oValue ); - } - } - } - ] - }, - { - type: 'vbox', - padding: 5, - children: [ - { - type: 'button', - id: 'btnAdd', - style: '', - label: editor.lang.forms.select.btnAdd, - title: editor.lang.forms.select.btnAdd, - style: 'width:100%;', - onClick: function() { - //Add new option. - var dialog = this.getDialog(), - parentEditor = dialog.getParentEditor(), - optName = dialog.getContentElement( 'info', 'txtOptName' ), - optValue = dialog.getContentElement( 'info', 'txtOptValue' ), - names = dialog.getContentElement( 'info', 'cmbName' ), - values = dialog.getContentElement( 'info', 'cmbValue' ); - - addOption( names, optName.getValue(), optName.getValue(), dialog.getParentEditor().document ); - addOption( values, optValue.getValue(), optValue.getValue(), dialog.getParentEditor().document ); - - optName.setValue( "" ); - optValue.setValue( "" ); - } - }, - { - type: 'button', - id: 'btnModify', - label: editor.lang.forms.select.btnModify, - title: editor.lang.forms.select.btnModify, - style: 'width:100%;', - onClick: function() { - //Modify selected option. - var dialog = this.getDialog(), - optName = dialog.getContentElement( 'info', 'txtOptName' ), - optValue = dialog.getContentElement( 'info', 'txtOptValue' ), - names = dialog.getContentElement( 'info', 'cmbName' ), - values = dialog.getContentElement( 'info', 'cmbValue' ), - iIndex = getSelectedIndex( names ); - - if ( iIndex >= 0 ) { - modifyOption( names, iIndex, optName.getValue(), optName.getValue() ); - modifyOption( values, iIndex, optValue.getValue(), optValue.getValue() ); - } - } - }, - { - type: 'button', - id: 'btnUp', - style: 'width:100%;', - label: editor.lang.forms.select.btnUp, - title: editor.lang.forms.select.btnUp, - onClick: function() { - //Move up. - var dialog = this.getDialog(), - names = dialog.getContentElement( 'info', 'cmbName' ), - values = dialog.getContentElement( 'info', 'cmbValue' ); - - changeOptionPosition( names, -1, dialog.getParentEditor().document ); - changeOptionPosition( values, -1, dialog.getParentEditor().document ); - } - }, - { - type: 'button', - id: 'btnDown', - style: 'width:100%;', - label: editor.lang.forms.select.btnDown, - title: editor.lang.forms.select.btnDown, - onClick: function() { - //Move down. - var dialog = this.getDialog(), - names = dialog.getContentElement( 'info', 'cmbName' ), - values = dialog.getContentElement( 'info', 'cmbValue' ); - - changeOptionPosition( names, 1, dialog.getParentEditor().document ); - changeOptionPosition( values, 1, dialog.getParentEditor().document ); - } - } - ] - } - ] - }, - { - type: 'hbox', - widths: [ '40%', '20%', '40%' ], - children: [ - { - type: 'button', - id: 'btnSetValue', - label: editor.lang.forms.select.btnSetValue, - title: editor.lang.forms.select.btnSetValue, - onClick: function() { - //Set as default value. - var dialog = this.getDialog(), - values = dialog.getContentElement( 'info', 'cmbValue' ), - txtValue = dialog.getContentElement( 'info', 'txtValue' ); - txtValue.setValue( values.getValue() ); - } - }, - { - type: 'button', - id: 'btnDelete', - label: editor.lang.forms.select.btnDelete, - title: editor.lang.forms.select.btnDelete, - onClick: function() { - // Delete option. - var dialog = this.getDialog(), - names = dialog.getContentElement( 'info', 'cmbName' ), - values = dialog.getContentElement( 'info', 'cmbValue' ), - optName = dialog.getContentElement( 'info', 'txtOptName' ), - optValue = dialog.getContentElement( 'info', 'txtOptValue' ); - - removeSelectedOptions( names ); - removeSelectedOptions( values ); - - optName.setValue( "" ); - optValue.setValue( "" ); - } - }, - { - id: 'chkMulti', - type: 'checkbox', - label: editor.lang.forms.select.chkMulti, - 'default': '', - accessKey: 'M', - value: "checked", - setup: function( name, element ) { - if ( name == 'select' ) - this.setValue( element.getAttribute( 'multiple' ) ); - if ( CKEDITOR.env.webkit ) - this.getElement().getParent().setStyle( 'vertical-align', 'middle' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'multiple', this.getValue() ); - else - element.removeAttribute( 'multiple' ); - } - } - ] - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textarea.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textarea.js deleted file mode 100644 index 717bc31df9c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textarea.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'textarea', function( editor ) { - return { - title: editor.lang.forms.textarea.title, - minWidth: 350, - minHeight: 220, - onShow: function() { - delete this.textarea; - - var element = this.getParentEditor().getSelection().getSelectedElement(); - if ( element && element.getName() == "textarea" ) { - this.textarea = element; - this.setupContent( element ); - } - }, - onOk: function() { - var editor, - element = this.textarea, - isInsertMode = !element; - - if ( isInsertMode ) { - editor = this.getParentEditor(); - element = editor.document.createElement( 'textarea' ); - } - this.commitContent( element ); - - if ( isInsertMode ) - editor.insertElement( element ); - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.textarea.title, - title: editor.lang.forms.textarea.title, - elements: [ - { - id: '_cke_saved_name', - type: 'text', - label: editor.lang.common.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'cols', - type: 'text', - label: editor.lang.forms.textarea.cols, - 'default': '', - accessKey: 'C', - style: 'width:50px', - validate: CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ), - setup: function( element ) { - var value = element.hasAttribute( 'cols' ) && element.getAttribute( 'cols' ); - this.setValue( value || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'cols', this.getValue() ); - else - element.removeAttribute( 'cols' ); - } - }, - { - id: 'rows', - type: 'text', - label: editor.lang.forms.textarea.rows, - 'default': '', - accessKey: 'R', - style: 'width:50px', - validate: CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ), - setup: function( element ) { - var value = element.hasAttribute( 'rows' ) && element.getAttribute( 'rows' ); - this.setValue( value || '' ); - }, - commit: function( element ) { - if ( this.getValue() ) - element.setAttribute( 'rows', this.getValue() ); - else - element.removeAttribute( 'rows' ); - } - } - ] - }, - { - id: 'value', - type: 'textarea', - label: editor.lang.forms.textfield.value, - 'default': '', - setup: function( element ) { - this.setValue( element.$.defaultValue ); - }, - commit: function( element ) { - element.$.value = element.$.defaultValue = this.getValue(); - } - } - - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textfield.js b/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textfield.js deleted file mode 100644 index c7c98814e8d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/dialogs/textfield.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ -CKEDITOR.dialog.add( 'textfield', function( editor ) { - var autoAttributes = { value:1,size:1,maxLength:1 }; - - var acceptedTypes = { email:1,password:1,search:1,tel:1,text:1,url:1 }; - - function autoCommit( data ) { - var element = data.element; - var value = this.getValue(); - - value ? element.setAttribute( this.id, value ) : element.removeAttribute( this.id ); - } - - function autoSetup( element ) { - var value = element.hasAttribute( this.id ) && element.getAttribute( this.id ); - this.setValue( value || '' ); - } - - return { - title: editor.lang.forms.textfield.title, - minWidth: 350, - minHeight: 150, - onShow: function() { - delete this.textField; - - var element = this.getParentEditor().getSelection().getSelectedElement(); - if ( element && element.getName() == "input" && ( acceptedTypes[ element.getAttribute( 'type' ) ] || !element.getAttribute( 'type' ) ) ) { - this.textField = element; - this.setupContent( element ); - } - }, - onOk: function() { - var editor = this.getParentEditor(), - element = this.textField, - isInsertMode = !element; - - if ( isInsertMode ) { - element = editor.document.createElement( 'input' ); - element.setAttribute( 'type', 'text' ); - } - - var data = { element: element }; - - if ( isInsertMode ) - editor.insertElement( data.element ); - - this.commitContent( data ); - - // Element might be replaced by commitment. - if ( !isInsertMode ) - editor.getSelection().selectElement( data.element ); - }, - onLoad: function() { - this.foreach( function( contentObj ) { - if ( contentObj.getValue ) { - if ( !contentObj.setup ) - contentObj.setup = autoSetup; - if ( !contentObj.commit ) - contentObj.commit = autoCommit; - } - }); - }, - contents: [ - { - id: 'info', - label: editor.lang.forms.textfield.title, - title: editor.lang.forms.textfield.title, - elements: [ - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: '_cke_saved_name', - type: 'text', - label: editor.lang.forms.textfield.name, - 'default': '', - accessKey: 'N', - setup: function( element ) { - this.setValue( element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || '' ); - }, - commit: function( data ) { - var element = data.element; - - if ( this.getValue() ) - element.data( 'cke-saved-name', this.getValue() ); - else { - element.data( 'cke-saved-name', false ); - element.removeAttribute( 'name' ); - } - } - }, - { - id: 'value', - type: 'text', - label: editor.lang.forms.textfield.value, - 'default': '', - accessKey: 'V', - commit: function( data ) { - if ( CKEDITOR.env.ie && !this.getValue() ) { - var element = data.element, - fresh = new CKEDITOR.dom.element( 'input', editor.document ); - element.copyAttributes( fresh, { value:1 } ); - fresh.replace( element ); - data.element = fresh; - } else - autoCommit.call( this, data ); - } - } - ] - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'size', - type: 'text', - label: editor.lang.forms.textfield.charWidth, - 'default': '', - accessKey: 'C', - style: 'width:50px', - validate: CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ) - }, - { - id: 'maxLength', - type: 'text', - label: editor.lang.forms.textfield.maxChars, - 'default': '', - accessKey: 'M', - style: 'width:50px', - validate: CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ) - } - ], - onLoad: function() { - // Repaint the style for IE7 (#6068) - if ( CKEDITOR.env.ie7Compat ) - this.getElement().setStyle( 'zoom', '100%' ); - } - }, - { - id: 'type', - type: 'select', - label: editor.lang.forms.textfield.type, - 'default': 'text', - accessKey: 'M', - items: [ - [ editor.lang.forms.textfield.typeEmail, 'email' ], - [ editor.lang.forms.textfield.typePass, 'password' ], - [ editor.lang.forms.textfield.typeSearch, 'search' ], - [ editor.lang.forms.textfield.typeTel, 'tel' ], - [ editor.lang.forms.textfield.typeText, 'text' ], - [ editor.lang.forms.textfield.typeUrl, 'url' ] - ], - setup: function( element ) { - this.setValue( element.getAttribute( 'type' ) ); - }, - commit: function( data ) { - var element = data.element; - - if ( CKEDITOR.env.ie ) { - var elementType = element.getAttribute( 'type' ); - var myType = this.getValue(); - - if ( elementType != myType ) { - var replace = CKEDITOR.dom.element.createFromHtml( '<input type="' + myType + '"></input>', editor.document ); - element.copyAttributes( replace, { type:1 } ); - replace.replace( element ); - data.element = replace; - } - } else - element.setAttribute( 'type', this.getValue() ); - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/button.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/button.png Binary files differdeleted file mode 100644 index 0bf68caaa5c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/button.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/checkbox.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/checkbox.png Binary files differdeleted file mode 100644 index 2f4eb2f40f5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/checkbox.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/form.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/form.png Binary files differdeleted file mode 100644 index 08416674e1f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/form.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hiddenfield.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hiddenfield.png Binary files differdeleted file mode 100644 index fce4fcccc6e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hiddenfield.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/button.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/button.png Binary files differdeleted file mode 100644 index bd92b165490..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/button.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/checkbox.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/checkbox.png Binary files differdeleted file mode 100644 index 36be4aa0bc6..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/checkbox.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/form.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/form.png Binary files differdeleted file mode 100644 index 4a02649cda7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/form.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/hiddenfield.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/hiddenfield.png Binary files differdeleted file mode 100644 index cd5f31868bb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/hiddenfield.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/imagebutton.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/imagebutton.png Binary files differdeleted file mode 100644 index d27379639b7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/imagebutton.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/radio.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/radio.png Binary files differdeleted file mode 100644 index 2f0c72d6344..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/radio.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select-rtl.png Binary files differdeleted file mode 100644 index 42452e19de3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select.png Binary files differdeleted file mode 100644 index da2b066bea5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/select.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea-rtl.png Binary files differdeleted file mode 100644 index 60618a5b598..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea.png Binary files differdeleted file mode 100644 index 87073d22015..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textarea.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield-rtl.png Binary files differdeleted file mode 100644 index d3c13582d92..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield.png Binary files differdeleted file mode 100644 index d3c13582d92..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/hidpi/textfield.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/imagebutton.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/imagebutton.png Binary files differdeleted file mode 100644 index 162df9a38bc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/imagebutton.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/radio.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/radio.png Binary files differdeleted file mode 100644 index aaad523fa50..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/radio.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/select-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/select-rtl.png Binary files differdeleted file mode 100644 index 029a0d22984..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/select-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/select.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/select.png Binary files differdeleted file mode 100644 index 44b02b9d91b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/select.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea-rtl.png Binary files differdeleted file mode 100644 index 8a15d68804b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea.png Binary files differdeleted file mode 100644 index 58e0fa02030..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/textarea.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield-rtl.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield-rtl.png Binary files differdeleted file mode 100644 index 054aab56e1c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield.png b/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield.png Binary files differdeleted file mode 100644 index 054aab56e1c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/icons/textfield.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/forms/lang/en.js b/addons/website/static/lib/ckeditor/plugins/forms/lang/en.js deleted file mode 100644 index 6063bc68ae7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/lang/en.js +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'forms', 'en', { - button: { - title: 'Button Properties', - text: 'Text (Value)', - type: 'Type', - typeBtn: 'Button', - typeSbm: 'Submit', - typeRst: 'Reset' - }, - checkboxAndRadio: { - checkboxTitle: 'Checkbox Properties', - radioTitle: 'Radio Button Properties', - value: 'Value', - selected: 'Selected' - }, - form: { - title: 'Form Properties', - menu: 'Form Properties', - action: 'Action', - method: 'Method', - encoding: 'Encoding' - }, - hidden: { - title: 'Hidden Field Properties', - name: 'Name', - value: 'Value' - }, - select: { - title: 'Selection Field Properties', - selectInfo: 'Select Info', - opAvail: 'Available Options', - value: 'Value', - size: 'Size', - lines: 'lines', - chkMulti: 'Allow multiple selections', - opText: 'Text', - opValue: 'Value', - btnAdd: 'Add', - btnModify: 'Modify', - btnUp: 'Up', - btnDown: 'Down', - btnSetValue: 'Set as selected value', - btnDelete: 'Delete' - }, - textarea: { - title: 'Textarea Properties', - cols: 'Columns', - rows: 'Rows' - }, - textfield: { - title: 'Text Field Properties', - name: 'Name', - value: 'Value', - charWidth: 'Character Width', - maxChars: 'Maximum Characters', - type: 'Type', - typeText: 'Text', - typePass: 'Password', - typeEmail: 'Email', - typeSearch: 'Search', - typeTel: 'Telephone Number', - typeUrl: 'URL' - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/forms/plugin.js b/addons/website/static/lib/ckeditor/plugins/forms/plugin.js deleted file mode 100644 index dc4b554646f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/forms/plugin.js +++ /dev/null @@ -1,292 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Forms Plugin - */ - -CKEDITOR.plugins.add( 'forms', { - requires: 'dialog,fakeobjects', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'button,checkbox,form,hiddenfield,imagebutton,radio,select,select-rtl,textarea,textarea-rtl,textfield', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - CKEDITOR.addCss( '.cke_editable form' + - '{' + - 'border: 1px dotted #FF0000;' + - 'padding: 2px;' + - '}\n' ); - - CKEDITOR.addCss( 'img.cke_hidden' + - '{' + - 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/hiddenfield.gif' ) + ');' + - 'background-position: center center;' + - 'background-repeat: no-repeat;' + - 'border: 1px solid #a9a9a9;' + - 'width: 16px !important;' + - 'height: 16px !important;' + - '}' ); - - }, - init: function( editor ) { - var lang = editor.lang, - order = 0, - textfieldTypes = { email:1,password:1,search:1,tel:1,text:1,url:1 }, - allowedContent = { - checkbox: 'input[type,name,checked]', - radio: 'input[type,name,checked]', - textfield: 'input[type,name,value,size,maxlength]', - textarea: 'textarea[cols,rows,name]', - select: 'select[name,size,multiple]; option[value,selected]', - button: 'input[type,name,value]', - form: 'form[action,name,id,enctype,target,method]', - hiddenfield: 'input[type,name,value]', - imagebutton: 'input[type,alt,src]{width,height,border,border-width,border-style,margin,float}' - }, - requiredContent = { - checkbox: 'input', - radio: 'input', - textfield: 'input', - textarea: 'textarea', - select: 'select', - button: 'input', - form: 'form', - hiddenfield: 'input', - imagebutton: 'input' - }; - - // All buttons use the same code to register. So, to avoid - // duplications, let's use this tool function. - var addButtonCommand = function( buttonName, commandName, dialogFile ) { - var def = { - allowedContent: allowedContent[ commandName ], - requiredContent: requiredContent[ commandName ] - }; - commandName == 'form' && ( def.context = 'form' ); - - editor.addCommand( commandName, new CKEDITOR.dialogCommand( commandName, def ) ); - - editor.ui.addButton && editor.ui.addButton( buttonName, { - label: lang.common[ buttonName.charAt( 0 ).toLowerCase() + buttonName.slice( 1 ) ], - command: commandName, - toolbar: 'forms,' + ( order += 10 ) - }); - CKEDITOR.dialog.add( commandName, dialogFile ); - }; - - var dialogPath = this.path + 'dialogs/'; - !editor.blockless && addButtonCommand( 'Form', 'form', dialogPath + 'form.js' ); - addButtonCommand( 'Checkbox', 'checkbox', dialogPath + 'checkbox.js' ); - addButtonCommand( 'Radio', 'radio', dialogPath + 'radio.js' ); - addButtonCommand( 'TextField', 'textfield', dialogPath + 'textfield.js' ); - addButtonCommand( 'Textarea', 'textarea', dialogPath + 'textarea.js' ); - addButtonCommand( 'Select', 'select', dialogPath + 'select.js' ); - addButtonCommand( 'Button', 'button', dialogPath + 'button.js' ); - - // If the "image" plugin is loaded. - var imagePlugin = CKEDITOR.plugins.get( 'image' ); - imagePlugin && addButtonCommand( 'ImageButton', 'imagebutton', CKEDITOR.plugins.getPath( 'image' ) + 'dialogs/image.js' ); - - addButtonCommand( 'HiddenField', 'hiddenfield', dialogPath + 'hiddenfield.js' ); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - var items = { - checkbox: { - label: lang.forms.checkboxAndRadio.checkboxTitle, - command: 'checkbox', - group: 'checkbox' - }, - - radio: { - label: lang.forms.checkboxAndRadio.radioTitle, - command: 'radio', - group: 'radio' - }, - - textfield: { - label: lang.forms.textfield.title, - command: 'textfield', - group: 'textfield' - }, - - hiddenfield: { - label: lang.forms.hidden.title, - command: 'hiddenfield', - group: 'hiddenfield' - }, - - imagebutton: { - label: lang.image.titleButton, - command: 'imagebutton', - group: 'imagebutton' - }, - - button: { - label: lang.forms.button.title, - command: 'button', - group: 'button' - }, - - select: { - label: lang.forms.select.title, - command: 'select', - group: 'select' - }, - - textarea: { - label: lang.forms.textarea.title, - command: 'textarea', - group: 'textarea' - } - }; - - !editor.blockless && ( items.form = { - label: lang.forms.form.menu, - command: 'form', - group: 'form' - }); - - editor.addMenuItems( items ); - - } - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - !editor.blockless && editor.contextMenu.addListener( function( element, selection, path ) { - var form = path.contains( 'form', 1 ); - if ( form && !form.isReadOnly() ) - return { form: CKEDITOR.TRISTATE_OFF }; - }); - - editor.contextMenu.addListener( function( element ) { - if ( element && !element.isReadOnly() ) { - var name = element.getName(); - - if ( name == 'select' ) - return { select: CKEDITOR.TRISTATE_OFF }; - - if ( name == 'textarea' ) - return { textarea: CKEDITOR.TRISTATE_OFF }; - - if ( name == 'input' ) { - var type = element.getAttribute( 'type' ) || 'text'; - switch ( type ) { - case 'button': - case 'submit': - case 'reset': - return { button: CKEDITOR.TRISTATE_OFF }; - - case 'checkbox': - return { checkbox: CKEDITOR.TRISTATE_OFF }; - - case 'radio': - return { radio: CKEDITOR.TRISTATE_OFF }; - - case 'image': - return imagePlugin ? { imagebutton: CKEDITOR.TRISTATE_OFF } : null; - } - - if ( textfieldTypes[ type ] ) - return { textfield: CKEDITOR.TRISTATE_OFF }; - } - - if ( name == 'img' && element.data( 'cke-real-element-type' ) == 'hiddenfield' ) - return { hiddenfield: CKEDITOR.TRISTATE_OFF }; - } - }); - } - - editor.on( 'doubleclick', function( evt ) { - var element = evt.data.element; - - if ( !editor.blockless && element.is( 'form' ) ) - evt.data.dialog = 'form'; - else if ( element.is( 'select' ) ) - evt.data.dialog = 'select'; - else if ( element.is( 'textarea' ) ) - evt.data.dialog = 'textarea'; - else if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'hiddenfield' ) - evt.data.dialog = 'hiddenfield'; - else if ( element.is( 'input' ) ) { - var type = element.getAttribute( 'type' ) || 'text'; - switch ( type ) { - case 'button': - case 'submit': - case 'reset': - evt.data.dialog = 'button'; - break; - case 'checkbox': - evt.data.dialog = 'checkbox'; - break; - case 'radio': - evt.data.dialog = 'radio'; - break; - case 'image': - evt.data.dialog = 'imagebutton'; - break; - } - if ( textfieldTypes[ type ] ) - evt.data.dialog = 'textfield'; - } - }); - }, - - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - htmlFilter = dataProcessor && dataProcessor.htmlFilter, - dataFilter = dataProcessor && dataProcessor.dataFilter; - - // Cleanup certain IE form elements default values. - if ( CKEDITOR.env.ie ) { - htmlFilter && htmlFilter.addRules({ - elements: { - input: function( input ) { - var attrs = input.attributes, - type = attrs.type; - // Old IEs don't provide type for Text inputs #5522 - if ( !type ) - attrs.type = 'text'; - if ( type == 'checkbox' || type == 'radio' ) - attrs.value == 'on' && delete attrs.value; - } - } - }); - } - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - input: function( element ) { - if ( element.attributes.type == 'hidden' ) - return editor.createFakeParserElement( element, 'cke_hidden', 'hiddenfield' ); - } - } - }); - } - } -}); - -if ( CKEDITOR.env.ie ) { - CKEDITOR.dom.element.prototype.hasAttribute = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.hasAttribute, function( original ) { - return function( name ) { - var $attr = this.$.attributes.getNamedItem( name ); - - if ( this.getName() == 'input' ) { - switch ( name ) { - case 'class': - return this.$.className.length > 0; - case 'checked': - return !!this.$.checked; - case 'value': - var type = this.getAttribute( 'type' ); - return type == 'checkbox' || type == 'radio' ? this.$.value != 'on' : this.$.value; - } - } - - return original.apply( this, arguments ); - }; - }); -} diff --git a/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/hidpi/horizontalrule.png b/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/hidpi/horizontalrule.png Binary files differdeleted file mode 100644 index 433613da214..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/hidpi/horizontalrule.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/horizontalrule.png b/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/horizontalrule.png Binary files differdeleted file mode 100644 index 4af9bc8e347..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/horizontalrule/icons/horizontalrule.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/horizontalrule/lang/en.js b/addons/website/static/lib/ckeditor/plugins/horizontalrule/lang/en.js deleted file mode 100644 index e5cca60996e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/horizontalrule/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'horizontalrule', 'en', { - toolbar: 'Insert Horizontal Line' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/horizontalrule/plugin.js b/addons/website/static/lib/ckeditor/plugins/horizontalrule/plugin.js deleted file mode 100644 index f9f19729f61..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/horizontalrule/plugin.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Horizontal Rule plugin. - */ - -(function() { - var horizontalruleCmd = { - canUndo: false, // The undo snapshot will be handled by 'insertElement'. - exec: function( editor ) { - var hr = editor.document.createElement( 'hr' ); - editor.insertElement( hr ); - }, - - allowedContent: 'hr', - requiredContent: 'hr' - }; - - var pluginName = 'horizontalrule'; - - // Register a plugin named "horizontalrule". - CKEDITOR.plugins.add( pluginName, { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'horizontalrule', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - editor.addCommand( pluginName, horizontalruleCmd ); - editor.ui.addButton && editor.ui.addButton( 'HorizontalRule', { - label: editor.lang.horizontalrule.toolbar, - command: pluginName, - toolbar: 'insert,40' - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/htmlwriter/plugin.js b/addons/website/static/lib/ckeditor/plugins/htmlwriter/plugin.js deleted file mode 100644 index bab2bda3917..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/htmlwriter/plugin.js +++ /dev/null @@ -1,359 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'htmlwriter', { - init: function( editor ) { - var writer = new CKEDITOR.htmlWriter(); - - writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand; - writer.indentationChars = editor.config.dataIndentationChars || '\t'; - - // Overwrite default basicWriter initialized in hmtlDataProcessor constructor. - editor.dataProcessor.writer = writer; - } -}); - -/** - * Class used to write HTML data. - * - * var writer = new CKEDITOR.htmlWriter(); - * writer.openTag( 'p' ); - * writer.attribute( 'class', 'MyClass' ); - * writer.openTagClose( 'p' ); - * writer.text( 'Hello' ); - * writer.closeTag( 'p' ); - * alert( writer.getHtml() ); // '<p class="MyClass">Hello</p>' - * - * @class - * @extends CKEDITOR.htmlParser.basicWriter - */ -CKEDITOR.htmlWriter = CKEDITOR.tools.createClass({ - base: CKEDITOR.htmlParser.basicWriter, - - /** - * Creates a htmlWriter class instance. - * - * @constructor - */ - $: function() { - // Call the base contructor. - this.base(); - - /** - * The characters to be used for each identation step. - * - * // Use tab for indentation. - * editorInstance.dataProcessor.writer.indentationChars = '\t'; - */ - this.indentationChars = '\t'; - - /** - * The characters to be used to close "self-closing" elements, like `<br>` or `<img>`. - * - * // Use HTML4 notation for self-closing elements. - * editorInstance.dataProcessor.writer.selfClosingEnd = '>'; - */ - this.selfClosingEnd = ' />'; - - /** - * The characters to be used for line breaks. - * - * // Use CRLF for line breaks. - * editorInstance.dataProcessor.writer.lineBreakChars = '\r\n'; - */ - this.lineBreakChars = '\n'; - - this.sortAttributes = 1; - - this._.indent = 0; - this._.indentation = ''; - // Indicate preformatted block context status. (#5789) - this._.inPre = 0; - this._.rules = {}; - - var dtd = CKEDITOR.dtd; - - for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) { - this.setRules( e, { - indent: !dtd[ e ][ '#' ], - breakBeforeOpen: 1, - breakBeforeClose: !dtd[ e ][ '#' ], - breakAfterClose: 1, - needsSpace: ( e in dtd.$block ) && !( e in { li:1,dt:1,dd:1 } ) - }); - } - - this.setRules( 'br', { breakAfterOpen:1 } ); - - this.setRules( 'title', { - indent: 0, - breakAfterOpen: 0 - }); - - this.setRules( 'style', { - indent: 0, - breakBeforeClose: 1 - }); - - this.setRules( 'pre', { - breakAfterOpen: 1, // Keep line break after the opening tag - indent: 0 // Disable indentation on <pre>. - }); - }, - - proto: { - /** - * Writes the tag opening part for a opener tag. - * - * // Writes '<p'. - * writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } ); - * - * @param {String} tagName The element name for this tag. - * @param {Object} attributes The attributes defined for this tag. The - * attributes could be used to inspect the tag. - */ - openTag: function( tagName, attributes ) { - var rules = this._.rules[ tagName ]; - - if ( this._.afterCloser && rules && rules.needsSpace && this._.needsSpace ) - this._.output.push( '\n' ); - - if ( this._.indent ) - this.indentation(); - // Do not break if indenting. - else if ( rules && rules.breakBeforeOpen ) { - this.lineBreak(); - this.indentation(); - } - - this._.output.push( '<', tagName ); - - this._.afterCloser = 0; - }, - - /** - * Writes the tag closing part for a opener tag. - * - * // Writes '>'. - * writer.openTagClose( 'p', false ); - * - * // Writes ' />'. - * writer.openTagClose( 'br', true ); - * - * @param {String} tagName The element name for this tag. - * @param {Boolean} isSelfClose Indicates that this is a self-closing tag, - * like `<br>` or `<img>`. - */ - openTagClose: function( tagName, isSelfClose ) { - var rules = this._.rules[ tagName ]; - - if ( isSelfClose ) { - this._.output.push( this.selfClosingEnd ); - - if ( rules && rules.breakAfterClose ) - this._.needsSpace = rules.needsSpace; - } else { - this._.output.push( '>' ); - - if ( rules && rules.indent ) - this._.indentation += this.indentationChars; - } - - if ( rules && rules.breakAfterOpen ) - this.lineBreak(); - tagName == 'pre' && ( this._.inPre = 1 ); - }, - - /** - * Writes an attribute. This function should be called after opening the - * tag with {@link #openTagClose}. - * - * // Writes ' class="MyClass"'. - * writer.attribute( 'class', 'MyClass' ); - * - * @param {String} attName The attribute name. - * @param {String} attValue The attribute value. - */ - attribute: function( attName, attValue ) { - - if ( typeof attValue == 'string' ) { - this.forceSimpleAmpersand && ( attValue = attValue.replace( /&/g, '&' ) ); - // Browsers don't always escape special character in attribute values. (#4683, #4719). - attValue = CKEDITOR.tools.htmlEncodeAttr( attValue ); - } - - this._.output.push( ' ', attName, '="', attValue, '"' ); - }, - - /** - * Writes a closer tag. - * - * // Writes '</p>'. - * writer.closeTag( 'p' ); - * - * @param {String} tagName The element name for this tag. - */ - closeTag: function( tagName ) { - var rules = this._.rules[ tagName ]; - - if ( rules && rules.indent ) - this._.indentation = this._.indentation.substr( this.indentationChars.length ); - - if ( this._.indent ) - this.indentation(); - // Do not break if indenting. - else if ( rules && rules.breakBeforeClose ) { - this.lineBreak(); - this.indentation(); - } - - this._.output.push( '</', tagName, '>' ); - tagName == 'pre' && ( this._.inPre = 0 ); - - if ( rules && rules.breakAfterClose ) { - this.lineBreak(); - this._.needsSpace = rules.needsSpace; - } - - this._.afterCloser = 1; - }, - - /** - * Writes text. - * - * // Writes 'Hello Word'. - * writer.text( 'Hello Word' ); - * - * @param {String} text The text value - */ - text: function( text ) { - if ( this._.indent ) { - this.indentation(); - !this._.inPre && ( text = CKEDITOR.tools.ltrim( text ) ); - } - - this._.output.push( text ); - }, - - /** - * Writes a comment. - * - * // Writes "<!-- My comment -->". - * writer.comment( ' My comment ' ); - * - * @param {String} comment The comment text. - */ - comment: function( comment ) { - if ( this._.indent ) - this.indentation(); - - this._.output.push( '<!--', comment, '-->' ); - }, - - /** - * Writes a line break. It uses the {@link #lineBreakChars} property for it. - * - * // Writes '\n' (e.g.). - * writer.lineBreak(); - */ - lineBreak: function() { - if ( !this._.inPre && this._.output.length > 0 ) - this._.output.push( this.lineBreakChars ); - this._.indent = 1; - }, - - /** - * Writes the current indentation chars. It uses the {@link #indentationChars} - * property, repeating it for the current indentation steps. - * - * // Writes '\t' (e.g.). - * writer.indentation(); - */ - indentation: function() { - if ( !this._.inPre && this._.indentation ) - this._.output.push( this._.indentation ); - this._.indent = 0; - }, - - /** - * Empties the current output buffer. It also brings back the default - * values of the writer flags. - * - * writer.reset(); - */ - reset: function() { - this._.output = []; - this._.indent = 0; - this._.indentation = ''; - this._.afterCloser = 0; - this._.inPre = 0; - }, - - /** - * Sets formatting rules for a give element. The possible rules are: - * - * * `indent`: indent the element contents. - * * `breakBeforeOpen`: break line before the opener tag for this element. - * * `breakAfterOpen`: break line after the opener tag for this element. - * * `breakBeforeClose`: break line before the closer tag for this element. - * * `breakAfterClose`: break line after the closer tag for this element. - * - * All rules default to `false`. Each call to the function overrides - * already present rules, leaving the undefined untouched. - * - * By default, all elements available in the {@link CKEDITOR.dtd#$block}, - * {@link CKEDITOR.dtd#$listItem} and {@link CKEDITOR.dtd#$tableContent} - * lists have all the above rules set to `true`. Additionaly, the `<br>` - * element has the `breakAfterOpen` set to `true`. - * - * // Break line before and after "img" tags. - * writer.setRules( 'img', { - * breakBeforeOpen: true - * breakAfterOpen: true - * } ); - * - * // Reset the rules for the "h1" tag. - * writer.setRules( 'h1', {} ); - * - * @param {String} tagName The element name to which set the rules. - * @param {Object} rules An object containing the element rules. - */ - setRules: function( tagName, rules ) { - var currentRules = this._.rules[ tagName ]; - - if ( currentRules ) - CKEDITOR.tools.extend( currentRules, rules, true ); - else - this._.rules[ tagName ] = rules; - } - } -}); - -/** - * Whether to force using `'&'` instead of `'&'` in elements attributes - * values, it's not recommended to change this setting for compliance with the - * W3C XHTML 1.0 standards ([C.12, XHTML 1.0](http://www.w3.org/TR/xhtml1/#C_12)). - * - * // Use `'&'` instead of `'&'` - * CKEDITOR.config.forceSimpleAmpersand = true; - * - * @cfg {Boolean} [forceSimpleAmpersand=false] - * @member CKEDITOR.config - */ - -/** - * The characters to be used for indenting the HTML produced by the editor. - * Using characters different than `' '` (space) and `'\t'` (tab) is definitely - * a bad idea as it'll mess the code. - * - * // No indentation. - * CKEDITOR.config.dataIndentationChars = ''; - * - * // Use two spaces for indentation. - * CKEDITOR.config.dataIndentationChars = ' '; - * - * @cfg {String} [dataIndentationChars='\t'] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/iframe/dialogs/iframe.js b/addons/website/static/lib/ckeditor/plugins/iframe/dialogs/iframe.js deleted file mode 100644 index 1b90592ef02..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframe/dialogs/iframe.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - // Map 'true' and 'false' values to match W3C's specifications - // http://www.w3.org/TR/REC-html40/present/frames.html#h-16.5 - var checkboxValues = { - scrolling: { 'true': 'yes', 'false': 'no' }, - frameborder: { 'true': '1', 'false': '0' } - }; - - function loadValue( iframeNode ) { - var isCheckbox = this instanceof CKEDITOR.ui.dialog.checkbox; - if ( iframeNode.hasAttribute( this.id ) ) { - var value = iframeNode.getAttribute( this.id ); - if ( isCheckbox ) - this.setValue( checkboxValues[ this.id ][ 'true' ] == value.toLowerCase() ); - else - this.setValue( value ); - } - } - - function commitValue( iframeNode ) { - var isRemove = this.getValue() === '', - isCheckbox = this instanceof CKEDITOR.ui.dialog.checkbox, - value = this.getValue(); - if ( isRemove ) - iframeNode.removeAttribute( this.att || this.id ); - else if ( isCheckbox ) - iframeNode.setAttribute( this.id, checkboxValues[ this.id ][ value ] ); - else - iframeNode.setAttribute( this.att || this.id, value ); - } - - CKEDITOR.dialog.add( 'iframe', function( editor ) { - var iframeLang = editor.lang.iframe, - commonLang = editor.lang.common, - dialogadvtab = editor.plugins.dialogadvtab; - return { - title: iframeLang.title, - minWidth: 350, - minHeight: 260, - onShow: function() { - // Clear previously saved elements. - this.fakeImage = this.iframeNode = null; - - var fakeImage = this.getSelectedElement(); - if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'iframe' ) { - this.fakeImage = fakeImage; - - var iframeNode = editor.restoreRealElement( fakeImage ); - this.iframeNode = iframeNode; - - this.setupContent( iframeNode ); - } - }, - onOk: function() { - var iframeNode; - if ( !this.fakeImage ) - iframeNode = new CKEDITOR.dom.element( 'iframe' ); - else - iframeNode = this.iframeNode; - - // A subset of the specified attributes/styles - // should also be applied on the fake element to - // have better visual effect. (#5240) - var extraStyles = {}, - extraAttributes = {}; - this.commitContent( iframeNode, extraStyles, extraAttributes ); - - // Refresh the fake image. - var newFakeImage = editor.createFakeElement( iframeNode, 'cke_iframe', 'iframe', true ); - newFakeImage.setAttributes( extraAttributes ); - newFakeImage.setStyles( extraStyles ); - if ( this.fakeImage ) { - newFakeImage.replace( this.fakeImage ); - editor.getSelection().selectElement( newFakeImage ); - } else - editor.insertElement( newFakeImage ); - }, - contents: [ - { - id: 'info', - label: commonLang.generalTab, - accessKey: 'I', - elements: [ - { - type: 'vbox', - padding: 0, - children: [ - { - id: 'src', - type: 'text', - label: commonLang.url, - required: true, - validate: CKEDITOR.dialog.validate.notEmpty( iframeLang.noUrl ), - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'hbox', - children: [ - { - id: 'width', - type: 'text', - requiredContent: 'iframe[width]', - style: 'width:100%', - labelLayout: 'vertical', - label: commonLang.width, - validate: CKEDITOR.dialog.validate.htmlLength( commonLang.invalidHtmlLength.replace( '%1', commonLang.width ) ), - setup: loadValue, - commit: commitValue - }, - { - id: 'height', - type: 'text', - requiredContent: 'iframe[height]', - style: 'width:100%', - labelLayout: 'vertical', - label: commonLang.height, - validate: CKEDITOR.dialog.validate.htmlLength( commonLang.invalidHtmlLength.replace( '%1', commonLang.height ) ), - setup: loadValue, - commit: commitValue - }, - { - id: 'align', - type: 'select', - requiredContent: 'iframe[align]', - 'default': '', - items: [ - [ commonLang.notSet, '' ], - [ commonLang.alignLeft, 'left' ], - [ commonLang.alignRight, 'right' ], - [ commonLang.alignTop, 'top' ], - [ commonLang.alignMiddle, 'middle' ], - [ commonLang.alignBottom, 'bottom' ] - ], - style: 'width:100%', - labelLayout: 'vertical', - label: commonLang.align, - setup: function( iframeNode, fakeImage ) { - loadValue.apply( this, arguments ); - if ( fakeImage ) { - var fakeImageAlign = fakeImage.getAttribute( 'align' ); - this.setValue( fakeImageAlign && fakeImageAlign.toLowerCase() || '' ); - } - }, - commit: function( iframeNode, extraStyles, extraAttributes ) { - commitValue.apply( this, arguments ); - if ( this.getValue() ) - extraAttributes.align = this.getValue(); - } - } - ] - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'scrolling', - type: 'checkbox', - requiredContent: 'iframe[scrolling]', - label: iframeLang.scrolling, - setup: loadValue, - commit: commitValue - }, - { - id: 'frameborder', - type: 'checkbox', - requiredContent: 'iframe[frameborder]', - label: iframeLang.border, - setup: loadValue, - commit: commitValue - } - ] - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - id: 'name', - type: 'text', - requiredContent: 'iframe[name]', - label: commonLang.name, - setup: loadValue, - commit: commitValue - }, - { - id: 'title', - type: 'text', - requiredContent: 'iframe[title]', - label: commonLang.advisoryTitle, - setup: loadValue, - commit: commitValue - } - ] - }, - { - id: 'longdesc', - type: 'text', - requiredContent: 'iframe[longdesc]', - label: commonLang.longDescr, - setup: loadValue, - commit: commitValue - } - ] - }, - dialogadvtab && dialogadvtab.createAdvancedTab( editor, { id:1,classes:1,styles:1 }, 'iframe' ) - ] - }; - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/iframe/icons/hidpi/iframe.png b/addons/website/static/lib/ckeditor/plugins/iframe/icons/hidpi/iframe.png Binary files differdeleted file mode 100644 index ff17604da22..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframe/icons/hidpi/iframe.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/iframe/icons/iframe.png b/addons/website/static/lib/ckeditor/plugins/iframe/icons/iframe.png Binary files differdeleted file mode 100644 index f72d191553f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframe/icons/iframe.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/iframe/lang/en.js b/addons/website/static/lib/ckeditor/plugins/iframe/lang/en.js deleted file mode 100644 index 95c12de56fb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframe/lang/en.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'iframe', 'en', { - border: 'Show frame border', - noUrl: 'Please type the iframe URL', - scrolling: 'Enable scrollbars', - title: 'IFrame Properties', - toolbar: 'IFrame' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/iframe/plugin.js b/addons/website/static/lib/ckeditor/plugins/iframe/plugin.js deleted file mode 100644 index 2ae1f064b57..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframe/plugin.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.add( 'iframe', { - requires: 'dialog,fakeobjects', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'iframe', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - CKEDITOR.addCss( 'img.cke_iframe' + - '{' + - 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/placeholder.png' ) + ');' + - 'background-position: center center;' + - 'background-repeat: no-repeat;' + - 'border: 1px solid #a9a9a9;' + - 'width: 80px;' + - 'height: 80px;' + - '}' - ); - }, - init: function( editor ) { - var pluginName = 'iframe', - lang = editor.lang.iframe, - allowed = 'iframe[align,longdesc,frameborder,height,name,scrolling,src,title,width]'; - - if ( editor.plugins.dialogadvtab ) - allowed += ';iframe' + editor.plugins.dialogadvtab.allowedContent( { id:1,classes:1,styles:1 } ); - - CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/iframe.js' ); - editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName, { - allowedContent: allowed, - requiredContent: 'iframe' - } ) ); - - editor.ui.addButton && editor.ui.addButton( 'Iframe', { - label: lang.toolbar, - command: pluginName, - toolbar: 'insert,80' - }); - - editor.on( 'doubleclick', function( evt ) { - var element = evt.data.element; - if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'iframe' ) - evt.data.dialog = 'iframe'; - }); - - if ( editor.addMenuItems ) { - editor.addMenuItems({ - iframe: { - label: lang.title, - command: 'iframe', - group: 'image' - } - }); - } - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - if ( element && element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'iframe' ) - return { iframe: CKEDITOR.TRISTATE_OFF }; - }); - } - }, - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter; - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - iframe: function( element ) { - return editor.createFakeParserElement( element, 'cke_iframe', 'iframe', true ); - } - } - }); - } - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/iframedialog/plugin.js b/addons/website/static/lib/ckeditor/plugins/iframedialog/plugin.js deleted file mode 100644 index 41863674d64..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/iframedialog/plugin.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Plugin for making iframe based dialogs. - */ - -CKEDITOR.plugins.add( 'iframedialog', { - requires: 'dialog', - onLoad: function() { - /** - * An iframe base dialog. - * - * @static - * @member CKEDITOR.dialog - * @param {String} name Name of the dialog. - * @param {String} title Title of the dialog. - * @param {Number} minWidth Minimum width of the dialog. - * @param {Number} minHeight Minimum height of the dialog. - * @param {Function} [onContentLoad] Function called when the iframe has been loaded. - * If it isn't specified, the inner frame is notified of the dialog events (`'load'`, - * `'resize'`, `'ok'` and `'cancel'`) on a function called `'onDialogEvent'`. - * @param {Object} [userDefinition] Additional properties for the dialog definition. - */ - CKEDITOR.dialog.addIframe = function( name, title, src, minWidth, minHeight, onContentLoad, userDefinition ) { - var element = { - type: 'iframe', - src: src, - width: '100%', - height: '100%' - }; - - if ( typeof( onContentLoad ) == 'function' ) - element.onContentLoad = onContentLoad; - else - element.onContentLoad = function() { - var element = this.getElement(), - childWindow = element.$.contentWindow; - - // If the inner frame has defined a "onDialogEvent" function, setup listeners - if ( childWindow.onDialogEvent ) { - var dialog = this.getDialog(), - notifyEvent = function( e ) { - return childWindow.onDialogEvent( e ); - }; - - dialog.on( 'ok', notifyEvent ); - dialog.on( 'cancel', notifyEvent ); - dialog.on( 'resize', notifyEvent ); - - // Clear listeners - dialog.on( 'hide', function( e ) { - dialog.removeListener( 'ok', notifyEvent ); - dialog.removeListener( 'cancel', notifyEvent ); - dialog.removeListener( 'resize', notifyEvent ); - - e.removeListener(); - }); - - // Notify child iframe of load: - childWindow.onDialogEvent({ - name: 'load', - sender: this, - editor: dialog._.editor - }); - } - }; - - var definition = { - title: title, - minWidth: minWidth, - minHeight: minHeight, - contents: [ - { - id: 'iframe', - label: title, - expand: true, - elements: [ element ], - style: 'width:' + element.width + ';height:' + element.height - } - ] - }; - - for ( var i in userDefinition ) - definition[ i ] = userDefinition[ i ]; - - this.add( name, function() { - return definition; - }); - }; - - (function() { - /** - * An iframe element. - * - * @class CKEDITOR.ui.dialog.iframeElement - * @extends CKEDITOR.ui.dialog.uiElement - * @constructor - * @private - * @param {CKEDITOR.dialog} dialog Parent dialog object. - * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition - * The element definition. Accepted fields: - * - * * `src` (Required) The src field of the iframe. - * * `width` (Required) The iframe's width. - * * `height` (Required) The iframe's height. - * * `onContentLoad` (Optional) A function to be executed - * after the iframe's contents has finished loading. - * - * @param {Array} htmlList List of HTML code to output to. - */ - var iframeElement = function( dialog, elementDefinition, htmlList ) { - if ( arguments.length < 3 ) - return; - - var _ = ( this._ || ( this._ = {} ) ), - contentLoad = elementDefinition.onContentLoad && CKEDITOR.tools.bind( elementDefinition.onContentLoad, this ), - cssWidth = CKEDITOR.tools.cssLength( elementDefinition.width ), - cssHeight = CKEDITOR.tools.cssLength( elementDefinition.height ); - _.frameId = CKEDITOR.tools.getNextId() + '_iframe'; - - // IE BUG: Parent container does not resize to contain the iframe automatically. - dialog.on( 'load', function() { - var iframe = CKEDITOR.document.getById( _.frameId ), - parentContainer = iframe.getParent(); - - parentContainer.setStyles({ - width: cssWidth, - height: cssHeight - }); - }); - - var attributes = { - src: '%2', - id: _.frameId, - frameborder: 0, - allowtransparency: true - }; - var myHtml = []; - - if ( typeof( elementDefinition.onContentLoad ) == 'function' ) - attributes.onload = 'CKEDITOR.tools.callFunction(%1);'; - - CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, myHtml, 'iframe', { - width: cssWidth, - height: cssHeight - }, attributes, '' ); - - // Put a placeholder for the first time. - htmlList.push( '<div style="width:' + cssWidth + ';height:' + cssHeight + ';" id="' + this.domId + '"></div>' ); - - // Iframe elements should be refreshed whenever it is shown. - myHtml = myHtml.join( '' ); - dialog.on( 'show', function() { - var iframe = CKEDITOR.document.getById( _.frameId ), - parentContainer = iframe.getParent(), - callIndex = CKEDITOR.tools.addFunction( contentLoad ), - html = myHtml.replace( '%1', callIndex ).replace( '%2', CKEDITOR.tools.htmlEncode( elementDefinition.src ) ); - parentContainer.setHtml( html ); - }); - }; - - iframeElement.prototype = new CKEDITOR.ui.dialog.uiElement; - - CKEDITOR.dialog.addUIElement( 'iframe', { - build: function( dialog, elementDefinition, output ) { - return new iframeElement( dialog, elementDefinition, output ); - } - }); - })(); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/image/dialogs/image.js b/addons/website/static/lib/ckeditor/plugins/image/dialogs/image.js deleted file mode 100644 index df5cc4c46b5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image/dialogs/image.js +++ /dev/null @@ -1,1216 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var imageDialog = function( editor, dialogType ) { - // Load image preview. - var IMAGE = 1, - LINK = 2, - PREVIEW = 4, - CLEANUP = 8, - regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i, - regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i, - pxLengthRegex = /^\d+px$/; - - var onSizeChange = function() { - var value = this.getValue(), - // This = input element. - dialog = this.getDialog(), - aMatch = value.match( regexGetSize ); // Check value - if ( aMatch ) { - if ( aMatch[ 2 ] == '%' ) // % is allowed - > unlock ratio. - switchLockRatio( dialog, false ); // Unlock. - value = aMatch[ 1 ]; - } - - // Only if ratio is locked - if ( dialog.lockRatio ) { - var oImageOriginal = dialog.originalElement; - if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { - if ( this.id == 'txtHeight' ) { - if ( value && value != '0' ) - value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) ); - if ( !isNaN( value ) ) - dialog.setValueOf( 'info', 'txtWidth', value ); - } else //this.id = txtWidth. - { - if ( value && value != '0' ) - value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) ); - if ( !isNaN( value ) ) - dialog.setValueOf( 'info', 'txtHeight', value ); - } - } - } - updatePreview( dialog ); - }; - - var updatePreview = function( dialog ) { - //Don't load before onShow. - if ( !dialog.originalElement || !dialog.preview ) - return 1; - - // Read attributes and update imagePreview; - dialog.commitContent( PREVIEW, dialog.preview ); - return 0; - }; - - // Custom commit dialog logic, where we're intended to give inline style - // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute - // by other fields. - function commitContent() { - var args = arguments; - var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' ); - inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args ); - - this.foreach( function( widget ) { - if ( widget.commit && widget.id != 'txtdlgGenStyle' ) - widget.commit.apply( widget, args ); - }); - } - - // Avoid recursions. - var incommit; - - // Synchronous field values to other impacted fields is required, e.g. border - // size change should alter inline-style text as well. - function commitInternally( targetFields ) { - if ( incommit ) - return; - - incommit = 1; - - var dialog = this.getDialog(), - element = dialog.imageElement; - if ( element ) { - // Commit this field and broadcast to target fields. - this.commit( IMAGE, element ); - - targetFields = [].concat( targetFields ); - var length = targetFields.length, - field; - for ( var i = 0; i < length; i++ ) { - field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) ); - // May cause recursion. - field && field.setup( IMAGE, element ); - } - } - - incommit = 0; - } - - var switchLockRatio = function( dialog, value ) { - if ( !dialog.getContentElement( 'info', 'ratioLock' ) ) - return null; - - var oImageOriginal = dialog.originalElement; - - // Dialog may already closed. (#5505) - if ( !oImageOriginal ) - return null; - - // Check image ratio and original image ratio, but respecting user's preference. - if ( value == 'check' ) { - if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { - var width = dialog.getValueOf( 'info', 'txtWidth' ), - height = dialog.getValueOf( 'info', 'txtHeight' ), - originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height, - thisRatio = width * 1000 / height; - dialog.lockRatio = false; // Default: unlock ratio - - if ( !width && !height ) - dialog.lockRatio = true; - else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) ) { - if ( Math.round( originalRatio ) == Math.round( thisRatio ) ) - dialog.lockRatio = true; - } - } - } else if ( value != undefined ) - dialog.lockRatio = value; - else { - dialog.userlockRatio = 1; - dialog.lockRatio = !dialog.lockRatio; - } - - var ratioButton = CKEDITOR.document.getById( btnLockSizesId ); - if ( dialog.lockRatio ) - ratioButton.removeClass( 'cke_btn_unlocked' ); - else - ratioButton.addClass( 'cke_btn_unlocked' ); - - ratioButton.setAttribute( 'aria-checked', dialog.lockRatio ); - - // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE - if ( CKEDITOR.env.hc ) { - var icon = ratioButton.getChild( 0 ); - icon.setHtml( dialog.lockRatio ? CKEDITOR.env.ie ? '\u25A0' : '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' ); - } - - return dialog.lockRatio; - }; - - var resetSize = function( dialog ) { - var oImageOriginal = dialog.originalElement; - if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { - var widthField = dialog.getContentElement( 'info', 'txtWidth' ), - heightField = dialog.getContentElement( 'info', 'txtHeight' ); - widthField && widthField.setValue( oImageOriginal.$.width ); - heightField && heightField.setValue( oImageOriginal.$.height ); - } - updatePreview( dialog ); - }; - - var setupDimension = function( type, element ) { - if ( type != IMAGE ) - return; - - function checkDimension( size, defaultValue ) { - var aMatch = size.match( regexGetSize ); - if ( aMatch ) { - if ( aMatch[ 2 ] == '%' ) // % is allowed. - { - aMatch[ 1 ] += '%'; - switchLockRatio( dialog, false ); // Unlock ratio - } - return aMatch[ 1 ]; - } - return defaultValue; - } - - var dialog = this.getDialog(), - value = '', - dimension = this.id == 'txtWidth' ? 'width' : 'height', - size = element.getAttribute( dimension ); - - if ( size ) - value = checkDimension( size, value ); - value = checkDimension( element.getStyle( dimension ), value ); - - this.setValue( value ); - }; - - var previewPreloader; - - var onImgLoadEvent = function() { - // Image is ready. - var original = this.originalElement; - original.setCustomData( 'isReady', 'true' ); - original.removeListener( 'load', onImgLoadEvent ); - original.removeListener( 'error', onImgLoadErrorEvent ); - original.removeListener( 'abort', onImgLoadErrorEvent ); - - // Hide loader - CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); - - // New image -> new domensions - if ( !this.dontResetSize ) - resetSize( this ); - - if ( this.firstLoad ) - CKEDITOR.tools.setTimeout( function() { - switchLockRatio( this, 'check' ); - }, 0, this ); - - this.firstLoad = false; - this.dontResetSize = false; - }; - - var onImgLoadErrorEvent = function() { - // Error. Image is not loaded. - var original = this.originalElement; - original.removeListener( 'load', onImgLoadEvent ); - original.removeListener( 'error', onImgLoadErrorEvent ); - original.removeListener( 'abort', onImgLoadErrorEvent ); - - // Set Error image. - var noimage = CKEDITOR.getUrl( CKEDITOR.plugins.get( 'image' ).path + 'images/noimage.png' ); - - if ( this.preview ) - this.preview.setAttribute( 'src', noimage ); - - // Hide loader - CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); - switchLockRatio( this, false ); // Unlock. - }; - - var numbering = function( id ) { - return CKEDITOR.tools.getNextId() + '_' + id; - }, - btnLockSizesId = numbering( 'btnLockSizes' ), - btnResetSizeId = numbering( 'btnResetSize' ), - imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ), - previewLinkId = numbering( 'previewLink' ), - previewImageId = numbering( 'previewImage' ); - - return { - title: editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ], - minWidth: 420, - minHeight: 360, - onShow: function() { - this.imageElement = false; - this.linkElement = false; - - // Default: create a new element. - this.imageEditMode = false; - this.linkEditMode = false; - - this.lockRatio = true; - this.userlockRatio = 0; - this.dontResetSize = false; - this.firstLoad = true; - this.addLink = false; - - var editor = this.getParentEditor(), - sel = editor.getSelection(), - element = sel && sel.getSelectedElement(), - link = element && editor.elementPath( element ).contains( 'a', 1 ); - - //Hide loader. - CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); - // Create the preview before setup the dialog contents. - previewPreloader = new CKEDITOR.dom.element( 'img', editor.document ); - this.preview = CKEDITOR.document.getById( previewImageId ); - - // Copy of the image - this.originalElement = editor.document.createElement( 'img' ); - this.originalElement.setAttribute( 'alt', '' ); - this.originalElement.setCustomData( 'isReady', 'false' ); - - if ( link ) { - this.linkElement = link; - this.linkEditMode = true; - - // Look for Image element. - var linkChildren = link.getChildren(); - if ( linkChildren.count() == 1 ) // 1 child. - { - var childTagName = linkChildren.getItem( 0 ).getName(); - if ( childTagName == 'img' || childTagName == 'input' ) { - this.imageElement = linkChildren.getItem( 0 ); - if ( this.imageElement.getName() == 'img' ) - this.imageEditMode = 'img'; - else if ( this.imageElement.getName() == 'input' ) - this.imageEditMode = 'input'; - } - } - // Fill out all fields. - if ( dialogType == 'image' ) - this.setupContent( LINK, link ); - } - - // Edit given image element instead the one from selection. - if ( this.customImageElement ) { - this.imageEditMode = 'img'; - this.imageElement = this.customImageElement; - delete this.customImageElement; - } - else if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' ) || - element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' ) { - this.imageEditMode = element.getName(); - this.imageElement = element; - } - - if ( this.imageEditMode ) { - // Use the original element as a buffer from since we don't want - // temporary changes to be committed, e.g. if the dialog is canceled. - this.cleanImageElement = this.imageElement; - this.imageElement = this.cleanImageElement.clone( true, true ); - - // Fill out all fields. - this.setupContent( IMAGE, this.imageElement ); - } else - this.imageElement = editor.document.createElement( 'img' ); - - // Refresh LockRatio button - switchLockRatio( this, true ); - - // Dont show preview if no URL given. - if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) ) { - this.preview.removeAttribute( 'src' ); - this.preview.setStyle( 'display', 'none' ); - } - }, - onOk: function() { - // Edit existing Image. - if ( this.imageEditMode ) { - var imgTagName = this.imageEditMode; - - // Image dialog and Input element. - if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) ) { - // Replace INPUT-> IMG - imgTagName = 'img'; - this.imageElement = editor.document.createElement( 'img' ); - this.imageElement.setAttribute( 'alt', '' ); - editor.insertElement( this.imageElement ); - } - // ImageButton dialog and Image element. - else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ) ) { - // Replace IMG -> INPUT - imgTagName = 'input'; - this.imageElement = editor.document.createElement( 'input' ); - this.imageElement.setAttributes({ - type: 'image', - alt: '' - }); - editor.insertElement( this.imageElement ); - } else { - // Restore the original element before all commits. - this.imageElement = this.cleanImageElement; - delete this.cleanImageElement; - } - } else // Create a new image. - { - // Image dialog -> create IMG element. - if ( dialogType == 'image' ) - this.imageElement = editor.document.createElement( 'img' ); - else { - this.imageElement = editor.document.createElement( 'input' ); - this.imageElement.setAttribute( 'type', 'image' ); - } - this.imageElement.setAttribute( 'alt', '' ); - } - - // Create a new link. - if ( !this.linkEditMode ) - this.linkElement = editor.document.createElement( 'a' ); - - // Set attributes. - this.commitContent( IMAGE, this.imageElement ); - this.commitContent( LINK, this.linkElement ); - - // Remove empty style attribute. - if ( !this.imageElement.getAttribute( 'style' ) ) - this.imageElement.removeAttribute( 'style' ); - - // Insert a new Image. - if ( !this.imageEditMode ) { - if ( this.addLink ) { - //Insert a new Link. - if ( !this.linkEditMode ) { - editor.insertElement( this.linkElement ); - this.linkElement.append( this.imageElement, false ); - } else //Link already exists, image not. - editor.insertElement( this.imageElement ); - } else - editor.insertElement( this.imageElement ); - } else // Image already exists. - { - //Add a new link element. - if ( !this.linkEditMode && this.addLink ) { - editor.insertElement( this.linkElement ); - this.imageElement.appendTo( this.linkElement ); - } - //Remove Link, Image exists. - else if ( this.linkEditMode && !this.addLink ) { - editor.getSelection().selectElement( this.linkElement ); - editor.insertElement( this.imageElement ); - } - } - }, - onLoad: function() { - if ( dialogType != 'image' ) - this.hidePage( 'Link' ); //Hide Link tab. - var doc = this._.element.getDocument(); - - if ( this.getContentElement( 'info', 'ratioLock' ) ) { - this.addFocusable( doc.getById( btnResetSizeId ), 5 ); - this.addFocusable( doc.getById( btnLockSizesId ), 5 ); - } - - this.commitContent = commitContent; - }, - onHide: function() { - if ( this.preview ) - this.commitContent( CLEANUP, this.preview ); - - if ( this.originalElement ) { - this.originalElement.removeListener( 'load', onImgLoadEvent ); - this.originalElement.removeListener( 'error', onImgLoadErrorEvent ); - this.originalElement.removeListener( 'abort', onImgLoadErrorEvent ); - this.originalElement.remove(); - this.originalElement = false; // Dialog is closed. - } - - delete this.imageElement; - }, - contents: [ - { - id: 'info', - label: editor.lang.image.infoTab, - accessKey: 'I', - elements: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'hbox', - widths: [ '280px', '110px' ], - align: 'right', - children: [ - { - id: 'txtUrl', - type: 'text', - label: editor.lang.common.url, - required: true, - onChange: function() { - var dialog = this.getDialog(), - newUrl = this.getValue(); - - //Update original image - if ( newUrl.length > 0 ) //Prevent from load before onShow - { - dialog = this.getDialog(); - var original = dialog.originalElement; - - dialog.preview.removeStyle( 'display' ); - - original.setCustomData( 'isReady', 'false' ); - // Show loader - var loader = CKEDITOR.document.getById( imagePreviewLoaderId ); - if ( loader ) - loader.setStyle( 'display', '' ); - - original.on( 'load', onImgLoadEvent, dialog ); - original.on( 'error', onImgLoadErrorEvent, dialog ); - original.on( 'abort', onImgLoadErrorEvent, dialog ); - original.setAttribute( 'src', newUrl ); - - // Query the preloader to figure out the url impacted by based href. - previewPreloader.setAttribute( 'src', newUrl ); - dialog.preview.setAttribute( 'src', previewPreloader.$.src ); - updatePreview( dialog ); - } - // Dont show preview if no URL given. - else if ( dialog.preview ) { - dialog.preview.removeAttribute( 'src' ); - dialog.preview.setStyle( 'display', 'none' ); - } - }, - setup: function( type, element ) { - if ( type == IMAGE ) { - var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' ); - var field = this; - - this.getDialog().dontResetSize = true; - - field.setValue( url ); // And call this.onChange() - // Manually set the initial value.(#4191) - field.setInitValue(); - } - }, - commit: function( type, element ) { - if ( type == IMAGE && ( this.getValue() || this.isChanged() ) ) { - element.data( 'cke-saved-src', this.getValue() ); - element.setAttribute( 'src', this.getValue() ); - } else if ( type == CLEANUP ) { - element.setAttribute( 'src', '' ); // If removeAttribute doesn't work. - element.removeAttribute( 'src' ); - } - }, - validate: CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing ) - }, - { - type: 'button', - id: 'browse', - // v-align with the 'txtUrl' field. - // TODO: We need something better than a fixed size here. - style: 'display:inline-block;margin-top:10px;', - align: 'center', - label: editor.lang.common.browseServer, - hidden: true, - filebrowser: 'info:txtUrl' - } - ] - } - ] - }, - { - id: 'txtAlt', - type: 'text', - label: editor.lang.image.alt, - accessKey: 'T', - 'default': '', - onChange: function() { - updatePreview( this.getDialog() ); - }, - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'alt' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'alt', this.getValue() ); - } else if ( type == PREVIEW ) { - element.setAttribute( 'alt', this.getValue() ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'alt' ); - } - } - }, - { - type: 'hbox', - children: [ - { - id: 'basic', - type: 'vbox', - children: [ - { - type: 'hbox', - requiredContent: 'img{width,height}', - widths: [ '50%', '50%' ], - children: [ - { - type: 'vbox', - padding: 1, - children: [ - { - type: 'text', - width: '45px', - id: 'txtWidth', - label: editor.lang.common.width, - onKeyUp: onSizeChange, - onChange: function() { - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - validate: function() { - var aMatch = this.getValue().match( regexGetSizeOrEmpty ), - isValid = !!( aMatch && parseInt( aMatch[ 1 ], 10 ) !== 0 ); - if ( !isValid ) - alert( editor.lang.common.invalidWidth ); - return isValid; - }, - setup: setupDimension, - commit: function( type, element, internalCommit ) { - var value = this.getValue(); - if ( type == IMAGE ) { - if ( value ) - element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) ); - else - element.removeStyle( 'width' ); - - !internalCommit && element.removeAttribute( 'width' ); - } else if ( type == PREVIEW ) { - var aMatch = value.match( regexGetSize ); - if ( !aMatch ) { - var oImageOriginal = this.getDialog().originalElement; - if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) - element.setStyle( 'width', oImageOriginal.$.width + 'px' ); - } else - element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'width' ); - element.removeStyle( 'width' ); - } - } - }, - { - type: 'text', - id: 'txtHeight', - width: '45px', - label: editor.lang.common.height, - onKeyUp: onSizeChange, - onChange: function() { - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - validate: function() { - var aMatch = this.getValue().match( regexGetSizeOrEmpty ), - isValid = !!( aMatch && parseInt( aMatch[ 1 ], 10 ) !== 0 ); - if ( !isValid ) - alert( editor.lang.common.invalidHeight ); - return isValid; - }, - setup: setupDimension, - commit: function( type, element, internalCommit ) { - var value = this.getValue(); - if ( type == IMAGE ) { - if ( value ) - element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) ); - else - element.removeStyle( 'height' ); - - !internalCommit && element.removeAttribute( 'height' ); - } else if ( type == PREVIEW ) { - var aMatch = value.match( regexGetSize ); - if ( !aMatch ) { - var oImageOriginal = this.getDialog().originalElement; - if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) - element.setStyle( 'height', oImageOriginal.$.height + 'px' ); - } else - element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'height' ); - element.removeStyle( 'height' ); - } - } - } - ] - }, - { - id: 'ratioLock', - type: 'html', - style: 'margin-top:30px;width:40px;height:40px;', - onLoad: function() { - // Activate Reset button - var resetButton = CKEDITOR.document.getById( btnResetSizeId ), - ratioButton = CKEDITOR.document.getById( btnLockSizesId ); - if ( resetButton ) { - resetButton.on( 'click', function( evt ) { - resetSize( this ); - evt.data && evt.data.preventDefault(); - }, this.getDialog() ); - resetButton.on( 'mouseover', function() { - this.addClass( 'cke_btn_over' ); - }, resetButton ); - resetButton.on( 'mouseout', function() { - this.removeClass( 'cke_btn_over' ); - }, resetButton ); - } - // Activate (Un)LockRatio button - if ( ratioButton ) { - ratioButton.on( 'click', function( evt ) { - var locked = switchLockRatio( this ), - oImageOriginal = this.originalElement, - width = this.getValueOf( 'info', 'txtWidth' ); - - if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width ) { - var height = oImageOriginal.$.height / oImageOriginal.$.width * width; - if ( !isNaN( height ) ) { - this.setValueOf( 'info', 'txtHeight', Math.round( height ) ); - updatePreview( this ); - } - } - evt.data && evt.data.preventDefault(); - }, this.getDialog() ); - ratioButton.on( 'mouseover', function() { - this.addClass( 'cke_btn_over' ); - }, ratioButton ); - ratioButton.on( 'mouseout', function() { - this.removeClass( 'cke_btn_over' ); - }, ratioButton ); - } - }, - html: '<div>' + - '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio + - '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor.lang.image.lockRatio + '</span></a>' + - '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize + - '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>' + - '</div>' - } - ] - }, - { - type: 'vbox', - padding: 1, - children: [ - { - type: 'text', - id: 'txtBorder', - requiredContent: 'img{border-width}', - width: '60px', - label: editor.lang.image.border, - 'default': '', - onKeyUp: function() { - updatePreview( this.getDialog() ); - }, - onChange: function() { - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ), - setup: function( type, element ) { - if ( type == IMAGE ) { - var value, - borderStyle = element.getStyle( 'border-width' ); - borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ ); - value = borderStyle && parseInt( borderStyle[ 1 ], 10 ); - isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) ); - this.setValue( value ); - } - }, - commit: function( type, element, internalCommit ) { - var value = parseInt( this.getValue(), 10 ); - if ( type == IMAGE || type == PREVIEW ) { - if ( !isNaN( value ) ) { - element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) ); - element.setStyle( 'border-style', 'solid' ); - } else if ( !value && this.isChanged() ) - element.removeStyle( 'border' ); - - if ( !internalCommit && type == IMAGE ) - element.removeAttribute( 'border' ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'border' ); - element.removeStyle( 'border-width' ); - element.removeStyle( 'border-style' ); - element.removeStyle( 'border-color' ); - } - } - }, - { - type: 'text', - id: 'txtHSpace', - requiredContent: 'img{margin-left,margin-right}', - width: '60px', - label: editor.lang.image.hSpace, - 'default': '', - onKeyUp: function() { - updatePreview( this.getDialog() ); - }, - onChange: function() { - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ), - setup: function( type, element ) { - if ( type == IMAGE ) { - var value, marginLeftPx, marginRightPx, - marginLeftStyle = element.getStyle( 'margin-left' ), - marginRightStyle = element.getStyle( 'margin-right' ); - - marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex ); - marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex ); - marginLeftPx = parseInt( marginLeftStyle, 10 ); - marginRightPx = parseInt( marginRightStyle, 10 ); - - value = ( marginLeftPx == marginRightPx ) && marginLeftPx; - isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) ); - - this.setValue( value ); - } - }, - commit: function( type, element, internalCommit ) { - var value = parseInt( this.getValue(), 10 ); - if ( type == IMAGE || type == PREVIEW ) { - if ( !isNaN( value ) ) { - element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) ); - element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) ); - } else if ( !value && this.isChanged() ) { - element.removeStyle( 'margin-left' ); - element.removeStyle( 'margin-right' ); - } - - if ( !internalCommit && type == IMAGE ) - element.removeAttribute( 'hspace' ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'hspace' ); - element.removeStyle( 'margin-left' ); - element.removeStyle( 'margin-right' ); - } - } - }, - { - type: 'text', - id: 'txtVSpace', - requiredContent: 'img{margin-top,margin-bottom}', - width: '60px', - label: editor.lang.image.vSpace, - 'default': '', - onKeyUp: function() { - updatePreview( this.getDialog() ); - }, - onChange: function() { - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ), - setup: function( type, element ) { - if ( type == IMAGE ) { - var value, marginTopPx, marginBottomPx, - marginTopStyle = element.getStyle( 'margin-top' ), - marginBottomStyle = element.getStyle( 'margin-bottom' ); - - marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex ); - marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex ); - marginTopPx = parseInt( marginTopStyle, 10 ); - marginBottomPx = parseInt( marginBottomStyle, 10 ); - - value = ( marginTopPx == marginBottomPx ) && marginTopPx; - isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) ); - this.setValue( value ); - } - }, - commit: function( type, element, internalCommit ) { - var value = parseInt( this.getValue(), 10 ); - if ( type == IMAGE || type == PREVIEW ) { - if ( !isNaN( value ) ) { - element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) ); - element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) ); - } else if ( !value && this.isChanged() ) { - element.removeStyle( 'margin-top' ); - element.removeStyle( 'margin-bottom' ); - } - - if ( !internalCommit && type == IMAGE ) - element.removeAttribute( 'vspace' ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'vspace' ); - element.removeStyle( 'margin-top' ); - element.removeStyle( 'margin-bottom' ); - } - } - }, - { - id: 'cmbAlign', - requiredContent: 'img{float}', - type: 'select', - widths: [ '35%', '65%' ], - style: 'width:90px', - label: editor.lang.common.align, - 'default': '', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.alignLeft, 'left' ], - [ editor.lang.common.alignRight, 'right' ] - // Backward compatible with v2 on setup when specified as attribute value, - // while these values are no more available as select options. - // [ editor.lang.image.alignAbsBottom , 'absBottom'], - // [ editor.lang.image.alignAbsMiddle , 'absMiddle'], - // [ editor.lang.image.alignBaseline , 'baseline'], - // [ editor.lang.image.alignTextTop , 'text-top'], - // [ editor.lang.image.alignBottom , 'bottom'], - // [ editor.lang.image.alignMiddle , 'middle'], - // [ editor.lang.image.alignTop , 'top'] - ], - onChange: function() { - updatePreview( this.getDialog() ); - commitInternally.call( this, 'advanced:txtdlgGenStyle' ); - }, - setup: function( type, element ) { - if ( type == IMAGE ) { - var value = element.getStyle( 'float' ); - switch ( value ) { - // Ignore those unrelated values. - case 'inherit': - case 'none': - value = ''; - } - - !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() ); - this.setValue( value ); - } - }, - commit: function( type, element, internalCommit ) { - var value = this.getValue(); - if ( type == IMAGE || type == PREVIEW ) { - if ( value ) - element.setStyle( 'float', value ); - else - element.removeStyle( 'float' ); - - if ( !internalCommit && type == IMAGE ) { - value = ( element.getAttribute( 'align' ) || '' ).toLowerCase(); - switch ( value ) { - // we should remove it only if it matches "left" or "right", - // otherwise leave it intact. - case 'left': - case 'right': - element.removeAttribute( 'align' ); - } - } - } else if ( type == CLEANUP ) - element.removeStyle( 'float' ); - - } - } - ] - } - ] - }, - { - type: 'vbox', - height: '250px', - children: [ - { - type: 'html', - id: 'htmlPreview', - style: 'width:95%;', - html: '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) + '<br>' + - '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>' + - '<div class="ImagePreviewBox"><table><tr><td>' + - '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">' + - '<img id="' + previewImageId + '" alt="" /></a>' + - ( editor.config.image_previewText || 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' + - 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, ' + - 'nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. Nunc imperdiet gravida mauris.' ) + - '</td></tr></table></div></div>' - } - ] - } - ] - } - ] - }, - { - id: 'Link', - requiredContent: 'a[href]', - label: editor.lang.image.linkTab, - padding: 0, - elements: [ - { - id: 'txtUrl', - type: 'text', - label: editor.lang.common.url, - style: 'width: 100%', - 'default': '', - setup: function( type, element ) { - if ( type == LINK ) { - var href = element.data( 'cke-saved-href' ); - if ( !href ) - href = element.getAttribute( 'href' ); - this.setValue( href ); - } - }, - commit: function( type, element ) { - if ( type == LINK ) { - if ( this.getValue() || this.isChanged() ) { - var url = decodeURI( this.getValue() ); - element.data( 'cke-saved-href', url ); - element.setAttribute( 'href', url ); - - if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL ) - this.getDialog().addLink = true; - } - } - } - }, - { - type: 'button', - id: 'browse', - filebrowser: { - action: 'Browse', - target: 'Link:txtUrl', - url: editor.config.filebrowserImageBrowseLinkUrl - }, - style: 'float:right', - hidden: true, - label: editor.lang.common.browseServer - }, - { - id: 'cmbTarget', - type: 'select', - requiredContent: 'a[target]', - label: editor.lang.common.target, - 'default': '', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.targetNew, '_blank' ], - [ editor.lang.common.targetTop, '_top' ], - [ editor.lang.common.targetSelf, '_self' ], - [ editor.lang.common.targetParent, '_parent' ] - ], - setup: function( type, element ) { - if ( type == LINK ) - this.setValue( element.getAttribute( 'target' ) || '' ); - }, - commit: function( type, element ) { - if ( type == LINK ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'target', this.getValue() ); - } - } - } - ] - }, - { - id: 'Upload', - hidden: true, - filebrowser: 'uploadButton', - label: editor.lang.image.upload, - elements: [ - { - type: 'file', - id: 'upload', - label: editor.lang.image.btnUpload, - style: 'height:40px', - size: 38 - }, - { - type: 'fileButton', - id: 'uploadButton', - filebrowser: 'info:txtUrl', - label: editor.lang.image.btnUpload, - 'for': [ 'Upload', 'upload' ] - } - ] - }, - { - id: 'advanced', - label: editor.lang.common.advancedTab, - elements: [ - { - type: 'hbox', - widths: [ '50%', '25%', '25%' ], - children: [ - { - type: 'text', - id: 'linkId', - requiredContent: 'img[id]', - label: editor.lang.common.id, - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'id' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'id', this.getValue() ); - } - } - }, - { - id: 'cmbLangDir', - type: 'select', - requiredContent: 'img[dir]', - style: 'width : 100px;', - label: editor.lang.common.langDir, - 'default': '', - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.langDirLtr, 'ltr' ], - [ editor.lang.common.langDirRtl, 'rtl' ] - ], - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'dir' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'dir', this.getValue() ); - } - } - }, - { - type: 'text', - id: 'txtLangCode', - requiredContent: 'img[lang]', - label: editor.lang.common.langCode, - 'default': '', - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'lang' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'lang', this.getValue() ); - } - } - } - ] - }, - { - type: 'text', - id: 'txtGenLongDescr', - requiredContent: 'img[longdesc]', - label: editor.lang.common.longDescr, - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'longDesc' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'longDesc', this.getValue() ); - } - } - }, - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - type: 'text', - id: 'txtGenClass', - requiredContent: 'img(cke-xyz)', // Random text like 'xyz' will check if all are allowed. - label: editor.lang.common.cssClass, - 'default': '', - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'class' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'class', this.getValue() ); - } - } - }, - { - type: 'text', - id: 'txtGenTitle', - requiredContent: 'img[title]', - label: editor.lang.common.advisoryTitle, - 'default': '', - onChange: function() { - updatePreview( this.getDialog() ); - }, - setup: function( type, element ) { - if ( type == IMAGE ) - this.setValue( element.getAttribute( 'title' ) ); - }, - commit: function( type, element ) { - if ( type == IMAGE ) { - if ( this.getValue() || this.isChanged() ) - element.setAttribute( 'title', this.getValue() ); - } else if ( type == PREVIEW ) { - element.setAttribute( 'title', this.getValue() ); - } else if ( type == CLEANUP ) { - element.removeAttribute( 'title' ); - } - } - } - ] - }, - { - type: 'text', - id: 'txtdlgGenStyle', - requiredContent: 'img{cke-xyz}', // Random text like 'xyz' will check if all are allowed. - label: editor.lang.common.cssStyle, - validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ), - 'default': '', - setup: function( type, element ) { - if ( type == IMAGE ) { - var genStyle = element.getAttribute( 'style' ); - if ( !genStyle && element.$.style.cssText ) - genStyle = element.$.style.cssText; - this.setValue( genStyle ); - - var height = element.$.style.height, - width = element.$.style.width, - aMatchH = ( height ? height : '' ).match( regexGetSize ), - aMatchW = ( width ? width : '' ).match( regexGetSize ); - - this.attributesInStyle = { - height: !!aMatchH, - width: !!aMatchW - }; - } - }, - onChange: function() { - commitInternally.call( this, [ 'info:cmbFloat', 'info:cmbAlign', - 'info:txtVSpace', 'info:txtHSpace', - 'info:txtBorder', - 'info:txtWidth', 'info:txtHeight' ] ); - updatePreview( this ); - }, - commit: function( type, element ) { - if ( type == IMAGE && ( this.getValue() || this.isChanged() ) ) { - element.setAttribute( 'style', this.getValue() ); - } - } - } - ] - } - ] - }; - }; - - CKEDITOR.dialog.add( 'image', function( editor ) { - return imageDialog( editor, 'image' ); - }); - - CKEDITOR.dialog.add( 'imagebutton', function( editor ) { - return imageDialog( editor, 'imagebutton' ); - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/image/icons/hidpi/image.png b/addons/website/static/lib/ckeditor/plugins/image/icons/hidpi/image.png Binary files differdeleted file mode 100644 index b3c7ade53ce..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image/icons/hidpi/image.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image/icons/image.png b/addons/website/static/lib/ckeditor/plugins/image/icons/image.png Binary files differdeleted file mode 100644 index fcf61b5f2b3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image/icons/image.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image/lang/en.js b/addons/website/static/lib/ckeditor/plugins/image/lang/en.js deleted file mode 100644 index 76d8dc4b498..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image/lang/en.js +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'image', 'en', { - alertUrl: 'Please type the image URL', - alt: 'Alternative Text', - border: 'Border', - btnUpload: 'Send it to the Server', - button2Img: 'Do you want to transform the selected image button on a simple image?', - hSpace: 'HSpace', - img2Button: 'Do you want to transform the selected image on a image button?', - infoTab: 'Image Info', - linkTab: 'Link', - lockRatio: 'Lock Ratio', - menu: 'Image Properties', - resetSize: 'Reset Size', - title: 'Image Properties', - titleButton: 'Image Button Properties', - upload: 'Upload', - urlMissing: 'Image source URL is missing.', - vSpace: 'VSpace', - validateBorder: 'Border must be a whole number.', - validateHSpace: 'HSpace must be a whole number.', - validateVSpace: 'VSpace must be a whole number.' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/image/plugin.js b/addons/website/static/lib/ckeditor/plugins/image/plugin.js deleted file mode 100644 index b7717477cd6..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image/plugin.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Image plugin - */ - -(function() { - - CKEDITOR.plugins.add( 'image', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'image', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var pluginName = 'image'; - - // Register the dialog. - CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/image.js' ); - - var allowed = 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}', - required = 'img[alt,src]'; - - if ( CKEDITOR.dialog.isTabEnabled( editor, pluginName, 'advanced' ) ) - allowed = 'img[alt,dir,id,lang,longdesc,!src,title]{*}(*)'; - - // Register the command. - editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName, { - allowedContent: allowed, - requiredContent: required, - contentTransformations: [ - [ 'img{width}: sizeToStyle', 'img[width]: sizeToAttribute' ], - [ 'img{float}: alignmentToStyle', 'img[align]: alignmentToAttribute' ] - ] - } ) ); - - // Register the toolbar button. - editor.ui.addButton && editor.ui.addButton( 'Image', { - label: editor.lang.common.image, - command: pluginName, - toolbar: 'insert,10' - }); - - editor.on( 'doubleclick', function( evt ) { - var element = evt.data.element; - - if ( element.is( 'img' ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() ) - evt.data.dialog = 'image'; - }); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - editor.addMenuItems({ - image: { - label: editor.lang.image.menu, - command: 'image', - group: 'image' - } - }); - } - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - if ( getSelectedImage( editor, element ) ) - return { image: CKEDITOR.TRISTATE_OFF }; - }); - } - }, - afterInit: function( editor ) { - // Customize the behavior of the alignment commands. (#7430) - setupAlignCommand( 'left' ); - setupAlignCommand( 'right' ); - setupAlignCommand( 'center' ); - setupAlignCommand( 'block' ); - - function setupAlignCommand( value ) { - var command = editor.getCommand( 'justify' + value ); - if ( command ) { - if ( value == 'left' || value == 'right' ) { - command.on( 'exec', function( evt ) { - var img = getSelectedImage( editor ), - align; - if ( img ) { - align = getImageAlignment( img ); - if ( align == value ) { - img.removeStyle( 'float' ); - - // Remove "align" attribute when necessary. - if ( value == getImageAlignment( img ) ) - img.removeAttribute( 'align' ); - } else - img.setStyle( 'float', value ); - - evt.cancel(); - } - }); - } - - command.on( 'refresh', function( evt ) { - var img = getSelectedImage( editor ), - align; - if ( img ) { - align = getImageAlignment( img ); - - this.setState( - ( align == value ) ? CKEDITOR.TRISTATE_ON : ( value == 'right' || value == 'left' ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - - evt.cancel(); - } - }); - } - } - } - }); - - function getSelectedImage( editor, element ) { - if ( !element ) { - var sel = editor.getSelection(); - element = sel.getSelectedElement(); - } - - if ( element && element.is( 'img' ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() ) - return element; - } - - function getImageAlignment( element ) { - var align = element.getStyle( 'float' ); - - if ( align == 'inherit' || align == 'none' ) - align = 0; - - if ( !align ) - align = element.getAttribute( 'align' ); - - return align; - } - -})(); - -/** - * Whether to remove links when emptying the link URL field in the image dialog. - * - * config.image_removeLinkByEmptyURL = false; - * - * @cfg {Boolean} [image_removeLinkByEmptyURL=true] - * @member CKEDITOR.config - */ -CKEDITOR.config.image_removeLinkByEmptyURL = true; - -/** - * Padding text to set off the image in preview area. - * - * config.image_previewText = CKEDITOR.tools.repeat( '___ ', 100 ); - * - * @cfg {String} [image_previewText='Lorem ipsum dolor...' (placeholder text)] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image1.jpg b/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image1.jpg Binary files differdeleted file mode 100644 index 2fe79eb2cce..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image1.jpg +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image2.jpg b/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image2.jpg Binary files differdeleted file mode 100644 index 453ece5d339..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/dev/assets/image2.jpg +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image2/dev/contents.css b/addons/website/static/lib/ckeditor/plugins/image2/dev/contents.css deleted file mode 100644 index 1392835036d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/dev/contents.css +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ - -figure.caption { - text-align: center; - border: solid 1px #ccc; - border-radius: 2px; - background: rgba(0,0,0,0.05); - padding: 10px; - margin: 10px 20px; - display: block; /* For IE8 */ -} - -figure.caption figcaption { - text-align: center; - display: block; /* For IE8 */ -} - -.cke_widget_wrapper:hover:after { - content: "id: " attr(data-widget-id); - position: absolute; - top: 0; - right: 0; - padding: 2px 4px; - background: #EEE; - border: solid 1px #DDD; - border-radius: 2px; - color: #BBB; - font: bold 10px sans-serif; -}
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/image2/dev/image2.html b/addons/website/static/lib/ckeditor/plugins/image2/dev/image2.html deleted file mode 100644 index 18a530843d9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/dev/image2.html +++ /dev/null @@ -1,199 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.html or http://ckeditor.com/license ---> -<html> -<head> - <title>Widget image2 — CKEditor Sample</title> - <meta charset="utf-8"> - <script src="../../../ckeditor.js"></script> - <script src="../../../dev/console/console.js"></script> - <script src="../../../dev/console/focusconsole.js"></script> - <script src="../../widget/dev/console.js"></script> - <script> - if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) - CKEDITOR.tools.enableHtml5Elements( document ); - </script> - <link href="../../../samples/sample.css" rel="stylesheet"> - <meta name="ckeditor-sample-name" content="Widget image2"> - <meta name="ckeditor-sample-group" content="Plugins"> - <meta name="ckeditor-sample-description" content="Widget img showcase."> - <meta name="ckeditor-sample-isnew" content="1"> - - <style> - - body { - font-size: 13px; - } - .editable { - padding: 20px; - border: 2px solid #dfdfdf; - overflow: auto; - } - - body p { - line-height: 1.8em; - } - - /* Reset some styles from sample.css */ - .cke_editable.cke_editable_inline - { - cursor: auto; - } - .cke_editable.cke_editable_inline.cke_focus - { - box-shadow: none; - background: inherit; - cursor: auto; - } - - </style> - <link href="contents.css" rel="stylesheet"> -</head> -<body> - <h1 class="samples"> - <a href="../../../samples/index.html">CKEditor Samples</a> » Widget image2 - </h1> - - <h2>Framed sample</h2> - - <textarea id="editor1" cols="10" rows="10"> - <h1>Apollo 11</h1> - - <figure class="caption" style="float: right"> - <img alt="Saturn V" src="assets/image1.jpg" width="200" /> - <figcaption>Roll out of Saturn V on launch pad</figcaption> - </figure> - - <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p> - - <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5 kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p> - - <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2> - - <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p> - - <blockquote> - <p>One small step for [a] man, one giant leap for mankind.</p> - </blockquote> - - <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p> - - <blockquote> - <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p> - </blockquote> - - <figure class="caption" style="float: right"> - <img alt="The Eagle" src="assets/image2.jpg" style="width: 200px" /> - <figcaption>The Eagle in lunar orbit</figcaption> - </figure> - - <h2>Technical details <a id="tech-details" name="tech-details"></a></h2> - - <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>'s Apollo program. The Apollo spacecraft had three parts:</p> - - <ol> - <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li> - <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li> - <li><strong>Lunar Module</strong> for landing on the Moon.</li> - </ol> - - <p>After being sent to the Moon by the Saturn V's upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p> - - <p style="text-align:center"> - <img alt="Saturn V" src="assets/image1.jpg" width="200" /> - </p> - - <hr /> - <p style="text-align:right"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p> - </textarea> - - <h2>Inline sample</h2> - - <div id="editor2" contenteditable="true" class="editable"> - <h2>Apollo 11</h2> - - <figure class="caption" style="float: right"> - <img alt="Saturn V" src="assets/image1.jpg" width="200" /> - <figcaption>Roll out of Saturn V on launch pad</figcaption> - </figure> - - <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p> - - <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5 kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p> - - <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2> - - <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p> - - <blockquote> - <p>One small step for [a] man, one giant leap for mankind.</p> - </blockquote> - - <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p> - - <blockquote> - <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p> - </blockquote> - - <figure class="caption" style="float: right"> - <img alt="The Eagle" src="assets/image2.jpg" style="width: 200px" /> - <figcaption>The Eagle in lunar orbit</figcaption> - </figure> - - <h2>Technical details <a id="tech-details" name="tech-details"></a></h2> - - <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>'s Apollo program. The Apollo spacecraft had three parts:</p> - - <ol> - <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li> - <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li> - <li><strong>Lunar Module</strong> for landing on the Moon.</li> - </ol> - - <p>After being sent to the Moon by the Saturn V's upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p> - - <p style="text-align:center"> - <img alt="Saturn V" src="assets/image1.jpg" width="200" /> - </p> - - <hr /> - <p style="text-align:right"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p> - </div> - - <script> - - CKEDITOR.disableAutoInline = true; - - CKEDITOR.replace( 'editor1', { - extraPlugins: 'image2', - height: 600, - removePlugins: 'image,forms', - contentsCss: [ '../../../contents.css', 'contents.css' ], - } ); - - CKEDITOR.inline( 'editor2', { - removePlugins: 'image,forms', - extraPlugins: 'image2,sourcedialog' - } ); - - CKCONSOLE.create( 'widget', { editor: 'editor1' } ); - CKCONSOLE.create( 'focus', { editor: 'editor1' } ); - CKCONSOLE.create( 'widget', { editor: 'editor2', folded: true } ); - CKCONSOLE.create( 'focus', { editor: 'editor2', folded: true } ); - - </script> - - <div id="footer"> - <hr> - <p> - CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a> - </p> - <p id="copy"> - Copyright © 2003-2013, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico - Knabben. All rights reserved. - </p> - </div> -</body> -</html> diff --git a/addons/website/static/lib/ckeditor/plugins/image2/dialogs/image2.js b/addons/website/static/lib/ckeditor/plugins/image2/dialogs/image2.js deleted file mode 100644 index 8c4b924bd42..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/dialogs/image2.js +++ /dev/null @@ -1,480 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.html or http://ckeditor.com/license - */ - -'use strict'; - -CKEDITOR.dialog.add( 'image2', function( editor ) { - - // RegExp: 123, 123px, empty string "" - var regexGetSizeOrEmpty = /(^\s*(\d+)(px)?\s*$)|^$/i, - - lockButtonId = CKEDITOR.tools.getNextId(), - resetButtonId = CKEDITOR.tools.getNextId(), - - lang = editor.lang.image2, - commonLang = editor.lang.common, - - lockResetStyle = 'margin-top:18px;width:40px;height:20px;', - lockResetHtml = new CKEDITOR.template( - '<div>' + - '<a href="javascript:void(0)" tabindex="-1" title="' + lang.lockRatio + '" class="cke_btn_locked" id="{lockButtonId}" role="checkbox">' + - '<span class="cke_icon"></span>' + - '<span class="cke_label">' + lang.lockRatio + '</span>' + - '</a>' + - - '<a href="javascript:void(0)" tabindex="-1" title="' + lang.resetSize + '" class="cke_btn_reset" id="{resetButtonId}" role="button">' + - '<span class="cke_label">' + lang.resetSize + '</span>' + - '</a>' + - '</div>' ).output( { - lockButtonId: lockButtonId, - resetButtonId: resetButtonId - } ), - - // Global variables referring to the dialog's context. - doc, widget, image, - - // Global variable referring to this dialog's image pre-loader. - preLoader, - - // Global variables holding the original size of the image. - domWidth, domHeight, - - // Global variables related to image pre-loading. - preLoadedWidth, preLoadedHeight, srcChanged, - - // Global variables related to size locking. - lockRatio, userDefinedLock, - - // Global variables referring to dialog fields and elements. - lockButton, resetButton, widthField, heightField; - - // Validates dimension. Allowed values are: - // "123px", "123", "" (empty string) - function validateDimension() { - var match = this.getValue().match( regexGetSizeOrEmpty ), - isValid = !!( match && parseInt( match[ 1 ], 10 ) !== 0 ); - - if ( !isValid ) - alert( commonLang[ 'invalid' + CKEDITOR.tools.capitalize( this.id ) ] ); - - return isValid; - } - - // Creates a function that pre-loads images. The callback function passes - // [image, width, height] or null if loading failed. - // - // @returns {Function} - function createPreLoader() { - var image = doc.createElement( 'img' ), - listeners = []; - - function addListener( event, callback ) { - listeners.push( image.once( event, function( evt ) { - removeListeners(); - callback( evt ); - } ) ); - } - - function removeListeners() { - var l; - - while ( ( l = listeners.pop() ) ) - l.removeListener(); - } - - // @param {String} src. - // @param {Function} callback. - return function( src, callback, scope ) { - addListener( 'load', function() { - callback.call( scope, image, image.$.width, image.$.height ); - } ); - - addListener( 'error', function() { - callback( null ); - } ); - - addListener( 'abort', function() { - callback( null ); - } ); - - image.setAttribute( 'src', src + '?' + Math.random().toString( 16 ).substring( 2 ) ); - }; - } - - function onChangeDimension() { - // If ratio is un-locked, then we don't care what's next. - if ( !lockRatio ) - return; - - var value = this.getValue(); - - // No reason to auto-scale or unlock if the field is empty. - if ( !value ) - return; - - // If the value of the field is invalid (e.g. with %), unlock ratio. - if ( !value.match( regexGetSizeOrEmpty ) ) - toggleLockDimensions( false ); - - // No automatic re-scale when dimension is '0'. - if ( value === '0' ) - return; - - var isWidth = this.id == 'width', - // If dialog opened for the new image, domWidth and domHeight - // will be empty. Use dimensions from pre-loader in such case instead. - width = domWidth || preLoadedWidth, - height = domHeight || preLoadedHeight; - - // If changing width, then auto-scale height. - if ( isWidth ) - value = Math.round( height * ( value / width ) ); - - // If changing height, then auto-scale width. - else - value = Math.round( width * ( value / height ) ); - - // If the value is a number, apply it to the other field. - if ( !isNaN( value ) ) - ( isWidth ? heightField : widthField ).setValue( value ); - } - - // Set-up function for lock and reset buttons: - // * Adds lock and reset buttons to focusables. Check if button exist first - // because it may be disabled e.g. due to ACF restrictions. - // * Register mouseover and mouseout event listeners for UI manipulations. - // * Register click event listeners for buttons. - function onLoadLockReset() { - var dialog = this.getDialog(); - - function setupMouseClasses( el ) { - el.on( 'mouseover', function() { - this.addClass( 'cke_btn_over' ); - }, el ); - - el.on( 'mouseout', function() { - this.removeClass( 'cke_btn_over' ); - }, el ); - } - - // Create references to lock and reset buttons for this dialog instance. - lockButton = doc.getById( lockButtonId ); - resetButton = doc.getById( resetButtonId ); - - // Activate (Un)LockRatio button - if ( lockButton ) { - dialog.addFocusable( lockButton, 4 ); - - lockButton.on( 'click', function( evt ) { - toggleLockDimensions(); - evt.data && evt.data.preventDefault(); - }, this.getDialog() ); - - setupMouseClasses( lockButton ); - } - - // Activate the reset size button. - if ( resetButton ) { - dialog.addFocusable( resetButton, 5 ); - - // Fills width and height fields with the original dimensions of the - // image (stored in widget#data since widget#init). - resetButton.on( 'click', function( evt ) { - // If there's a new image loaded, reset button should revert - // cached dimensions of pre-loaded DOM element. - if ( srcChanged ) { - widthField.setValue( preLoadedWidth ); - heightField.setValue( preLoadedHeight ); - } - - // If the old image remains, reset button should revert - // dimensions as loaded when the dialog was first shown. - else { - widthField.setValue( domWidth ); - heightField.setValue( domHeight ); - } - - evt.data && evt.data.preventDefault(); - }, this ); - - setupMouseClasses( resetButton ); - } - } - - function toggleLockDimensions( enable ) { - // No locking if there's no radio (i.e. due to ACF). - if ( !lockButton ) - return; - - var width, height; - - // Check image ratio and original image ratio, but respecting user's - // preference. This is performed when a new image is pre-loaded - // but not if user already manually locked the ratio. - if ( enable == 'check' && !userDefinedLock ) { - width = widthField.getValue(); - height = heightField.getValue(); - - var domRatio = preLoadedWidth * 1000 / preLoadedHeight, - ratio = width * 1000 / height; - - lockRatio = false; - - // Lock ratio, if there is no width and no height specified. - if ( !width && !height ) - lockRatio = true; - - // Lock ratio if there is at least width or height specified, - // and the old ratio that matches the new one. - else if ( !isNaN( domRatio + ratio ) && Math.round( domRatio ) == Math.round( ratio ) ) - lockRatio = true; - } - - // True or false. - else if ( typeof enable == 'boolean' ) - lockRatio = enable; - - // Undefined. User changed lock value. - else { - userDefinedLock = true; - lockRatio = !lockRatio; - - width = widthField.getValue(); - - // Automatically adjust height to width to match - // the original ratio (based on dom- dimensions). - if ( lockRatio && width ) { - height = domHeight / domWidth * width; - - if ( !isNaN( height ) ) - heightField.setValue( Math.round( height ) ); - } - } - - lockButton[ lockRatio ? 'removeClass' : 'addClass' ]( 'cke_btn_unlocked' ); - lockButton.setAttribute( 'aria-checked', lockRatio ); - - // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE - if ( CKEDITOR.env.hc ) { - var icon = lockButton.getChild( 0 ); - icon.setHtml( lockRatio ? CKEDITOR.env.ie ? '\u25A0' : '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' ); - } - } - - function toggleDimensions( enable ) { - var method = enable ? 'enable' : 'disable'; - - widthField[ method ](); - heightField[ method ](); - } - - return { - title: lang.title, - minWidth: 250, - minHeight: 100, - onLoad: function() { - // Create a "global" reference to the document for this dialog instance. - doc = this._.element.getDocument(); - - // Create a pre-loader used for determining dimensions of new images. - preLoader = createPreLoader(); - }, - onShow: function() { - // Create a "global" reference to edited widget. - widget = this._.widget; - - // Create a "global" reference to widget's image. - image = widget.parts.image; - - // Reset global variables. - preLoadedWidth = preLoadedHeight = srcChanged = - userDefinedLock = lockRatio = false; - - // TODO: IE8 - // Get the natural width of the image. - domWidth = image.$.naturalWidth; - - // TODO: IE8 - // Get the natural height of the image. - domHeight = image.$.naturalHeight; - - // Determine image ratio lock on startup. Delayed, waiting for - // fields to be filled with setup functions. - setTimeout( function() { - toggleLockDimensions( 'check' ); - } ); - }, - contents: [ - { - id: 'info', - elements: [ - { - id: 'src', - type: 'text', - label: commonLang.url, - onKeyup: function() { - var value = this.getValue(); - - toggleDimensions( false ); - - // Remember that src is different than default. - if ( value !== widget.data.src ) { - // Update dimensions of the image once it's preloaded. - preLoader( value, function( image, width, height ) { - // Re-enable width and height fields. - toggleDimensions( true ); - - // There was problem loading the image. Unlock ratio. - if ( !image ) - return toggleLockDimensions( false ); - - // Fill width field with the width of the new image. - widthField.setValue( width ); - - // Fill height field with the height of the new image. - heightField.setValue( height ); - - // Cache the new width. - preLoadedWidth = width; - - // Cache the new height. - preLoadedHeight = height; - - // Check for new lock value if image exist. - toggleLockDimensions( 'check' ); - } ); - - srcChanged = true; - } - - // Value is the same as in widget data but is was - // modified back in time. Roll back dimensions when restoring - // default src. - else if ( srcChanged ) { - // Re-enable width and height fields. - toggleDimensions( true ); - - // Restore width field with cached width. - widthField.setValue( domWidth ); - - // Restore height field with cached height. - heightField.setValue( domHeight ); - - // Src equals default one back again. - srcChanged = false; - } - - // Value is the same as in widget data and it hadn't - // been modified. - else { - // Re-enable width and height fields. - toggleDimensions( true ); - } - }, - setup: function( widget ) { - this.setValue( widget.data.src ); - }, - commit: function( widget ) { - widget.setData( 'src', this.getValue() ); - }, - validate: CKEDITOR.dialog.validate.notEmpty( lang.urlMissing ) - }, - { - id: 'alt', - type: 'text', - label: lang.alt, - setup: function( widget ) { - this.setValue( widget.data.alt ); - }, - commit: function( widget ) { - widget.setData( 'alt', this.getValue() ); - } - }, - { - type: 'hbox', - widths: [ '25%', '25%', '50%' ], - requiredContent: 'img[width,height]', - children: [ - { - type: 'text', - width: '45px', - id: 'width', - label: commonLang.width, - validate: validateDimension, - onKeyUp: onChangeDimension, - onLoad: function() { - widthField = this; - }, - setup: function( widget ) { - this.setValue( widget.data.width ); - }, - commit: function( widget ) { - widget.setData( 'width', this.getValue() ); - } - }, - { - type: 'text', - id: 'height', - width: '45px', - label: commonLang.height, - validate: validateDimension, - onKeyUp: onChangeDimension, - onLoad: function() { - heightField = this; - }, - setup: function( widget ) { - this.setValue( widget.data.height ); - }, - commit: function( widget ) { - widget.setData( 'height', this.getValue() ); - } - }, - { - id: 'lock', - type: 'html', - style: lockResetStyle, - onLoad: onLoadLockReset, - html: lockResetHtml - } - ] - }, - { - type: 'hbox', - id: 'alignment', - children: [ - { - id: 'align', - type: 'radio', - items: [ - [ 'None', 'none' ], - [ 'Left', 'left' ], - [ 'Center', 'center' ], - [ 'Right', 'right' ] ], - label: commonLang.align, - setup: function( widget ) { - this.setValue( widget.data.align ); - }, - commit: function( widget ) { - widget.setData( 'align', this.getValue() ); - } - } - ] - }, - { - id: 'hasCaption', - type: 'checkbox', - label: lang.captioned, - setup: function( widget ) { - this.setValue( widget.data.hasCaption ); - }, - commit: function( widget ) { - widget.setData( 'hasCaption', this.getValue() ); - } - } - ] - } - ] - }; -} );
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/image2/icons/hidpi/image2.png b/addons/website/static/lib/ckeditor/plugins/image2/icons/hidpi/image2.png Binary files differdeleted file mode 100644 index b3c7ade53ce..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/icons/hidpi/image2.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image2/icons/image2.png b/addons/website/static/lib/ckeditor/plugins/image2/icons/image2.png Binary files differdeleted file mode 100644 index fcf61b5f2b3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/icons/image2.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/image2/lang/en.js b/addons/website/static/lib/ckeditor/plugins/image2/lang/en.js deleted file mode 100644 index 6431dfc0089..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/lang/en.js +++ /dev/null @@ -1,14 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'image2', 'en', { - alt: 'Alternative Text', // Inherit from image plugin. - captioned: 'Captioned image', // NEW property. - lockRatio: 'Lock Ratio', // Inherit from image plugin. - menu: 'Image Properties', // Inherit from image plugin. - resetSize: 'Reset Size', // Inherit from image plugin. - resizer: 'Click and drag to resize', // NEW property. - title: 'Image Properties', // Inherit from image plugin. - urlMissing: 'Image source URL is missing.' // Inherit from image plugin. -} ); diff --git a/addons/website/static/lib/ckeditor/plugins/image2/plugin.js b/addons/website/static/lib/ckeditor/plugins/image2/plugin.js deleted file mode 100644 index 48ca3e98990..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/image2/plugin.js +++ /dev/null @@ -1,940 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.html or http://ckeditor.com/license - */ - -'use strict'; - -(function() { - - var template = - '<figure class="caption">' + - '<img alt="" src="" />' + - '<figcaption>Caption</figcaption>' + - '</figure>', - templateInline = '<img alt="" src="" />'; - - CKEDITOR.plugins.add( 'image2', { - lang: 'en', // %REMOVE_LINE_CORE% - requires: 'widget,dialog', - icons: 'image2', - hidpi: true, - - onLoad: function( editor ) { - CKEDITOR.addCss( '.cke_image2_resizer{' + - 'display:none;' + - 'position:absolute;' + - 'bottom:2px;' + - 'width: 0px;' + - 'height: 0px;' + - 'border-style:solid;' + - // Bottom-right corner style of the resizer. - 'right:2px;' + - 'border-width:0 0 10px 10px;' + - 'border-color:transparent transparent #ccc transparent;' + - CKEDITOR.tools.cssVendorPrefix( 'box-shadow', '1px 1px 0px #777', true ) + ';' + - 'cursor:se-resize;' + - '}' + - '.cke_image2_resizer_wrapper{' + - 'position:relative;' + - 'display:inline-block;' + - 'line-height:0;' + - '}' + - // Bottom-left corner style of the resizer. - '.cke_image2_resizer.cke_image2_resizer_left{' + - 'right:auto;' + - 'left:2px;' + - 'border-width:10px 0 0 10px;' + - 'border-color:transparent transparent transparent #ccc;' + - CKEDITOR.tools.cssVendorPrefix( 'box-shadow', '-1px 1px 0px #777', true ) + ';' + - 'cursor:sw-resize;' + - '}' + - '.cke_widget_wrapper:hover .cke_image2_resizer{display:block;}' ); - }, - - init: function( editor ) { - // Register the inline widget. - editor.widgets.add( 'image2inline', image2inline ); - - // Register the block widget. - editor.widgets.add( 'image2block', image2block ); - - // Add the command for this plugin. - editor.addCommand( 'image2', { - exec: function() { - var focused = getFocusedWidget( editor ); - - if ( focused ) - focused.edit(); - else - editor.execCommand( 'image2inline' ); - } - } ); - - // Add toolbar button for this plugin. - editor.ui.addButton && editor.ui.addButton( 'image2', { - label: editor.lang.common.image, - command: 'image2', - toolbar: 'insert,10' - } ); - - // Integrate the plugin with context menus. - if ( editor.contextMenu ) { - editor.addMenuGroup( 'image2', 10 ); - - // Define a menu item for the plguin. - editor.addMenuItem( 'image2', { - label: editor.lang.image2.menu, - command: 'image2', - group: 'image2' - } ); - - // Show the menu item in the context menu when a widget - // is focused. - editor.contextMenu.addListener( function() { - var focused = getFocusedWidget( editor ); - - if ( focused ) - return { image2: CKEDITOR.TRISTATE_OFF }; - - return null; - } ); - } - - // Add the dialog associated with both widgets. - CKEDITOR.dialog.add( 'image2', this.path + 'dialogs/image2.js' ); - }, - - afterInit: function( editor ) { - var align = { left:1,right:1,center:1,block:1 }, - integrate = alignCommandIntegrator( editor ); - - for ( var value in align ) - integrate( value ); - } - } ); - - // Default definition shared across widgets. - var image2 = { - // This widget converts style-driven dimensions to attributes. - contentTransformations: [ - [ 'img[width]: sizeToAttribute' ] - ], - - data: function() { - var widget = this, - editor = widget.editor, - oldState = widget.oldData, - newState = widget.data; - - // Convert the internal form of the widget - // from the old state to the new one. - widget.shiftState( { - element: widget.element, - oldState: oldState, - newState: newState, - - // Destroy the widget. - destroy: function() { - if ( this.destroyed ) - return; - - editor.widgets.destroy( widget ); - - // Mark widget was destroyed. - this.destroyed = true; - }, - - init: function( element ) { - // Create a new widget. This widget will be either captioned - // non-captioned, block or inline according to what is the - // new state of the widget. - if ( this.destroyed ) { - var name = 'image2' + ( newState.hasCaption || newState.align == 'center' ? 'block' : 'inline' ); - widget = editor.widgets.initOn( element, name, widget.data ); - } - - // If now widget was destroyed just update wrapper's alignment. - // According to the new state. - else - setWrapperAlign( widget ); - } - } ); - - // Get the <img> from the widget. As widget may have been - // re-initialized, this may be a totally different <img>. - var image = widget.parts.image; - - image.setAttributes( { - src: widget.data.src, - - // This internal is required by the editor. - 'data-cke-saved-src': widget.data.src, - - alt: widget.data.alt - } ); - - // Set dimensions of the image according to gathered data. - setDimensions( widget ); - - // Cache current data. - widget.oldData = CKEDITOR.tools.extend( {}, widget.data ); - }, - - // The name of this widget's dialog. - dialog: 'image2', - - // Initialization of this widget. - init: function() { - var image = this.parts.image, - data = { - // Check whether widget has caption. - hasCaption: !!this.parts.caption, - - // Read initial image SRC attribute. - src: image.getAttribute( 'src' ), - - // Read initial image ALT attribute. - alt: image.getAttribute( 'alt' ) || '', - - // Read initial width from either attribute or style. - width: image.getAttribute( 'width' ) || '', - - // Read initial height from either attribute or style. - height: image.getAttribute( 'height' ) || '' - }; - - // If element was marked as centered when upcasting, update - // the alignment both visually and in widget data. - if ( this.element.data( 'cke-centered' ) ) { - this.element.data( 'cke-centered', false ); - data.align = 'center'; - } - - // Otherwise, read initial float style from figure/image and - // then remove it. This style will be set on wrapper in #data listener. - else { - data.align = this.element.getStyle( 'float' ) || image.getStyle( 'float' ) || 'none'; - this.element.removeStyle( 'float' ); - image.removeStyle( 'float' ); - } - - // Get rid of extra vertical space when there's no caption. - // It will improve the look of the resizer. - if ( !data.hasCaption ) - this.wrapper.setStyle( 'line-height', '0' ); - - // Set collected data. - this.setData( data ); - - // Setup dynamic image resizing with mouse. - setupResizer( this ); - - // Create shift stater for this widget. - this.shiftState = CKEDITOR.plugins.image2.stateShifter( this.editor ); - }, - - // Widget downcasting. - downcast: downcastWidgetElement - }, - - image2inline = CKEDITOR.tools.extend( { - // Widget-specific rules for Allowed Content Filter. - allowedContent: { - // This widget needs <img>. - img: { - attributes: '!src,alt,width,height', - styles: 'float' - } - }, - - // This widget is inline. - inline: true, - - // Parts of this widget. - parts: { image: 'img' }, - - // Template of the widget: plain image. - template: templateInline, - - // Widget upcasting. - upcast: createUpcastFunction() - }, image2 ), - - image2block = CKEDITOR.tools.extend( { - // Widget-specific rules for Allowed Content Filter. - allowedContent: { - // This widget needs <figcaption>. - figcaption: true, - - // This widget needs <figure>. - figure: { - classes: '!caption', - styles: 'float,display' - }, - - // This widget needs <img>. - img: { - attributes: '!src,alt,width,height' - }, - - // This widget may need <div> centering wrapper. - div: { - match: isCenterWrapper, - styles: 'text-align' - }, - - // This widget may need <p> centering wrapper. - p: { - match: isCenterWrapper, - styles: 'text-align' - } - }, - - // This widget has an editable caption. - editables: { - caption: { - selector: 'figcaption', - allowedContent: 'br em strong sub sup u; a[!href]' - } - }, - - // Parts of this widget: image and caption. - parts: { - image: 'img', - caption: 'figcaption' - }, - - // Template of the widget: figure with image and caption. - template: template, - - // Widget upcasting. - upcast: createUpcastFunction( true ) - }, image2 ); - - CKEDITOR.plugins.image2 = { - stateShifter: function( editor ) { - // Tag name used for centering non-captioned widgets. - var centerElement = editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div', - - // The order that stateActions get executed. It matters! - shiftables = [ 'hasCaption', 'align' ], - - editable = editor.editable(), - - // Atomic procedures, one per state variable. - stateActions = { - align: function( data, oldValue, newValue ) { - var hasCaptionAfter = data.newState.hasCaption, - element = data.element; - - // Alignment changed. - if ( changed( data, 'align' ) ) { - // No caption in the new state. - if ( !hasCaptionAfter ) { - // Changed to "center" (non-captioned). - if ( newValue == 'center' ) { - data.destroy(); - data.element = wrapInCentering( element ); - } - - // Changed to "non-center" from "center" while caption removed. - if ( !changed( data, 'hasCaption' ) && oldValue == 'center' && newValue != 'center' ) { - data.destroy(); - data.element = unwrapFromCentering( element ); - } - } - } - - // Alignment remains and "center" removed caption. - else if ( newValue == 'center' && changed( data, 'hasCaption' ) && !hasCaptionAfter ) { - data.destroy(); - data.element = wrapInCentering( element ); - } - - // Finally set display for figure. - if ( element.is( 'figure' ) ) { - if ( newValue == 'center' ) - element.setStyle( 'display', 'inline-block' ); - else - element.removeStyle( 'display' ); - } - }, - hasCaption: function( data, oldValue, newValue ) { - // This action is for real state change only. - if ( !changed( data, 'hasCaption' ) ) - return; - - var element = data.element, - oldState = data.oldState, - newState = data.newState, - img; - - // Switching hasCaption always destroys the widget. - data.destroy(); - - // There was no caption, but the caption is to be added. - if ( newValue ) { - // Get <img> from element. As element may be either - // <img> or centering <p>, consider it now. - img = element.findOne( 'img' ) || element; - - // Create new <figure> from widget template. - var figure = CKEDITOR.dom.element.createFromHtml( template, editor.document ); - - // Replace element with <figure>. - replaceSafely( figure, element ); - - // Use old <img> instead of the one from the template, - // so we won't lose additional attributes. - img.replace( figure.findOne( 'img' ) ); - - // Update widget's element. - data.element = figure; - } - - // The caption was present, but now it's to be removed. - else { - // Unwrap <img> from figure. - img = element.findOne( 'img' ); - - // Replace <figure> with <img>. - img.replace( element ); - - // Update widget's element. - data.element = img; - } - } - }; - - function getValue( state, name ) { - return state && state[ name ] !== undefined ? state[ name ] : null; - } - - function changed( data, name ) { - if ( !data.oldState ) - return false; - else - return data.oldState[ name ] !== data.newState[ name ]; - } - - function wrapInCentering( element ) { - // When widget gets centered. Wrapper must be created. - // Create new <p|div> with text-align:center. - var center = editor.document.createElement( centerElement, { - // Centering wrapper is.. centering. - styles: { 'text-align': 'center' } - } ); - - // Replace element with centering wrapper. - replaceSafely( center, element ); - - // Append element into centering wrapper. - element.move( center ); - - return center; - } - - function unwrapFromCentering( element ) { - var img = element.findOne( 'img' ); - - img.replace( element ); - - return img; - } - - function replaceSafely( replacing, replaced ) { - if ( replaced.getParent() ) { - // Create a range that corresponds with old element's position. - var range = editor.createRange(); - - // Move the range before old element. - range.moveToPosition( replaced, CKEDITOR.POSITION_BEFORE_START ); - - // Insert element at range position. - editable.insertElementIntoRange( replacing, range ); - - // Remove old element. - replaced.remove(); - } - else - replacing.replace( replaced ); - } - - return function( data ) { - var oldState = data.oldState, - newState = data.newState, - name; - - // Iterate over possible state variables. - for ( var i = 0; i < shiftables.length; i++ ) { - name = shiftables[ i ]; - - stateActions[ name ]( data, - oldState ? oldState[ name ] : null, - newState[ name ] ); - } - - data.init( data.element ); - }; - } - }; - - function setWrapperAlign( widget ) { - var wrapper = widget.wrapper, - align = widget.data.align; - - if ( align == 'center' ) { - if ( !widget.inline ) - wrapper.setStyle( 'text-align', 'center' ); - - wrapper.removeStyle( 'float' ); - } else { - if ( !widget.inline ) - wrapper.removeStyle( 'text-align' ); - - if ( align == 'none' ) - wrapper.removeStyle( 'float' ); - else - wrapper.setStyle( 'float', align ); - } - } - - // Creates widgets from all <img> and <figure class="caption">. - // - // @param {CKEDITOR.htmlParser.element} el - function createUpcastFunction( isBlock ) { - var regexPercent = /^\s*(\d+\%)\s*$/i, - dimensions = { width:1,height:1 }; - - function upcastElement( el, isBlock, isCenter ) { - var name = el.name, - image; - - // Block widget to be upcasted. - if ( isBlock ) { - // If a center wrapper is found. - if ( isCenter ) { - // So the element is: - // <div style="text-align:center"><figure></figure></div>. - // Centering is done by widget.wrapper in such case. Hence, replace - // centering wrapper with figure. - // The other case is: - // <p style="text-align:center"><img></p>. - // Then <p> takes charge of <figure> and nothing is to be changed. - if ( name == 'div' ) { - var figure = el.getFirst( 'figure' ); - el.replaceWith( figure ); - el = figure; - } - - // Mark the element as centered, so widget.data.align - // can be correctly filled on init. - el.attributes[ 'data-cke-centered' ] = true; - - image = el.getFirst( 'img' ); - } - - // No center wrapper has been found. - else if ( name == 'figure' && el.hasClass( 'caption' ) ) - image = el.getFirst( 'img' ); - } - - // Inline widget from plain img. - else if ( name == 'img' ) - image = el; - - if ( !image ) - return; - - // If there's an image, then cool, we got a widget. - // Now just remove dimension attributes expressed with %. - for ( var d in dimensions ) { - var dimension = image.attributes[ d ]; - - if ( dimension && dimension.match( regexPercent ) ) - delete image.attributes[ d ]; - } - - return el; - } - - return isBlock ? - function( el ) { - return upcastElement( el, true, isCenterWrapper( el ) ); - } - : - function( el ) { - // Basically upcast the element if there is no special - // wrapper around. - return upcastElement( el ); - }; - } - - // Transforms the widget to the external format according to - // the current configuration. - // - // @param {CKEDITOR.htmlParser.element} el - function downcastWidgetElement( el ) { - var attrs = el.attributes, - align = this.data.align; - - // De-wrap the image from resize handle wrapper. - // Only block widgets have one. - if ( !this.inline ) { - var resizeWrapper = el.getFirst( 'span' ), - img = resizeWrapper.getFirst( 'img' ); - - resizeWrapper.replaceWith( img ); - } - - if ( align && align != 'none' ) { - // Parse element styles. Styles will be extended. - var styles = CKEDITOR.tools.parseCssText( attrs.style || '' ); - - // If centering, wrap downcasted element. - // Wrappers for <img> and <figure> are <p> and <div>, respectively. - if ( align == 'center' && el.name != 'p' ) { - var name = el.name == 'img' ? 'p' : 'div'; - - el = el.wrapWith( new CKEDITOR.htmlParser.element( name, { - 'style': 'text-align:center' - } ) ); - } - - // If left/right, add float style to the downcasted element. - else if ( align in { left:1,right:1 } ) - styles[ 'float' ] = align; - - // Update element styles. - if ( !CKEDITOR.tools.isEmpty( styles ) ) - attrs.style = CKEDITOR.tools.writeCssText( styles ); - } - - return el; - } - - function isCenterWrapper( el ) { - // Wrapper must be either <div> or <p>. - if ( !( el.name in { div:1,p:1 } ) ) - return false; - - var children = el.children; - - // Centering wrapper can have only one child. - if ( children.length !== 1 ) - return false; - - var styles = CKEDITOR.tools.parseCssText( el.attributes.style || '' ); - - // Centering wrapper got to be... centering. - if ( !styles[ 'text-align' ] || styles[ 'text-align' ] != 'center' ) - return false; - - var child = children[ 0 ], - childName = child.name; - - // The only child of centering wrapper can be <figure> with - // class="caption" or plain <img>. - if ( childName == 'img' || ( childName == 'figure' && child.hasClass( 'caption' ) ) ) - return true; - - return false; - } - - // Sets width and height of the widget image according to - // current widget data. - // - // @param {CKEDITOR.plugins.widget} widget - function setDimensions( widget ) { - var dimensions = CKEDITOR.tools.extend( {}, widget.data, false, { width:1,height:1 } ), - image = widget.parts.image; - - for ( var d in dimensions ) { - if ( dimensions[ d ] ) - image.setAttribute( d, dimensions[ d ] ); - else - image.removeAttribute( d ); - } - } - - // Defines all features related to drag-driven image resizing. - // @param {CKEDITOR.plugins.widget} widget - function setupResizer( widget ) { - var editor = widget.editor, - doc = editor.document, - resizer = doc.createElement( 'span' ); - - resizer.addClass( 'cke_image2_resizer' ); - resizer.setAttribute( 'title', editor.lang.image2.resizer ); - resizer.append( new CKEDITOR.dom.text( '\u200b', doc ) ); - - // Inline widgets don't need a resizer wrapper as an image spans the entire widget. - if ( !widget.inline ) { - var oldResizeWrapper = widget.element.getFirst(), - resizeWrapper = doc.createElement( 'span' ); - - resizeWrapper.addClass( 'cke_image2_resizer_wrapper' ); - resizeWrapper.append( widget.parts.image ); - resizeWrapper.append( resizer ); - widget.element.append( resizeWrapper, true ); - - // Remove the old wrapper which could came from e.g. pasted HTML - // and which could be corrupted (e.g. resizer span has been lost). - if ( oldResizeWrapper.is( 'span' ) ) - oldResizeWrapper.remove(); - } else - widget.wrapper.append( resizer ); - - // Calculate values of size variables and mouse offsets. - // Start observing mousemove. - resizer.on( 'mousedown', function( evt ) { - var image = widget.parts.image, - - // "factor" can be either 1 or -1. I.e.: For right-aligned images, we need to - // subtract the difference to get proper width, etc. Without "factor", - // resizer starts working the opposite way. - factor = widget.data.align == 'right' ? -1 : 1, - - // The x-coordinate of the mouse relative to the screen - // when button gets pressed. - startX = evt.data.$.screenX, - startY = evt.data.$.screenY, - - // The initial dimensions and aspect ratio of the image. - startWidth = image.$.clientWidth, - startHeight = image.$.clientHeight, - ratio = startWidth / startHeight, - - moveListeners = [], - - nativeEvt, newWidth, newHeight, updateData, - moveDiffX, moveDiffY, moveRatio; - - // Save the undo snapshot first: before resizing. - editor.fire( 'saveSnapshot' ); - - // Mousemove listeners are removed on mouseup. - attachToDocuments( 'mousemove', onMouseMove, moveListeners ); - - // Clean up the mousemove listener. Update widget data if valid. - attachToDocuments( 'mouseup', onMouseUp ); - - // Attaches an event to a global document if inline editor. - // Additionally, if framed, also attaches the same event to iframe's document. - function attachToDocuments( name, callback, collection ) { - var globalDoc = CKEDITOR.document, - listeners = []; - - if ( !doc.equals( globalDoc ) ) - listeners.push( globalDoc.on( name, callback ) ); - - listeners.push( doc.on( name, callback ) ); - - if ( collection ) { - for ( var i = listeners.length; i--; ) - collection.push( listeners.pop() ); - } - } - - // Calculate with first, and then adjust height, preserving ratio. - function adjustToX() { - newWidth = startWidth + factor * moveDiffX; - newHeight = 0 | newWidth / ratio; - } - - // Calculate height first, and then adjust width, preserving ratio. - function adjustToY() { - newHeight = startHeight - moveDiffY; - newWidth = 0 | newHeight * ratio; - } - - // This is how variables refer to the geometry. - // Note: x corresponds to moveOffset, this is the position of mouse - // Note: o corresponds to [startX, startY]. - // - // +--------------+--------------+ - // | | | - // | I | II | - // | | | - // +------------- o -------------+ _ _ _ - // | | | ^ - // | VI | III | | moveDiffY - // | | x _ _ _ _ _ v - // +--------------+---------|----+ - // | | - // <-------> - // moveDiffX - function onMouseMove( evt ) { - nativeEvt = evt.data.$; - - // This is how far the mouse is from the point the button was pressed. - moveDiffX = nativeEvt.screenX - startX; - moveDiffY = startY - nativeEvt.screenY; - - // This is the aspect ratio of the move difference. - moveRatio = Math.abs( moveDiffX / moveDiffY ); - - // Left, center or none-aligned widget. - if ( factor == 1 ) { - if ( moveDiffX <= 0 ) { - // Case: IV. - if ( moveDiffY <= 0 ) - adjustToX(); - - // Case: I. - else { - if ( moveRatio >= ratio ) - adjustToX(); - else - adjustToY(); - } - } else { - // Case: III. - if ( moveDiffY <= 0 ) { - if ( moveRatio >= ratio ) - adjustToY(); - else - adjustToX(); - } - - // Case: II. - else - adjustToY(); - } - } - - // Right-aligned widget. It mirrors behaviours, so I becomes II, - // IV becomes III and vice-versa. - else { - if ( moveDiffX <= 0 ) { - // Case: IV. - if ( moveDiffY <= 0 ) { - if ( moveRatio >= ratio ) - adjustToY(); - else - adjustToX(); - } - - // Case: I. - else - adjustToY(); - } else { - // Case: III. - if ( moveDiffY <= 0 ) - adjustToX(); - - // Case: II. - else { - if ( moveRatio >= ratio ) - adjustToX(); - else - adjustToY(); - } - } - } - - // Don't update attributes if less than 10. - // This is to prevent images to visually disappear. - if ( newWidth >= 15 && newHeight >= 15 ) { - image.setAttributes( { width: newWidth, height: newHeight } ); - updateData = true; - } else - updateData = false; - } - - function onMouseUp( evt ) { - var l; - - while ( ( l = moveListeners.pop() ) ) - l.removeListener(); - - if ( updateData ) { - widget.setData( { width: newWidth, height: newHeight } ); - - // Save another undo snapshot: after resizing. - editor.fire( 'saveSnapshot' ); - } - - // Don't update data twice or more. - updateData = false; - } - } ); - - // Change the position of the widget resizer when data changes. - widget.on( 'data', function() { - resizer[ widget.data.align == 'right' ? 'addClass' : 'removeClass' ]( 'cke_image2_resizer_left' ); - } ); - } - - // Integrates widget alignment setting with justify - // plugin's commands (execution and refreshment). - // @param {CKEDITOR.editor} editor - // @param {String} value 'left', 'right', 'center' or 'block' - function alignCommandIntegrator( editor ) { - var execCallbacks = []; - - return function( value ) { - var command = editor.getCommand( 'justify' + value ); - - // Most likely, the justify plugin isn't loaded. - if ( !command ) - return; - - // This command will be manually refreshed along with - // other commands after exec. - execCallbacks.push( function() { - command.refresh( editor, editor.elementPath() ); - } ); - - if ( value in { right:1,left:1,center:1 } ) { - command.on( 'exec', function( evt ) { - var widget = getFocusedWidget( editor ); - - if ( widget ) { - widget.setData( 'align', value ); - - // Once the widget changed its align, all the align commands - // must be refreshed: the event is to be cancelled. - for ( var i = execCallbacks.length; i--; ) - execCallbacks[ i ](); - - evt.cancel(); - } - } ); - } - - command.on( 'refresh', function( evt ) { - var widget = getFocusedWidget( editor ), - allowed = { right:1,left:1,center:1 }; - - if ( !widget ) - return; - - this.setState( - ( widget.data.align == value ) ? - CKEDITOR.TRISTATE_ON - : - ( value in allowed ) ? - CKEDITOR.TRISTATE_OFF - : - CKEDITOR.TRISTATE_DISABLED ); - - evt.cancel(); - } ); - }; - } - - // Returns the focused widget, if of the type specific for this plugin. - // If no widget is focused, `null` is returned. - // @param {CKEDITOR.editor} - // @returns {CKEDITOR.plugins.widget} - function getFocusedWidget( editor ) { - var widget = editor.widgets.focused; - - if ( widget && widget.name in { image2inline:1,image2block:1 } ) - return widget; - - return null; - } -})();
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/indent/dev/indent.html b/addons/website/static/lib/ckeditor/plugins/indent/dev/indent.html deleted file mode 100644 index 6bb49a87fa7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/dev/indent.html +++ /dev/null @@ -1,290 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license ---> -<html> -<head> - <title>Indent DEV sample</title> - <meta charset="utf-8"> - <script src="../../../ckeditor.js"></script> - <style> - body { - padding: 20px; - margin: 0; - } - .editors { - display: block; - overflow: hidden; - width: 100%; - margin: 0px auto; - list-style-type: none; - margin: 0; - padding: 0; - - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - - background: #eee; - } - .editors li { - width: 50%; - margin: 0; - padding: 10px; - float: left; - - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - - } - .editors li:nth-child(2n) { - background: #D4E59A; - } - #menu { - position: fixed; - top: 0; - right: 20px; - padding: 5px; - border: 1px solid #aaa; - background: #eee; - } - - </style> -</head> -<body> - <p id="menu"> - <a href="#listnblock">List & Block</a>, - <a href="#classes">Classes</a>, - <a href="#list">List</a>, - <a href="#block">Block</a>, - <a href="#br">ENTER_BR</a> - </p> - - <h1 class="samples">Indent DEV sample</h1> - <h2 id="listnblock">List & Block</h2> - <ul class="editors"> - <li> - <textarea cols="80" id="editor1" rows="10"> - <p>xx</p> - <ul> - <li>x</li> - <li>y</li> - </ul> - <p>xx</p> - - <br> - - <ul><li><ol><li>xx</li></ol></li><li>yy</li></ul> - </textarea> - </li> - <li> - <pre id="editor1_out"></pre> - </li> - </ul> - - <h2 id="classes">Indent classes</h2> - <ul class="editors"> - <li> - <textarea cols="80" id="editor2" rows="10"> - <ul> - <li>a</li> - <li> - b - <ol> - <li>inner</li> - </ol> - </li> - <li>c</li> - </ul> - <p>moo</p> - </textarea> - </li> - <li> - <pre id="editor2_out"></pre> - </li> - </ul> - - <h2 id="list">List only</h2> - <ul class="editors"> - <li> - <textarea cols="80" id="editor3" rows="10"> - <ul> - <li>a</li> - <li> - b - <ol> - <li>inner</li> - </ol> - </li> - <li>c</li> - </ul> - <p>moo</p> - </textarea> - </li> - <li> - <pre id="editor3_out"></pre> - </li> - </ul> - - <h2 id="block">Block only</h2> - <ul class="editors"> - <li> - <textarea cols="80" id="editor4" rows="10"> - <ul> - <li>a</li> - <li> - b - <ol> - <li>inner</li> - </ol> - </li> - <li>c</li> - </ul> - <p>moo</p> - </textarea> - </li> - <li> - <pre id="editor4_out"></pre> - </li> - </ul> - - <h2 id="br">CKEDITOR.ENTER_BR</h2> - <ul class="editors"> - <li> - <textarea cols="80" id="editor5" rows="10"> - Text - <br> - <ul> - <li>a</li> - <li>b</li> - </ul> - </textarea> - </li> - <li> - <pre id="editor5_out"></pre> - </li> - </ul> - <script> - - var plugins = 'enterkey,toolbar,htmlwriter,wysiwygarea,undo,sourcearea,clipboard,list,justify,indent,indentlist,indentblock'; - - CKEDITOR.config.indentOffset = 10; - CKEDITOR.addCss( '\ - .i1{ margin-left: 10px}\ - .i2{ margin-left: 20px}\ - .i3{ margin-left: 30px}' ); - - function showData( event ) { - CKEDITOR.document.getById( this.name + '_out' ).setText( getHtmlWithSelection( this ) ); - } - - function browserHtmlFix( html ) { - if ( CKEDITOR.env.ie && ( document.documentMode || CKEDITOR.env.version ) < 9 ) { - // Fix output base href on anchored link. - html = html.replace( /href="(.*?)#(.*?)"/gi, - function( m, base, anchor ) { - if ( base == window.location.href.replace( window.location.hash, '' ) ) - return 'href="#' + anchor + '"'; - - return m; - } ); - - // Fix output line break after HR. - html = html.replace( /(<HR>)\r\n/gi, function( m, hr ) { return hr; } ); - } - - return html; - } - - function getHtmlWithSelection( editorOrElement, root ) { - var isEditor = editorOrElement instanceof CKEDITOR.editor, - element = isEditor ? editorOrElement.editable() : editorOrElement; - - root = isEditor ? element : - root instanceof CKEDITOR.dom.document ? - root.getBody() : root || CKEDITOR.document.getBody(); - - function replaceWithBookmark( match, startOrEnd ) { - var bookmark; - switch( startOrEnd ) { - case 'S' : - bookmark = '['; - break; - case 'E' : - bookmark = ']'; - break; - case 'C' : - bookmark = '^'; - break; - } - return bookmark; - } - - // Hack: force remove the filling char hack in Webkit. - isEditor && CKEDITOR.env.webkit && editorOrElement.fire( 'beforeSetMode' ); - - var sel = isEditor ? editorOrElement.getSelection() - : new CKEDITOR.dom.selection( root ); - - var doc = sel.document; - var ranges = sel.getRanges(), - range; - - var bms = []; - var iter = ranges.createIterator(); - while( range = iter.getNextRange() ) - bms.push( range.createBookmark( 1 ) ); - - var html = browserHtmlFix( isEditor ? editorOrElement.getData() : element.getHtml() ); - html = html.replace( /<span\b[^>]*?id="?cke_bm_\d+(\w)"?\b[^>]*?>.*?<\/span>/gi, - replaceWithBookmark ); - - for ( var i = 0, bm; i < bms.length; i++ ) { - bm = bms[ i ]; - var start = doc.getById( bm.startNode ), - end = doc.getById( bm.endNode ); - - start && start.remove(); - end && end.remove(); - } - - return html; - } - - CKEDITOR.on( 'instanceReady', function ( event ) { - var editor = event.editor; - - showData.call( editor ); - - editor.on( 'afterCommandExec', showData, editor ); - }); - - CKEDITOR.replace( 'editor1', { - plugins: plugins - } ); - - CKEDITOR.replace( 'editor2', { - plugins: plugins, - indentClasses: [ 'i1', 'i2', 'i3' ] - } ); - - CKEDITOR.replace( 'editor3', { - plugins: plugins, - removePlugins: 'indentblock' - } ); - - CKEDITOR.replace( 'editor4', { - plugins: plugins, - removePlugins: 'indentlist' - } ); - - CKEDITOR.replace( 'editor5', { - plugins: plugins, - enterMode: CKEDITOR.ENTER_BR - } ); - </script> -</body> -</html> - diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent-rtl.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent-rtl.png Binary files differdeleted file mode 100644 index e14dc30835b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent.png Binary files differdeleted file mode 100644 index c629bb41a88..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/indent.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent-rtl.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent-rtl.png Binary files differdeleted file mode 100644 index 35f69abfd5b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent.png Binary files differdeleted file mode 100644 index b00179e2443..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/hidpi/outdent.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/indent-rtl.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/indent-rtl.png Binary files differdeleted file mode 100644 index ff3fd222ee3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/indent-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/indent.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/indent.png Binary files differdeleted file mode 100644 index 3e151bc691f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/indent.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent-rtl.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent-rtl.png Binary files differdeleted file mode 100644 index 7165424d36a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent.png b/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent.png Binary files differdeleted file mode 100644 index 54f205d6de7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/icons/outdent.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/indent/lang/en.js b/addons/website/static/lib/ckeditor/plugins/indent/lang/en.js deleted file mode 100644 index 0308f2ba354..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'indent', 'en', { - indent: 'Increase Indent', - outdent: 'Decrease Indent' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/indent/plugin.js b/addons/website/static/lib/ckeditor/plugins/indent/plugin.js deleted file mode 100755 index 96465d07f9f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indent/plugin.js +++ /dev/null @@ -1,458 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Increase and Decrease Indent commands. - */ - -(function() { - 'use strict'; - - var TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED, - TRISTATE_OFF = CKEDITOR.TRISTATE_OFF; - - CKEDITOR.plugins.add( 'indent', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'indent,indent-rtl,outdent,outdent-rtl', // %REMOVE_LINE_CORE% - - init: function( editor ) { - var genericDefinition = CKEDITOR.plugins.indent.genericDefinition; - - // Register generic commands. - setupGenericListeners( editor, editor.addCommand( 'indent', new genericDefinition( true ) ) ); - setupGenericListeners( editor, editor.addCommand( 'outdent', new genericDefinition() ) ); - - // Create and register toolbar button if possible. - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Indent', { - label: editor.lang.indent.indent, - command: 'indent', - directional: true, - toolbar: 'indent,20' - } ); - - editor.ui.addButton( 'Outdent', { - label: editor.lang.indent.outdent, - command: 'outdent', - directional: true, - toolbar: 'indent,10' - } ); - } - - // Register dirChanged listener. - editor.on( 'dirChanged', function( evt ) { - var range = editor.createRange(), - dataNode = evt.data.node; - - range.setStartBefore( dataNode ); - range.setEndAfter( dataNode ); - - var walker = new CKEDITOR.dom.walker( range ), - node; - - while ( ( node = walker.next() ) ) { - if ( node.type == CKEDITOR.NODE_ELEMENT ) { - // A child with the defined dir is to be ignored. - if ( !node.equals( dataNode ) && node.getDirection() ) { - range.setStartAfter( node ); - walker = new CKEDITOR.dom.walker( range ); - continue; - } - - // Switch alignment classes. - var classes = editor.config.indentClasses; - if ( classes ) { - var suffix = ( evt.data.dir == 'ltr' ) ? [ '_rtl', '' ] : [ '', '_rtl' ]; - for ( var i = 0; i < classes.length; i++ ) { - if ( node.hasClass( classes[ i ] + suffix[ 0 ] ) ) { - node.removeClass( classes[ i ] + suffix[ 0 ] ); - node.addClass( classes[ i ] + suffix[ 1 ] ); - } - } - } - - // Switch the margins. - var marginLeft = node.getStyle( 'margin-right' ), - marginRight = node.getStyle( 'margin-left' ); - - marginLeft ? node.setStyle( 'margin-left', marginLeft ) : node.removeStyle( 'margin-left' ); - marginRight ? node.setStyle( 'margin-right', marginRight ) : node.removeStyle( 'margin-right' ); - } - } - } ); - } - } ); - - /** - * Global command class definitions and global helpers. - * - * @class - * @singleton - */ - CKEDITOR.plugins.indent = { - /** - * A base class for a generic command definition, responsible mainly for creating - * Increase Indent and Decrease Indent toolbar buttons as well as for refreshing - * UI states. - * - * Commands of this class do not perform any indentation by themselves. They - * delegate this job to content-specific indentation commands (i.e. indentlist). - * - * @class CKEDITOR.plugins.indent.genericDefinition - * @extends CKEDITOR.commandDefinition - * @param {CKEDITOR.editor} editor The editor instance this command will be - * applied to. - * @param {String} name The name of the command. - * @param {Boolean} [isIndent] Defines the command as indenting or outdenting. - */ - genericDefinition: function( isIndent ) { - /** - * Determines whether the command belongs to the indentation family. - * Otherwise it is assumed to be an outdenting command. - * - * @readonly - * @property {Boolean} [=false] - */ - this.isIndent = !!isIndent; - - // Mimic naive startDisabled behavior for outdent. - this.startDisabled = !this.isIndent; - }, - - /** - * A base class for specific indentation command definitions responsible for - * handling a pre-defined set of elements i.e. indentlist for lists or - * indentblock for text block elements. - * - * Commands of this class perform indentation operations and modify the DOM structure. - * They listen for events fired by {@link CKEDITOR.plugins.indent.genericDefinition} - * and execute defined actions. - * - * **NOTE**: This is not an {@link CKEDITOR.command editor command}. - * Context-specific commands are internal, for indentation system only. - * - * @class CKEDITOR.plugins.indent.specificDefinition - * @param {CKEDITOR.editor} editor The editor instance this command will be - * applied to. - * @param {String} name The name of the command. - * @param {Boolean} [isIndent] Defines the command as indenting or outdenting. - */ - specificDefinition: function( editor, name, isIndent ) { - this.name = name; - this.editor = editor; - - /** - * An object of jobs handled by the command. Each job consists - * of two functions: `refresh` and `exec` as well as the execution priority. - * - * * The `refresh` function determines whether a job is doable for - * a particular context. These functions are executed in the - * order of priorities, one by one, for all plugins that registered - * jobs. As jobs are related to generic commands, refreshing - * occurs when the global command is firing the `refresh` event. - * - * **Note**: This function must return either {@link CKEDITOR#TRISTATE_DISABLED} - * or {@link CKEDITOR#TRISTATE_OFF}. - * - * * The `exec` function modifies the DOM if possible. Just like - * `refresh`, `exec` functions are executed in the order of priorities - * while the generic command is executed. This function is not executed - * if `refresh` for this job returned {@link CKEDITOR#TRISTATE_DISABLED}. - * - * **Note**: This function must return a Boolean value, indicating whether it - * was successful. If a job was successful, then no other jobs are being executed. - * - * Sample definition: - * - * command.jobs = { - * // Priority = 20. - * '20': { - * refresh( editor, path ) { - * if ( condition ) - * return CKEDITOR.TRISTATE_OFF; - * else - * return CKEDITOR.TRISTATE_DISABLED; - * }, - * exec( editor ) { - * // DOM modified! This was OK. - * return true; - * } - * }, - * // Priority = 60. This job is done later. - * '60': { - * // Another job. - * } - * }; - * - * For additional information, please check comments for - * the `setupGenericListeners` function. - * - * @readonly - * @property {Object} [={}] - */ - this.jobs = {}; - - /** - * Determines whether the editor that the command belongs to has - * {@link CKEDITOR.config#enterMode config.enterMode} set to {@link CKEDITOR#ENTER_BR}. - * - * @readonly - * @see CKEDITOR.config#enterMode - * @property {Boolean} [=false] - */ - this.enterBr = editor.config.enterMode == CKEDITOR.ENTER_BR; - - /** - * Determines whether the command belongs to the indentation family. - * Otherwise it is assumed to be an outdenting command. - * - * @readonly - * @property {Boolean} [=false] - */ - this.isIndent = !!isIndent; - - /** - * The name of the global command related to this one. - * - * @readonly - */ - this.relatedGlobal = isIndent ? 'indent' : 'outdent'; - - /** - * A keystroke associated with this command (*Tab* or *Shift+Tab*). - * - * @readonly - */ - this.indentKey = isIndent ? 9 : CKEDITOR.SHIFT + 9; - - /** - * Stores created markers for the command so they can eventually be - * purged after the `exec` function is run. - */ - this.database = {}; - }, - - /** - * Registers content-specific commands as a part of the indentation system - * directed by generic commands. Once a command is registered, - * it listens for events of a related generic command. - * - * CKEDITOR.plugins.indent.registerCommands( editor, { - * 'indentlist': new indentListCommand( editor, 'indentlist' ), - * 'outdentlist': new indentListCommand( editor, 'outdentlist' ) - * } ); - * - * Content-specific commands listen for the generic command's `exec` and - * try to execute their own jobs, one after another. If some execution is - * successful, `evt.data.done` is set so no more jobs (commands) are involved. - * - * Content-specific commands also listen for the generic command's `refresh` - * and fill the `evt.data.states` object with states of jobs. A generic command - * uses this data to determine its own state and to update the UI. - * - * @member CKEDITOR.plugins.indent - * @param {CKEDITOR.editor} editor The editor instance this command is - * applied to. - * @param {Object} commands An object of {@link CKEDITOR.command}. - */ - registerCommands: function( editor, commands ) { - editor.on( 'pluginsLoaded', function() { - for ( var name in commands ) { - ( function( editor, command ) { - var relatedGlobal = editor.getCommand( command.relatedGlobal ); - - for ( var priority in command.jobs ) { - // Observe generic exec event and execute command when necessary. - // If the command was successfully handled by the command and - // DOM has been modified, stop event propagation so no other plugin - // will bother. Job is done. - relatedGlobal.on( 'exec', function( evt ) { - if ( evt.data.done ) - return; - - // Make sure that anything this command will do is invisible - // for undoManager. What undoManager only can see and - // remember is the execution of the global command (relatedGlobal). - editor.fire( 'lockSnapshot' ); - - if ( command.execJob( editor, priority ) ) - evt.data.done = true; - - editor.fire( 'unlockSnapshot' ); - - // Clean up the markers. - CKEDITOR.dom.element.clearAllMarkers( command.database ); - }, this, null, priority ); - - // Observe generic refresh event and force command refresh. - // Once refreshed, save command state in event data - // so generic command plugin can update its own state and UI. - relatedGlobal.on( 'refresh', function( evt ) { - if ( !evt.data.states ) - evt.data.states = {}; - - evt.data.states[ command.name + '@' + priority ] = - command.refreshJob( editor, priority, evt.data.path ); - }, this, null, priority ); - } - - // Since specific indent commands have no UI elements, - // they need to be manually registered as a editor feature. - editor.addFeature( command ); - } )( this, commands[ name ] ); - } - } ); - } - }; - - CKEDITOR.plugins.indent.genericDefinition.prototype = { - context: 'p', - - exec: function() {} - }; - - CKEDITOR.plugins.indent.specificDefinition.prototype = { - /** - * Executes the content-specific procedure if the context is correct. - * It calls the `exec` function of a job of the given `priority` - * that modifies the DOM. - * - * @param {CKEDITOR.editor} editor The editor instance this command - * will be applied to. - * @param {Number} priority The priority of the job to be executed. - * @returns {Boolean} Indicates whether the job was successful. - */ - execJob: function( editor, priority ) { - var job = this.jobs[ priority ]; - - if ( job.state != TRISTATE_DISABLED ) - return job.exec.call( this, editor ); - }, - - /** - * Calls the `refresh` function of a job of the given `priority`. - * The function returns the state of the job which can be either - * {@link CKEDITOR#TRISTATE_DISABLED} or {@link CKEDITOR#TRISTATE_OFF}. - * - * @param {CKEDITOR.editor} editor The editor instance this command - * will be applied to. - * @param {Number} priority The priority of the job to be executed. - * @returns {Number} The state of the job. - */ - refreshJob: function( editor, priority, path ) { - var job = this.jobs[ priority ]; - - job.state = job.refresh.call( this, editor, path ); - - return job.state; - }, - - /** - * Checks if the element path contains the element handled - * by this indentation command. - * - * @param {CKEDITOR.dom.elementPath} node A path to be checked. - * @returns {CKEDITOR.dom.element} - */ - getContext: function( path ) { - return path.contains( this.context ); - } - }; - - /** - * Attaches event listeners for this generic command. Since the indentation - * system is event-oriented, generic commands communicate with - * content-specific commands using the `exec` and `refresh` events. - * - * Listener priorities are crucial. Different indentation phases - * are executed with different priorities. - * - * For the `exec` event: - * - * * 0: Selection and bookmarks are saved by the generic command. - * * 1-99: Content-specific commands try to indent the code by executing - * their own jobs ({@link CKEDITOR.plugins.indent.specificDefinition#jobs}). - * * 100: Bookmarks are re-selected by the generic command. - * - * The visual interpretation looks as follows: - * - * +------------------+ - * | Exec event fired | - * +------ + ---------+ - * | - * 0 -<----------+ Selection and bookmarks saved. - * | - * | - * 25 -<---+ Exec 1st job of plugin#1 (return false, continuing...). - * | - * | - * 50 -<---+ Exec 1st job of plugin#2 (return false, continuing...). - * | - * | - * 75 -<---+ Exec 2nd job of plugin#1 (only if plugin#2 failed). - * | - * | - * 100 -<-----------+ Re-select bookmarks, clean-up. - * | - * +-------- v ----------+ - * | Exec event finished | - * +---------------------+ - * - * For the `refresh` event: - * - * * <100: Content-specific commands refresh their job states according - * to the given path. Jobs save their states in the `evt.data.states` object - * passed along with the event. This can be either {@link CKEDITOR#TRISTATE_DISABLED} - * or {@link CKEDITOR#TRISTATE_OFF}. - * * 100: Command state is determined according to what states - * have been returned by content-specific jobs (`evt.data.states`). - * UI elements are updated at this stage. - * - * **Note**: If there is at least one job with the {@link CKEDITOR#TRISTATE_OFF} state, - * then the generic command state is also {@link CKEDITOR#TRISTATE_OFF}. Otherwise, - * the command state is {@link CKEDITOR#TRISTATE_DISABLED}. - * - * @param {CKEDITOR.command} command The command to be set up. - * @private - */ - function setupGenericListeners( editor, command ) { - var selection, bookmarks; - - // Set the command state according to content-specific - // command states. - command.on( 'refresh', function( evt ) { - // If no state comes with event data, disable command. - var states = [ TRISTATE_DISABLED ]; - - for ( var s in evt.data.states ) - states.push( evt.data.states[ s ] ); - - this.setState( CKEDITOR.tools.search( states, TRISTATE_OFF ) ? - TRISTATE_OFF - : - TRISTATE_DISABLED ); - }, command, null, 100 ); - - // Initialization. Save bookmarks and mark event as not handled - // by any plugin (command) yet. - command.on( 'exec', function( evt ) { - selection = editor.getSelection(); - bookmarks = selection.createBookmarks( 1 ); - - // Mark execution as not handled yet. - if ( !evt.data ) - evt.data = {}; - - evt.data.done = false; - }, command, null, 0 ); - - // Housekeeping. Make sure selectionChange will be called. - // Also re-select previously saved bookmarks. - command.on( 'exec', function( evt ) { - editor.forceNextSelectionCheck(); - selection.selectBookmarks( bookmarks ); - }, command, null, 100 ); - } -})();
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/indentblock/plugin.js b/addons/website/static/lib/ckeditor/plugins/indentblock/plugin.js deleted file mode 100644 index 37130e6e334..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indentblock/plugin.js +++ /dev/null @@ -1,307 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Handles the indentation of block elements. - */ - -(function() { - 'use strict'; - - var $listItem = CKEDITOR.dtd.$listItem, - $list = CKEDITOR.dtd.$list, - TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED, - TRISTATE_OFF = CKEDITOR.TRISTATE_OFF; - - CKEDITOR.plugins.add( 'indentblock', { - requires: 'indent', - init: function( editor ) { - var globalHelpers = CKEDITOR.plugins.indent, - classes = editor.config.indentClasses; - - // Register commands. - globalHelpers.registerCommands( editor, { - indentblock: new commandDefinition( editor, 'indentblock', true ), - outdentblock: new commandDefinition( editor, 'outdentblock' ) - } ); - - function commandDefinition( editor, name ) { - globalHelpers.specificDefinition.apply( this, arguments ); - - this.allowedContent = { - 'div h1 h2 h3 h4 h5 h6 ol p pre ul': { - // Do not add elements, but only text-align style if element is validated by other rule. - propertiesOnly: true, - styles: !classes ? 'margin-left,margin-right' : null, - classes: classes || null - } - }; - - if ( this.enterBr ) - this.allowedContent.div = true; - - this.requiredContent = ( this.enterBr ? 'div' : 'p' ) + - ( classes ? - '(' + classes.join( ',' ) + ')' - : - '{margin-left}' ); - - this.jobs = { - '20': { - refresh: function( editor, path ) { - var firstBlock = path.block || path.blockLimit; - - // Switch context from list item to list - // because indentblock can indent entire list - // but not a single list element. - - if ( firstBlock.is( $listItem ) ) - firstBlock = firstBlock.getParent(); - - // If firstBlock isn't list item, but still there's - // some ascendant (i.e. <ul>), then this is not - // a job for indentblock, e.g.: - // - // <ul> - // <li><p>foo</p></li> - // </ul> - - else if ( firstBlock.getAscendant( $listItem ) ) - return TRISTATE_DISABLED; - - // [-] Context in the path or ENTER_BR - // - // Don't try to indent if the element is out of - // this plugin's scope. This assertion is omitted - // if ENTER_BR is in use since there may be no block - // in the path. - - if ( !this.enterBr && !this.getContext( path ) ) - return TRISTATE_DISABLED; - - else if ( classes ) { - - // [+] Context in the path or ENTER_BR - // [+] IndentClasses - // - // If there are indentation classes, check if reached - // the highest level of indentation. If so, disable - // the command. - - if ( indentClassLeft.call( this, firstBlock, classes ) ) - return TRISTATE_OFF; - else - return TRISTATE_DISABLED; - } else { - - // [+] Context in the path or ENTER_BR - // [-] IndentClasses - // [+] Indenting - // - // No indent-level limitations due to indent classes. - // Indent-like command can always be executed. - - if ( this.isIndent ) - return TRISTATE_OFF; - - // [+] Context in the path or ENTER_BR - // [-] IndentClasses - // [-] Indenting - // [-] Block in the path - // - // No block in path. There's no element to apply indentation - // so disable the command. - - else if ( !firstBlock ) - return TRISTATE_DISABLED; - - // [+] Context in the path or ENTER_BR - // [-] IndentClasses - // [-] Indenting - // [+] Block in path. - // - // Not using indentClasses but there is firstBlock. - // We can calculate current indentation level and - // try to increase/decrease it. - - else { - return CKEDITOR[ - ( getIndent( firstBlock ) || 0 ) <= 0 ? - 'TRISTATE_DISABLED' - : - 'TRISTATE_OFF' ]; - } - } - }, - - exec: function( editor ) { - var selection = editor.getSelection(), - range = selection && selection.getRanges( 1 )[ 0 ], - nearestListBlock; - - // If there's some list in the path, then it will be - // a full-list indent by increasing or decreasing margin property. - if ( ( nearestListBlock = editor.elementPath().contains( $list ) ) ) - indentElement.call( this, nearestListBlock, classes ); - - // If no list in the path, use iterator to indent all the possible - // paragraphs in the range, creating them if necessary. - else { - var iterator = range.createIterator(), - enterMode = editor.config.enterMode, - block; - - iterator.enforceRealBlocks = true; - iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; - - while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) - indentElement.call( this, block, classes ); - } - - return true; - } - } - }; - } - - CKEDITOR.tools.extend( commandDefinition.prototype, globalHelpers.specificDefinition.prototype, { - // Elements that, if in an elementpath, will be handled by this - // command. They restrict the scope of the plugin. - context: { div: 1, dl: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, ul: 1, ol: 1, p: 1, pre: 1, table: 1 }, - - // A regex built on config#indentClasses to detect whether an - // element has some indentClass or not. - classNameRegex: classes ? - new RegExp( '(?:^|\\s+)(' + classes.join( '|' ) + ')(?=$|\\s)' ) - : - null - } ); - } - } ); - - // Generic indentation procedure for indentation of any element - // either with margin property or config#indentClass. - function indentElement( element, classes, dir ) { - if ( element.getCustomData( 'indent_processed' ) ) - return; - - var editor = this.editor, - isIndent = this.isIndent; - - if ( classes ) { - // Transform current class f to indent step index. - var indentClass = element.$.className.match( this.classNameRegex ), - indentStep = 0; - - if ( indentClass ) { - indentClass = indentClass[ 1 ]; - indentStep = CKEDITOR.tools.indexOf( classes, indentClass ) + 1; - } - - // Operate on indent step index, transform indent step index - // back to class name. - if ( ( indentStep += isIndent ? 1 : -1 ) < 0 ) - return; - - indentStep = Math.min( indentStep, classes.length ); - indentStep = Math.max( indentStep, 0 ); - element.$.className = CKEDITOR.tools.ltrim( element.$.className.replace( this.classNameRegex, '' ) ); - - if ( indentStep > 0 ) - element.addClass( classes[ indentStep - 1 ] ); - } else { - var indentCssProperty = getIndentCss( element, dir ), - currentOffset = parseInt( element.getStyle( indentCssProperty ), 10 ), - indentOffset = editor.config.indentOffset || 40; - - if ( isNaN( currentOffset ) ) - currentOffset = 0; - - currentOffset += ( isIndent ? 1 : -1 ) * indentOffset; - - if ( currentOffset < 0 ) - return; - - currentOffset = Math.max( currentOffset, 0 ); - currentOffset = Math.ceil( currentOffset / indentOffset ) * indentOffset; - - element.setStyle( indentCssProperty, currentOffset ? - currentOffset + ( editor.config.indentUnit || 'px' ) - : - '' ); - - if ( element.getAttribute( 'style' ) === '' ) - element.removeAttribute( 'style' ); - } - - CKEDITOR.dom.element.setMarker( this.database, element, 'indent_processed', 1 ); - - return; - } - - // Method that checks if current indentation level for an element - // reached the limit determined by config#indentClasses. - function indentClassLeft( node, classes ) { - var indentClass = node.$.className.match( this.classNameRegex ), - isIndent = this.isIndent; - - // If node has one of the indentClasses: - // * If it holds the topmost indentClass, then - // no more classes have left. - // * If it holds any other indentClass, it can use the next one - // or the previous one. - // * Outdent is always possible. We can remove indentClass. - if ( indentClass ) - return isIndent ? indentClass[ 1 ] != classes.slice( -1 ) : true; - - // If node has no class which belongs to indentClasses, - // then it is at 0-level. It can be indented but not outdented. - else - return isIndent; - } - - // Determines indent CSS property for an element according to - // what is the direction of such element. It can be either `margin-left` - // or `margin-right`. - function getIndentCss( element, dir ) { - return ( dir || element.getComputedStyle( 'direction' ) ) == 'ltr' ? 'margin-left' : 'margin-right'; - } - - // Return the numerical indent value of margin-left|right of an element, - // considering element's direction. If element has no margin specified, - // NaN is returned. - function getIndent( element ) { - return parseInt( element.getStyle( getIndentCss( element ) ), 10 ); - } -})(); - -/** - * A list of classes to use for indenting the contents. If set to `null`, no classes will be used - * and instead the {@link #indentUnit} and {@link #indentOffset} properties will be used. - * - * // Use the 'Indent1', 'Indent2', 'Indent3' classes. - * config.indentClasses = ['Indent1', 'Indent2', 'Indent3']; - * - * @cfg {Array} [indentClasses=null] - * @member CKEDITOR.config - */ - -/** - * The size in {@link CKEDITOR.config#indentUnit indentation units} of each indentation step. - * - * config.indentOffset = 4; - * - * @cfg {Number} [indentOffset=40] - * @member CKEDITOR.config - */ - -/** - * The unit used for {@link CKEDITOR.config#indentOffset indentation offset}. - * - * config.indentUnit = 'em'; - * - * @cfg {String} [indentUnit='px'] - * @member CKEDITOR.config - */
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/indentlist/plugin.js b/addons/website/static/lib/ckeditor/plugins/indentlist/plugin.js deleted file mode 100644 index de5dfea2429..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/indentlist/plugin.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Handles the indentation of lists. - */ - -(function() { - 'use strict'; - - var isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ), - isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true ), - TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED, - TRISTATE_OFF = CKEDITOR.TRISTATE_OFF; - - CKEDITOR.plugins.add( 'indentlist', { - requires: 'indent', - init: function( editor ) { - var globalHelpers = CKEDITOR.plugins.indent, - editable = editor; - - // Register commands. - globalHelpers.registerCommands( editor, { - indentlist: new commandDefinition( editor, 'indentlist', true ), - outdentlist: new commandDefinition( editor, 'outdentlist' ) - } ); - - function commandDefinition( editor, name ) { - globalHelpers.specificDefinition.apply( this, arguments ); - - // Require ul OR ol list. - this.requiredContent = [ 'ul', 'ol' ]; - - // Indent and outdent lists with TAB/SHIFT+TAB key. Indenting can - // be done for any list item that isn't the first child of the parent. - editor.on( 'key', function( evt ) { - if ( editor.mode != 'wysiwyg' ) - return; - - if ( evt.data.keyCode == this.indentKey ) { - var list = this.getContext( editor.elementPath() ); - - if ( list ) { - // Don't indent if in first list item of the parent. - // Outdent, however, can always be done to collapse - // the list into a paragraph (div). - if ( this.isIndent && firstItemInPath.call( this, editor.elementPath(), list ) ) - return; - - // Exec related global indentation command. Global - // commands take care of bookmarks and selection, - // so it's much easier to use them instead of - // content-specific commands. - editor.execCommand( this.relatedGlobal ); - - // Cancel the key event so editor doesn't lose focus. - evt.cancel(); - } - } - }, this ); - - // There are two different jobs for this plugin: - // - // * Indent job (priority=10), before indentblock. - // - // This job is before indentblock because, if this plugin is - // loaded it has higher priority over indentblock. It means that, - // if possible, nesting is performed, and then block manipulation, - // if necessary. - // - // * Outdent job (priority=30), after outdentblock. - // - // This job got to be after outdentblock because in some cases - // (margin, config#indentClass on list) outdent must be done on - // block-level. - - this.jobs[ this.isIndent ? 10 : 30 ] = { - refresh: this.isIndent ? - function( editor, path ) { - var list = this.getContext( path ), - inFirstListItem = firstItemInPath.call( this, path, list ); - - if ( !list || !this.isIndent || inFirstListItem ) - return TRISTATE_DISABLED; - - return TRISTATE_OFF; - } - : - function( editor, path ) { - var list = this.getContext( path ); - - if ( !list || this.isIndent ) - return TRISTATE_DISABLED; - - return TRISTATE_OFF; - }, - - exec: CKEDITOR.tools.bind( indentList, this ) - }; - } - - CKEDITOR.tools.extend( commandDefinition.prototype, globalHelpers.specificDefinition.prototype, { - // Elements that, if in an elementpath, will be handled by this - // command. They restrict the scope of the plugin. - context: { ol: 1, ul: 1 } - } ); - } - } ); - - function indentList( editor ) { - var that = this, - database = this.database, - context = this.context; - - function indent( listNode ) { - // Our starting and ending points of the range might be inside some blocks under a list item... - // So before playing with the iterator, we need to expand the block to include the list items. - var startContainer = range.startContainer, - endContainer = range.endContainer; - while ( startContainer && !startContainer.getParent().equals( listNode ) ) - startContainer = startContainer.getParent(); - while ( endContainer && !endContainer.getParent().equals( listNode ) ) - endContainer = endContainer.getParent(); - - if ( !startContainer || !endContainer ) - return false; - - // Now we can iterate over the individual items on the same tree depth. - var block = startContainer, - itemsToMove = [], - stopFlag = false; - - while ( !stopFlag ) { - if ( block.equals( endContainer ) ) - stopFlag = true; - - itemsToMove.push( block ); - block = block.getNext(); - } - - if ( itemsToMove.length < 1 ) - return false; - - // Do indent or outdent operations on the array model of the list, not the - // list's DOM tree itself. The array model demands that it knows as much as - // possible about the surrounding lists, we need to feed it the further - // ancestor node that is still a list. - var listParents = listNode.getParents( true ); - for ( var i = 0; i < listParents.length; i++ ) { - if ( listParents[ i ].getName && context[ listParents[ i ].getName() ] ) { - listNode = listParents[ i ]; - break; - } - } - - var indentOffset = that.isIndent ? 1 : -1, - startItem = itemsToMove[ 0 ], - lastItem = itemsToMove[ itemsToMove.length - 1 ], - - // Convert the list DOM tree into a one dimensional array. - listArray = CKEDITOR.plugins.list.listToArray( listNode, database ), - - // Apply indenting or outdenting on the array. - baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent; - - for ( i = startItem.getCustomData( 'listarray_index' ); i <= lastItem.getCustomData( 'listarray_index' ); i++ ) { - listArray[ i ].indent += indentOffset; - // Make sure the newly created sublist get a brand-new element of the same type. (#5372) - if ( indentOffset > 0 ) { - var listRoot = listArray[ i ].parent; - listArray[ i ].parent = new CKEDITOR.dom.element( listRoot.getName(), listRoot.getDocument() ); - } - } - - for ( i = lastItem.getCustomData( 'listarray_index' ) + 1; i < listArray.length && listArray[ i ].indent > baseIndent; i++ ) - listArray[ i ].indent += indentOffset; - - // Convert the array back to a DOM forest (yes we might have a few subtrees now). - // And replace the old list with the new forest. - var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, listNode.getDirection() ); - - // Avoid nested <li> after outdent even they're visually same, - // recording them for later refactoring.(#3982) - if ( !that.isIndent ) { - var parentLiElement; - if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) ) { - var children = newList.listNode.getChildren(), - pendingLis = [], - count = children.count(), - child; - - for ( i = count - 1; i >= 0; i-- ) { - if ( ( child = children.getItem( i ) ) && child.is && child.is( 'li' ) ) - pendingLis.push( child ); - } - } - } - - if ( newList ) - newList.listNode.replace( listNode ); - - // Move the nested <li> to be appeared after the parent. - if ( pendingLis && pendingLis.length ) { - for ( i = 0; i < pendingLis.length; i++ ) { - var li = pendingLis[ i ], - followingList = li; - - // Nest preceding <ul>/<ol> inside current <li> if any. - while ( ( followingList = followingList.getNext() ) && followingList.is && followingList.getName() in context ) { - // IE requires a filler NBSP for nested list inside empty list item, - // otherwise the list item will be inaccessiable. (#4476) - if ( CKEDITOR.env.ie && !li.getFirst( function( node ) { - return isNotWhitespaces( node ) && isNotBookmark( node ); - } ) ) - li.append( range.document.createText( '\u00a0' ) ); - - li.append( followingList ); - } - - li.insertAfter( parentLiElement ); - } - } - - return true; - } - - var selection = editor.getSelection(), - ranges = selection && selection.getRanges( 1 ), - iterator = ranges.createIterator(), - range; - - while ( ( range = iterator.getNextRange() ) ) { - var rangeRoot = range.getCommonAncestor(), - nearestListBlock = rangeRoot; - - while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && context[ nearestListBlock.getName() ] ) ) - nearestListBlock = nearestListBlock.getParent(); - - // Avoid having selection boundaries out of the list. - // <ul><li>[...</li></ul><p>...]</p> => <ul><li>[...]</li></ul><p>...</p> - if ( !nearestListBlock ) { - if ( ( nearestListBlock = range.startPath().contains( context ) ) ) - range.setEndAt( nearestListBlock, CKEDITOR.POSITION_BEFORE_END ); - } - - // Avoid having selection enclose the entire list. (#6138) - // [<ul><li>...</li></ul>] =><ul><li>[...]</li></ul> - if ( !nearestListBlock ) { - var selectedNode = range.getEnclosedNode(); - if ( selectedNode && selectedNode.type == CKEDITOR.NODE_ELEMENT && selectedNode.getName() in context ) { - range.setStartAt( selectedNode, CKEDITOR.POSITION_AFTER_START ); - range.setEndAt( selectedNode, CKEDITOR.POSITION_BEFORE_END ); - nearestListBlock = selectedNode; - } - } - - // Avoid selection anchors under list root. - // <ul>[<li>...</li>]</ul> => <ul><li>[...]</li></ul> - if ( nearestListBlock && range.startContainer.type == CKEDITOR.NODE_ELEMENT && range.startContainer.getName() in context ) { - var walker = new CKEDITOR.dom.walker( range ); - walker.evaluator = listItem; - range.startContainer = walker.next(); - } - - if ( nearestListBlock && range.endContainer.type == CKEDITOR.NODE_ELEMENT && range.endContainer.getName() in context ) { - walker = new CKEDITOR.dom.walker( range ); - walker.evaluator = listItem; - range.endContainer = walker.previous(); - } - - if ( nearestListBlock ) - return indent( nearestListBlock ); - } - return 0; - } - - // Check whether a first child of a list is in the path. - // The list can be extracted from path or given explicitly - // e.g. for better performance if cached. - function firstItemInPath( path, list ) { - if ( !list ) - list = path.contains( this.context ); - - return list && path.block && path.block.equals( list.getFirst( listItem ) ); - } - - // Determines whether a node is a list <li> element. - function listItem( node ) { - return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' ); - } -})();
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyblock.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyblock.png Binary files differdeleted file mode 100644 index 7209fd41435..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyblock.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifycenter.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifycenter.png Binary files differdeleted file mode 100644 index 365e3205c42..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifycenter.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyleft.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyleft.png Binary files differdeleted file mode 100644 index 75308c126e2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyleft.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyright.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyright.png Binary files differdeleted file mode 100644 index de7c3d45402..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/hidpi/justifyright.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyblock.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyblock.png Binary files differdeleted file mode 100644 index a507be1bcee..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyblock.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifycenter.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/justifycenter.png Binary files differdeleted file mode 100644 index f758bc42209..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifycenter.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyleft.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyleft.png Binary files differdeleted file mode 100644 index 542ddee3133..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyleft.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyright.png b/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyright.png Binary files differdeleted file mode 100644 index 71a983c9194..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/icons/justifyright.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/justify/lang/en.js b/addons/website/static/lib/ckeditor/plugins/justify/lang/en.js deleted file mode 100644 index 90588e791d0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/lang/en.js +++ /dev/null @@ -1,10 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'justify', 'en', { - block: 'Justify', - center: 'Center', - left: 'Align Left', - right: 'Align Right' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/justify/plugin.js b/addons/website/static/lib/ckeditor/plugins/justify/plugin.js deleted file mode 100755 index 476af63afde..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/justify/plugin.js +++ /dev/null @@ -1,239 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Justify commands. - */ - -(function() { - function getAlignment( element, useComputedState ) { - useComputedState = useComputedState === undefined || useComputedState; - - var align; - if ( useComputedState ) - align = element.getComputedStyle( 'text-align' ); - else { - while ( !element.hasAttribute || !( element.hasAttribute( 'align' ) || element.getStyle( 'text-align' ) ) ) { - var parent = element.getParent(); - if ( !parent ) - break; - element = parent; - } - align = element.getStyle( 'text-align' ) || element.getAttribute( 'align' ) || ''; - } - - // Sometimes computed values doesn't tell. - align && ( align = align.replace( /(?:-(?:moz|webkit)-)?(?:start|auto)/i, '' ) ); - - !align && useComputedState && ( align = element.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' ); - - return align; - } - - function justifyCommand( editor, name, value ) { - this.editor = editor; - this.name = name; - this.value = value; - this.context = 'p'; - - var classes = editor.config.justifyClasses, - blockTag = editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div'; - - if ( classes ) { - switch ( value ) { - case 'left': - this.cssClassName = classes[ 0 ]; - break; - case 'center': - this.cssClassName = classes[ 1 ]; - break; - case 'right': - this.cssClassName = classes[ 2 ]; - break; - case 'justify': - this.cssClassName = classes[ 3 ]; - break; - } - - this.cssClassRegex = new RegExp( '(?:^|\\s+)(?:' + classes.join( '|' ) + ')(?=$|\\s)' ); - this.requiredContent = blockTag + '(' + this.cssClassName + ')'; - } - else { - this.requiredContent = blockTag + '{text-align}'; - } - - this.allowedContent = { - 'caption div h1 h2 h3 h4 h5 h6 p pre td th li': { - // Do not add elements, but only text-align style if element is validated by other rule. - propertiesOnly: true, - styles: this.cssClassName ? null : 'text-align', - classes: this.cssClassName || null - } - }; - - // In enter mode BR we need to allow here for div, because when non other - // feature allows div justify is the only plugin that uses it. - if ( editor.config.enterMode == CKEDITOR.ENTER_BR ) - this.allowedContent.div = true; - } - - function onDirChanged( e ) { - var editor = e.editor; - - var range = editor.createRange(); - range.setStartBefore( e.data.node ); - range.setEndAfter( e.data.node ); - - var walker = new CKEDITOR.dom.walker( range ), - node; - - while ( ( node = walker.next() ) ) { - if ( node.type == CKEDITOR.NODE_ELEMENT ) { - // A child with the defined dir is to be ignored. - if ( !node.equals( e.data.node ) && node.getDirection() ) { - range.setStartAfter( node ); - walker = new CKEDITOR.dom.walker( range ); - continue; - } - - // Switch the alignment. - var classes = editor.config.justifyClasses; - if ( classes ) { - // The left align class. - if ( node.hasClass( classes[ 0 ] ) ) { - node.removeClass( classes[ 0 ] ); - node.addClass( classes[ 2 ] ); - } - // The right align class. - else if ( node.hasClass( classes[ 2 ] ) ) { - node.removeClass( classes[ 2 ] ); - node.addClass( classes[ 0 ] ); - } - } - - // Always switch CSS margins. - var style = 'text-align'; - var align = node.getStyle( style ); - - if ( align == 'left' ) - node.setStyle( style, 'right' ); - else if ( align == 'right' ) - node.setStyle( style, 'left' ); - } - } - } - - justifyCommand.prototype = { - exec: function( editor ) { - var selection = editor.getSelection(), - enterMode = editor.config.enterMode; - - if ( !selection ) - return; - - var bookmarks = selection.createBookmarks(), - ranges = selection.getRanges( true ); - - var cssClassName = this.cssClassName, - iterator, block; - - var useComputedState = editor.config.useComputedState; - useComputedState = useComputedState === undefined || useComputedState; - - for ( var i = ranges.length - 1; i >= 0; i-- ) { - iterator = ranges[ i ].createIterator(); - iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR; - - while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) { - block.removeAttribute( 'align' ); - block.removeStyle( 'text-align' ); - - // Remove any of the alignment classes from the className. - var className = cssClassName && ( block.$.className = CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) ) ); - - var apply = ( this.state == CKEDITOR.TRISTATE_OFF ) && ( !useComputedState || ( getAlignment( block, true ) != this.value ) ); - - if ( cssClassName ) { - // Append the desired class name. - if ( apply ) - block.addClass( cssClassName ); - else if ( !className ) - block.removeAttribute( 'class' ); - } else if ( apply ) - block.setStyle( 'text-align', this.value ); - } - - } - - editor.focus(); - editor.forceNextSelectionCheck(); - selection.selectBookmarks( bookmarks ); - }, - - refresh: function( editor, path ) { - var firstBlock = path.block || path.blockLimit; - - this.setState( firstBlock.getName() != 'body' && getAlignment( firstBlock, this.editor.config.useComputedState ) == this.value ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - } - }; - - CKEDITOR.plugins.add( 'justify', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'justifyblock,justifycenter,justifyleft,justifyright', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - var left = new justifyCommand( editor, 'justifyleft', 'left' ), - center = new justifyCommand( editor, 'justifycenter', 'center' ), - right = new justifyCommand( editor, 'justifyright', 'right' ), - justify = new justifyCommand( editor, 'justifyblock', 'justify' ); - - editor.addCommand( 'justifyleft', left ); - editor.addCommand( 'justifycenter', center ); - editor.addCommand( 'justifyright', right ); - editor.addCommand( 'justifyblock', justify ); - - if ( editor.ui.addButton ) { - editor.ui.addButton( 'JustifyLeft', { - label: editor.lang.justify.left, - command: 'justifyleft', - toolbar: 'align,10' - }); - editor.ui.addButton( 'JustifyCenter', { - label: editor.lang.justify.center, - command: 'justifycenter', - toolbar: 'align,20' - }); - editor.ui.addButton( 'JustifyRight', { - label: editor.lang.justify.right, - command: 'justifyright', - toolbar: 'align,30' - }); - editor.ui.addButton( 'JustifyBlock', { - label: editor.lang.justify.block, - command: 'justifyblock', - toolbar: 'align,40' - }); - } - - editor.on( 'dirChanged', onDirChanged ); - } - }); -})(); - -/** - * List of classes to use for aligning the contents. If it's `null`, no classes will be used - * and instead the corresponding CSS values will be used. - * - * The array should contain 4 members, in the following order: left, center, right, justify. - * - * // Use the classes 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' - * config.justifyClasses = [ 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' ]; - * - * @cfg {Array} [justifyClasses=null] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/link/dialogs/anchor.js b/addons/website/static/lib/ckeditor/plugins/link/dialogs/anchor.js deleted file mode 100755 index a1c5067b512..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/dialogs/anchor.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'anchor', function( editor ) { - // Function called in onShow to load selected element. - var loadElements = function( element ) { - this._.selectedElement = element; - - var attributeValue = element.data( 'cke-saved-name' ); - this.setValueOf( 'info', 'txtName', attributeValue || '' ); - }; - - function createFakeAnchor( editor, anchor ) { - return editor.createFakeElement( anchor, 'cke_anchor', 'anchor' ); - } - - return { - title: editor.lang.link.anchor.title, - minWidth: 300, - minHeight: 60, - onOk: function() { - var name = CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtName' ) ); - var attributes = { - id: name, - name: name, - 'data-cke-saved-name': name - }; - - if ( this._.selectedElement ) { - if ( this._.selectedElement.data( 'cke-realelement' ) ) { - var newFake = createFakeAnchor( editor, editor.document.createElement( 'a', { attributes: attributes } ) ); - newFake.replace( this._.selectedElement ); - } else - this._.selectedElement.setAttributes( attributes ); - } else { - var sel = editor.getSelection(), - range = sel && sel.getRanges()[ 0 ]; - - // Empty anchor - if ( range.collapsed ) { - if ( CKEDITOR.plugins.link.synAnchorSelector ) - attributes[ 'class' ] = 'cke_anchor_empty'; - - if ( CKEDITOR.plugins.link.emptyAnchorFix ) { - attributes[ 'contenteditable' ] = 'false'; - attributes[ 'data-cke-editable' ] = 1; - } - - var anchor = editor.document.createElement( 'a', { attributes: attributes } ); - - // Transform the anchor into a fake element for browsers that need it. - if ( CKEDITOR.plugins.link.fakeAnchor ) - anchor = createFakeAnchor( editor, anchor ); - - range.insertNode( anchor ); - } else { - if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) - attributes[ 'class' ] = 'cke_anchor'; - - // Apply style. - var style = new CKEDITOR.style({ element: 'a', attributes: attributes } ); - style.type = CKEDITOR.STYLE_INLINE; - editor.applyStyle( style ); - } - } - }, - - onHide: function() { - delete this._.selectedElement; - }, - - onShow: function() { - var selection = editor.getSelection(), - fullySelected = selection.getSelectedElement(), - partialSelected; - - // Detect the anchor under selection. - if ( fullySelected ) { - if ( CKEDITOR.plugins.link.fakeAnchor ) { - var realElement = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, fullySelected ); - realElement && loadElements.call( this, realElement ); - this._.selectedElement = fullySelected; - } else if ( fullySelected.is( 'a' ) && fullySelected.hasAttribute( 'name' ) ) - loadElements.call( this, fullySelected ); - } else { - partialSelected = CKEDITOR.plugins.link.getSelectedLink( editor ); - if ( partialSelected ) { - loadElements.call( this, partialSelected ); - selection.selectElement( partialSelected ); - } - } - - this.getContentElement( 'info', 'txtName' ).focus(); - }, - contents: [ - { - id: 'info', - label: editor.lang.link.anchor.title, - accessKey: 'I', - elements: [ - { - type: 'text', - id: 'txtName', - label: editor.lang.link.anchor.name, - required: true, - validate: function() { - if ( !this.getValue() ) { - alert( editor.lang.link.anchor.errorName ); - return false; - } - return true; - } - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/link/dialogs/link.js b/addons/website/static/lib/ckeditor/plugins/link/dialogs/link.js deleted file mode 100755 index d2aa9dc76a9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/dialogs/link.js +++ /dev/null @@ -1,1288 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'link', function( editor ) { - var plugin = CKEDITOR.plugins.link; - // Handles the event when the "Target" selection box is changed. - var targetChanged = function() { - var dialog = this.getDialog(), - popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ), - targetName = dialog.getContentElement( 'target', 'linkTargetName' ), - value = this.getValue(); - - if ( !popupFeatures || !targetName ) - return; - - popupFeatures = popupFeatures.getElement(); - popupFeatures.hide(); - targetName.setValue( '' ); - - switch ( value ) { - case 'frame': - targetName.setLabel( editor.lang.link.targetFrameName ); - targetName.getElement().show(); - break; - case 'popup': - popupFeatures.show(); - targetName.setLabel( editor.lang.link.targetPopupName ); - targetName.getElement().show(); - break; - default: - targetName.setValue( value ); - targetName.getElement().hide(); - break; - } - - }; - - // Handles the event when the "Type" selection box is changed. - var linkTypeChanged = function() { - var dialog = this.getDialog(), - partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ], - typeValue = this.getValue(), - uploadTab = dialog.definition.getContents( 'upload' ), - uploadInitiallyHidden = uploadTab && uploadTab.hidden; - - if ( typeValue == 'url' ) { - if ( editor.config.linkShowTargetTab ) - dialog.showPage( 'target' ); - if ( !uploadInitiallyHidden ) - dialog.showPage( 'upload' ); - } else { - dialog.hidePage( 'target' ); - if ( !uploadInitiallyHidden ) - dialog.hidePage( 'upload' ); - } - - for ( var i = 0; i < partIds.length; i++ ) { - var element = dialog.getContentElement( 'info', partIds[ i ] ); - if ( !element ) - continue; - - element = element.getElement().getParent().getParent(); - if ( partIds[ i ] == typeValue + 'Options' ) - element.show(); - else - element.hide(); - } - - dialog.layout(); - }; - - // Loads the parameters in a selected link to the link dialog fields. - var javascriptProtocolRegex = /^javascript:/, - emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/, - emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/, - emailBodyRegex = /body=([^;?:@&=$,\/]*)/, - anchorRegex = /^#(.*)$/, - urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/, - selectableTargets = /^(_(?:self|top|parent|blank))$/, - encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/, - functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/; - - var popupRegex = /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/; - var popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi; - - var parseLink = function( editor, element ) { - var href = ( element && ( element.data( 'cke-saved-href' ) || element.getAttribute( 'href' ) ) ) || '', - javascriptMatch, emailMatch, anchorMatch, urlMatch, - retval = {}; - - if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) ) { - if ( emailProtection == 'encode' ) { - href = href.replace( encodedEmailLinkRegex, function( match, protectedAddress, rest ) { - return 'mailto:' + - String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) + - ( rest && unescapeSingleQuote( rest ) ); - }); - } - // Protected email link as function call. - else if ( emailProtection ) { - href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs ) { - if ( funcName == compiledProtectionFunction.name ) { - retval.type = 'email'; - var email = retval.email = {}; - - var paramRegex = /[^,\s]+/g, - paramQuoteRegex = /(^')|('$)/g, - paramsMatch = funcArgs.match( paramRegex ), - paramsMatchLength = paramsMatch.length, - paramName, paramVal; - - for ( var i = 0; i < paramsMatchLength; i++ ) { - paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) ); - paramName = compiledProtectionFunction.params[ i ].toLowerCase(); - email[ paramName ] = paramVal; - } - email.address = [ email.name, email.domain ].join( '@' ); - } - }); - } - } - - if ( !retval.type ) { - if ( ( anchorMatch = href.match( anchorRegex ) ) ) { - retval.type = 'anchor'; - retval.anchor = {}; - retval.anchor.name = retval.anchor.id = anchorMatch[ 1 ]; - } - // Protected email link as encoded string. - else if ( ( emailMatch = href.match( emailRegex ) ) ) { - var subjectMatch = href.match( emailSubjectRegex ), - bodyMatch = href.match( emailBodyRegex ); - - retval.type = 'email'; - var email = ( retval.email = {} ); - email.address = emailMatch[ 1 ]; - subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) ); - bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) ); - } - // urlRegex matches empty strings, so need to check for href as well. - else if ( href && ( urlMatch = href.match( urlRegex ) ) ) { - retval.type = 'url'; - retval.url = {}; - retval.url.protocol = urlMatch[ 1 ]; - retval.url.url = urlMatch[ 2 ]; - } else - retval.type = 'url'; - } - - // Load target and popup settings. - if ( element ) { - var target = element.getAttribute( 'target' ); - retval.target = {}; - retval.adv = {}; - - // IE BUG: target attribute is an empty string instead of null in IE if it's not set. - if ( !target ) { - var onclick = element.data( 'cke-pa-onclick' ) || element.getAttribute( 'onclick' ), - onclickMatch = onclick && onclick.match( popupRegex ); - if ( onclickMatch ) { - retval.target.type = 'popup'; - retval.target.name = onclickMatch[ 1 ]; - - var featureMatch; - while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[ 2 ] ) ) ) { - // Some values should remain numbers (#7300) - if ( ( featureMatch[ 2 ] == 'yes' || featureMatch[ 2 ] == '1' ) && !( featureMatch[ 1 ] in { height:1,width:1,top:1,left:1 } ) ) - retval.target[ featureMatch[ 1 ] ] = true; - else if ( isFinite( featureMatch[ 2 ] ) ) - retval.target[ featureMatch[ 1 ] ] = featureMatch[ 2 ]; - } - } - } else { - var targetMatch = target.match( selectableTargets ); - if ( targetMatch ) - retval.target.type = retval.target.name = target; - else { - retval.target.type = 'frame'; - retval.target.name = target; - } - } - - var me = this; - var advAttr = function( inputName, attrName ) { - var value = element.getAttribute( attrName ); - if ( value !== null ) - retval.adv[ inputName ] = value || ''; - }; - advAttr( 'advId', 'id' ); - advAttr( 'advLangDir', 'dir' ); - advAttr( 'advAccessKey', 'accessKey' ); - - retval.adv.advName = element.data( 'cke-saved-name' ) || element.getAttribute( 'name' ) || ''; - advAttr( 'advLangCode', 'lang' ); - advAttr( 'advTabIndex', 'tabindex' ); - advAttr( 'advTitle', 'title' ); - advAttr( 'advContentType', 'type' ); - CKEDITOR.plugins.link.synAnchorSelector ? retval.adv.advCSSClasses = getLinkClass( element ) : advAttr( 'advCSSClasses', 'class' ); - advAttr( 'advCharset', 'charset' ); - advAttr( 'advStyles', 'style' ); - advAttr( 'advRel', 'rel' ); - } - - // Find out whether we have any anchors in the editor. - var anchors = retval.anchors = [], - i, count, item; - - // For some browsers we set contenteditable="false" on anchors, making document.anchors not to include them, so we must traverse the links manually (#7893). - if ( CKEDITOR.plugins.link.emptyAnchorFix ) { - var links = editor.document.getElementsByTag( 'a' ); - for ( i = 0, count = links.count(); i < count; i++ ) { - item = links.getItem( i ); - if ( item.data( 'cke-saved-name' ) || item.hasAttribute( 'name' ) ) - anchors.push({ name: item.data( 'cke-saved-name' ) || item.getAttribute( 'name' ), id: item.getAttribute( 'id' ) } ); - } - } else { - var anchorList = new CKEDITOR.dom.nodeList( editor.document.$.anchors ); - for ( i = 0, count = anchorList.count(); i < count; i++ ) { - item = anchorList.getItem( i ); - anchors[ i ] = { name: item.getAttribute( 'name' ), id: item.getAttribute( 'id' ) }; - } - } - - if ( CKEDITOR.plugins.link.fakeAnchor ) { - var imgs = editor.document.getElementsByTag( 'img' ); - for ( i = 0, count = imgs.count(); i < count; i++ ) { - if ( ( item = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, imgs.getItem( i ) ) ) ) - anchors.push({ name: item.getAttribute( 'name' ), id: item.getAttribute( 'id' ) } ); - } - } - - // Record down the selected element in the dialog. - this._.selectedElement = element; - return retval; - }; - - var setupParams = function( page, data ) { - if ( data[ page ] ) - this.setValue( data[ page ][ this.id ] || '' ); - }; - - var setupPopupParams = function( data ) { - return setupParams.call( this, 'target', data ); - }; - - var setupAdvParams = function( data ) { - return setupParams.call( this, 'adv', data ); - }; - - var commitParams = function( page, data ) { - if ( !data[ page ] ) - data[ page ] = {}; - - data[ page ][ this.id ] = this.getValue() || ''; - }; - - var commitPopupParams = function( data ) { - return commitParams.call( this, 'target', data ); - }; - - var commitAdvParams = function( data ) { - return commitParams.call( this, 'adv', data ); - }; - - function unescapeSingleQuote( str ) { - return str.replace( /\\'/g, '\'' ); - } - - function escapeSingleQuote( str ) { - return str.replace( /'/g, '\\$&' ); - } - - var emailProtection = editor.config.emailProtection || ''; - - // Compile the protection function pattern. - if ( emailProtection && emailProtection != 'encode' ) { - var compiledProtectionFunction = {}; - - emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params ) { - compiledProtectionFunction.name = funcName; - compiledProtectionFunction.params = []; - params.replace( /[^,\s]+/g, function( param ) { - compiledProtectionFunction.params.push( param ); - }); - }); - } - - function protectEmailLinkAsFunction( email ) { - var retval, - name = compiledProtectionFunction.name, - params = compiledProtectionFunction.params, - paramName, paramValue; - - retval = [ name, '(' ]; - for ( var i = 0; i < params.length; i++ ) { - paramName = params[ i ].toLowerCase(); - paramValue = email[ paramName ]; - - i > 0 && retval.push( ',' ); - retval.push( '\'', paramValue ? escapeSingleQuote( encodeURIComponent( email[ paramName ] ) ) : '', '\'' ); - } - retval.push( ')' ); - return retval.join( '' ); - } - - function protectEmailAddressAsEncodedString( address ) { - var charCode, - length = address.length, - encodedChars = []; - for ( var i = 0; i < length; i++ ) { - charCode = address.charCodeAt( i ); - encodedChars.push( charCode ); - } - return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')'; - } - - function getLinkClass( ele ) { - var className = ele.getAttribute( 'class' ); - return className ? className.replace( /\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, '' ) : ''; - } - - var commonLang = editor.lang.common, - linkLang = editor.lang.link; - - return { - title: linkLang.title, - minWidth: 350, - minHeight: 230, - contents: [ - { - id: 'info', - label: linkLang.info, - title: linkLang.info, - elements: [ - { - id: 'linkType', - type: 'select', - label: linkLang.type, - 'default': 'url', - items: [ - [ linkLang.toUrl, 'url' ], - [ linkLang.toAnchor, 'anchor' ], - [ linkLang.toEmail, 'email' ] - ], - onChange: linkTypeChanged, - setup: function( data ) { - if ( data.type ) - this.setValue( data.type ); - }, - commit: function( data ) { - data.type = this.getValue(); - } - }, - { - type: 'vbox', - id: 'urlOptions', - children: [ - { - type: 'hbox', - widths: [ '25%', '75%' ], - children: [ - { - id: 'protocol', - type: 'select', - label: commonLang.protocol, - 'default': 'http://', - items: [ - // Force 'ltr' for protocol names in BIDI. (#5433) - [ 'http://\u200E', 'http://' ], - [ 'https://\u200E', 'https://' ], - [ 'ftp://\u200E', 'ftp://' ], - [ 'news://\u200E', 'news://' ], - [ linkLang.other, '' ] - ], - setup: function( data ) { - if ( data.url ) - this.setValue( data.url.protocol || '' ); - }, - commit: function( data ) { - if ( !data.url ) - data.url = {}; - - data.url.protocol = this.getValue(); - } - }, - { - type: 'text', - id: 'url', - label: commonLang.url, - required: true, - onLoad: function() { - this.allowOnChange = true; - }, - onKeyUp: function() { - this.allowOnChange = false; - var protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ), - url = this.getValue(), - urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/i, - urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i; - - var protocol = urlOnChangeProtocol.exec( url ); - if ( protocol ) { - this.setValue( url.substr( protocol[ 0 ].length ) ); - protocolCmb.setValue( protocol[ 0 ].toLowerCase() ); - } else if ( urlOnChangeTestOther.test( url ) ) - protocolCmb.setValue( '' ); - - this.allowOnChange = true; - }, - onChange: function() { - if ( this.allowOnChange ) // Dont't call on dialog load. - this.onKeyUp(); - }, - validate: function() { - var dialog = this.getDialog(); - - if ( dialog.getContentElement( 'info', 'linkType' ) && dialog.getValueOf( 'info', 'linkType' ) != 'url' ) - return true; - - if ( (/javascript\:/).test( this.getValue() ) ) { - alert( commonLang.invalidValue ); - return false; - } - - if ( this.getDialog().fakeObj ) // Edit Anchor. - return true; - - var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noUrl ); - return func.apply( this ); - }, - setup: function( data ) { - this.allowOnChange = false; - if ( data.url ) - this.setValue( data.url.url ); - this.allowOnChange = true; - - }, - commit: function( data ) { - // IE will not trigger the onChange event if the mouse has been used - // to carry all the operations #4724 - this.onChange(); - - if ( !data.url ) - data.url = {}; - - data.url.url = this.getValue(); - this.allowOnChange = false; - } - } - ], - setup: function( data ) { - if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) - this.getElement().show(); - } - }, - { - type: 'button', - id: 'browse', - hidden: 'true', - filebrowser: 'info:url', - label: commonLang.browseServer - } - ] - }, - { - type: 'vbox', - id: 'anchorOptions', - width: 260, - align: 'center', - padding: 0, - children: [ - { - type: 'fieldset', - id: 'selectAnchorText', - label: linkLang.selectAnchor, - setup: function( data ) { - if ( data.anchors.length > 0 ) - this.getElement().show(); - else - this.getElement().hide(); - }, - children: [ - { - type: 'hbox', - id: 'selectAnchor', - children: [ - { - type: 'select', - id: 'anchorName', - 'default': '', - label: linkLang.anchorName, - style: 'width: 100%;', - items: [ - [ '' ] - ], - setup: function( data ) { - this.clear(); - this.add( '' ); - for ( var i = 0; i < data.anchors.length; i++ ) { - if ( data.anchors[ i ].name ) - this.add( data.anchors[ i ].name ); - } - - if ( data.anchor ) - this.setValue( data.anchor.name ); - - var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); - if ( linkType && linkType.getValue() == 'email' ) - this.focus(); - }, - commit: function( data ) { - if ( !data.anchor ) - data.anchor = {}; - - data.anchor.name = this.getValue(); - } - }, - { - type: 'select', - id: 'anchorId', - 'default': '', - label: linkLang.anchorId, - style: 'width: 100%;', - items: [ - [ '' ] - ], - setup: function( data ) { - this.clear(); - this.add( '' ); - for ( var i = 0; i < data.anchors.length; i++ ) { - if ( data.anchors[ i ].id ) - this.add( data.anchors[ i ].id ); - } - - if ( data.anchor ) - this.setValue( data.anchor.id ); - }, - commit: function( data ) { - if ( !data.anchor ) - data.anchor = {}; - - data.anchor.id = this.getValue(); - } - } - ], - setup: function( data ) { - if ( data.anchors.length > 0 ) - this.getElement().show(); - else - this.getElement().hide(); - } - } - ] - }, - { - type: 'html', - id: 'noAnchors', - style: 'text-align: center;', - html: '<div role="note" tabIndex="-1">' + CKEDITOR.tools.htmlEncode( linkLang.noAnchors ) + '</div>', - // Focus the first element defined in above html. - focus: true, - setup: function( data ) { - if ( data.anchors.length < 1 ) - this.getElement().show(); - else - this.getElement().hide(); - } - } - ], - setup: function( data ) { - if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) - this.getElement().hide(); - } - }, - { - type: 'vbox', - id: 'emailOptions', - padding: 1, - children: [ - { - type: 'text', - id: 'emailAddress', - label: linkLang.emailAddress, - required: true, - validate: function() { - var dialog = this.getDialog(); - - if ( !dialog.getContentElement( 'info', 'linkType' ) || dialog.getValueOf( 'info', 'linkType' ) != 'email' ) - return true; - - var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noEmail ); - return func.apply( this ); - }, - setup: function( data ) { - if ( data.email ) - this.setValue( data.email.address ); - - var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); - if ( linkType && linkType.getValue() == 'email' ) - this.select(); - }, - commit: function( data ) { - if ( !data.email ) - data.email = {}; - - data.email.address = this.getValue(); - } - }, - { - type: 'text', - id: 'emailSubject', - label: linkLang.emailSubject, - setup: function( data ) { - if ( data.email ) - this.setValue( data.email.subject ); - }, - commit: function( data ) { - if ( !data.email ) - data.email = {}; - - data.email.subject = this.getValue(); - } - }, - { - type: 'textarea', - id: 'emailBody', - label: linkLang.emailBody, - rows: 3, - 'default': '', - setup: function( data ) { - if ( data.email ) - this.setValue( data.email.body ); - }, - commit: function( data ) { - if ( !data.email ) - data.email = {}; - - data.email.body = this.getValue(); - } - } - ], - setup: function( data ) { - if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) - this.getElement().hide(); - } - } - ] - }, - { - id: 'target', - requiredContent: 'a[target]', // This is not fully correct, because some target option requires JS. - label: linkLang.target, - title: linkLang.target, - elements: [ - { - type: 'hbox', - widths: [ '50%', '50%' ], - children: [ - { - type: 'select', - id: 'linkTargetType', - label: commonLang.target, - 'default': 'notSet', - style: 'width : 100%;', - 'items': [ - [ commonLang.notSet, 'notSet' ], - [ linkLang.targetFrame, 'frame' ], - [ linkLang.targetPopup, 'popup' ], - [ commonLang.targetNew, '_blank' ], - [ commonLang.targetTop, '_top' ], - [ commonLang.targetSelf, '_self' ], - [ commonLang.targetParent, '_parent' ] - ], - onChange: targetChanged, - setup: function( data ) { - if ( data.target ) - this.setValue( data.target.type || 'notSet' ); - targetChanged.call( this ); - }, - commit: function( data ) { - if ( !data.target ) - data.target = {}; - - data.target.type = this.getValue(); - } - }, - { - type: 'text', - id: 'linkTargetName', - label: linkLang.targetFrameName, - 'default': '', - setup: function( data ) { - if ( data.target ) - this.setValue( data.target.name ); - }, - commit: function( data ) { - if ( !data.target ) - data.target = {}; - - data.target.name = this.getValue().replace( /\W/gi, '' ); - } - } - ] - }, - { - type: 'vbox', - width: '100%', - align: 'center', - padding: 2, - id: 'popupFeatures', - children: [ - { - type: 'fieldset', - label: linkLang.popupFeatures, - children: [ - { - type: 'hbox', - children: [ - { - type: 'checkbox', - id: 'resizable', - label: linkLang.popupResizable, - setup: setupPopupParams, - commit: commitPopupParams - }, - { - type: 'checkbox', - id: 'status', - label: linkLang.popupStatusBar, - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'checkbox', - id: 'location', - label: linkLang.popupLocationBar, - setup: setupPopupParams, - commit: commitPopupParams - - }, - { - type: 'checkbox', - id: 'toolbar', - label: linkLang.popupToolbar, - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'checkbox', - id: 'menubar', - label: linkLang.popupMenuBar, - setup: setupPopupParams, - commit: commitPopupParams - - }, - { - type: 'checkbox', - id: 'fullscreen', - label: linkLang.popupFullScreen, - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'checkbox', - id: 'scrollbars', - label: linkLang.popupScrollBars, - setup: setupPopupParams, - commit: commitPopupParams - - }, - { - type: 'checkbox', - id: 'dependent', - label: linkLang.popupDependent, - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'text', - widths: [ '50%', '50%' ], - labelLayout: 'horizontal', - label: commonLang.width, - id: 'width', - setup: setupPopupParams, - commit: commitPopupParams - - }, - { - type: 'text', - labelLayout: 'horizontal', - widths: [ '50%', '50%' ], - label: linkLang.popupLeft, - id: 'left', - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - }, - { - type: 'hbox', - children: [ - { - type: 'text', - labelLayout: 'horizontal', - widths: [ '50%', '50%' ], - label: commonLang.height, - id: 'height', - setup: setupPopupParams, - commit: commitPopupParams - - }, - { - type: 'text', - labelLayout: 'horizontal', - label: linkLang.popupTop, - widths: [ '50%', '50%' ], - id: 'top', - setup: setupPopupParams, - commit: commitPopupParams - - } - ] - } - ] - } - ] - } - ] - }, - { - id: 'upload', - label: linkLang.upload, - title: linkLang.upload, - hidden: true, - filebrowser: 'uploadButton', - elements: [ - { - type: 'file', - id: 'upload', - label: commonLang.upload, - style: 'height:40px', - size: 29 - }, - { - type: 'fileButton', - id: 'uploadButton', - label: commonLang.uploadSubmit, - filebrowser: 'info:url', - 'for': [ 'upload', 'upload' ] - } - ] - }, - { - id: 'advanced', - label: linkLang.advanced, - title: linkLang.advanced, - elements: [ - { - type: 'vbox', - padding: 1, - children: [ - { - type: 'hbox', - widths: [ '45%', '35%', '20%' ], - children: [ - { - type: 'text', - id: 'advId', - requiredContent: 'a[id]', - label: linkLang.id, - setup: setupAdvParams, - commit: commitAdvParams - }, - { - type: 'select', - id: 'advLangDir', - requiredContent: 'a[dir]', - label: linkLang.langDir, - 'default': '', - style: 'width:110px', - items: [ - [ commonLang.notSet, '' ], - [ linkLang.langDirLTR, 'ltr' ], - [ linkLang.langDirRTL, 'rtl' ] - ], - setup: setupAdvParams, - commit: commitAdvParams - }, - { - type: 'text', - id: 'advAccessKey', - requiredContent: 'a[accesskey]', - width: '80px', - label: linkLang.acccessKey, - maxLength: 1, - setup: setupAdvParams, - commit: commitAdvParams - - } - ] - }, - { - type: 'hbox', - widths: [ '45%', '35%', '20%' ], - children: [ - { - type: 'text', - label: linkLang.name, - id: 'advName', - requiredContent: 'a[name]', - setup: setupAdvParams, - commit: commitAdvParams - - }, - { - type: 'text', - label: linkLang.langCode, - id: 'advLangCode', - requiredContent: 'a[lang]', - width: '110px', - 'default': '', - setup: setupAdvParams, - commit: commitAdvParams - - }, - { - type: 'text', - label: linkLang.tabIndex, - id: 'advTabIndex', - requiredContent: 'a[tabindex]', - width: '80px', - maxLength: 5, - setup: setupAdvParams, - commit: commitAdvParams - - } - ] - } - ] - }, - { - type: 'vbox', - padding: 1, - children: [ - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - type: 'text', - label: linkLang.advisoryTitle, - requiredContent: 'a[title]', - 'default': '', - id: 'advTitle', - setup: setupAdvParams, - commit: commitAdvParams - - }, - { - type: 'text', - label: linkLang.advisoryContentType, - requiredContent: 'a[type]', - 'default': '', - id: 'advContentType', - setup: setupAdvParams, - commit: commitAdvParams - - } - ] - }, - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - type: 'text', - label: linkLang.cssClasses, - requiredContent: 'a(cke-xyz)', // Random text like 'xyz' will check if all are allowed. - 'default': '', - id: 'advCSSClasses', - setup: setupAdvParams, - commit: commitAdvParams - - }, - { - type: 'text', - label: linkLang.charset, - requiredContent: 'a[charset]', - 'default': '', - id: 'advCharset', - setup: setupAdvParams, - commit: commitAdvParams - - } - ] - }, - { - type: 'hbox', - widths: [ '45%', '55%' ], - children: [ - { - type: 'text', - label: linkLang.rel, - requiredContent: 'a[rel]', - 'default': '', - id: 'advRel', - setup: setupAdvParams, - commit: commitAdvParams - }, - { - type: 'text', - label: linkLang.styles, - requiredContent: 'a{cke-xyz}', // Random text like 'xyz' will check if all are allowed. - 'default': '', - id: 'advStyles', - validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ), - setup: setupAdvParams, - commit: commitAdvParams - } - ] - } - ] - } - ] - } - ], - onShow: function() { - var editor = this.getParentEditor(), - selection = editor.getSelection(), - element = null; - - // Fill in all the relevant fields if there's already one link selected. - if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) ) - selection.selectElement( element ); - else - element = null; - - this.setupContent( parseLink.apply( this, [ editor, element ] ) ); - }, - onOk: function() { - var attributes = {}, - removeAttributes = [], - data = {}, - me = this, - editor = this.getParentEditor(); - - this.commitContent( data ); - - // Compose the URL. - switch ( data.type || 'url' ) { - case 'url': - var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://', - url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || ''; - attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url; - break; - case 'anchor': - var name = ( data.anchor && data.anchor.name ), - id = ( data.anchor && data.anchor.id ); - attributes[ 'data-cke-saved-href' ] = '#' + ( name || id || '' ); - break; - case 'email': - - var linkHref, - email = data.email, - address = email.address; - - switch ( emailProtection ) { - case '': - case 'encode': - { - var subject = encodeURIComponent( email.subject || '' ), - body = encodeURIComponent( email.body || '' ); - - // Build the e-mail parameters first. - var argList = []; - subject && argList.push( 'subject=' + subject ); - body && argList.push( 'body=' + body ); - argList = argList.length ? '?' + argList.join( '&' ) : ''; - - if ( emailProtection == 'encode' ) { - linkHref = [ 'javascript:void(location.href=\'mailto:\'+', - protectEmailAddressAsEncodedString( address ) ]; - // parameters are optional. - argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' ); - - linkHref.push( ')' ); - } else - linkHref = [ 'mailto:', address, argList ]; - - break; - } - default: - { - // Separating name and domain. - var nameAndDomain = address.split( '@', 2 ); - email.name = nameAndDomain[ 0 ]; - email.domain = nameAndDomain[ 1 ]; - - linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ]; - } - } - - attributes[ 'data-cke-saved-href' ] = linkHref.join( '' ); - break; - } - - // Popups and target. - if ( data.target ) { - if ( data.target.type == 'popup' ) { - var onclickList = [ 'window.open(this.href, \'', - data.target.name || '', '\', \'' ]; - var featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen', - 'scrollbars', 'dependent' ]; - var featureLength = featureList.length; - var addFeature = function( featureName ) { - if ( data.target[ featureName ] ) - featureList.push( featureName + '=' + data.target[ featureName ] ); - }; - - for ( var i = 0; i < featureLength; i++ ) - featureList[ i ] = featureList[ i ] + ( data.target[ featureList[ i ] ] ? '=yes' : '=no' ); - addFeature( 'width' ); - addFeature( 'left' ); - addFeature( 'height' ); - addFeature( 'top' ); - - onclickList.push( featureList.join( ',' ), '\'); return false;' ); - attributes[ 'data-cke-pa-onclick' ] = onclickList.join( '' ); - - // Add the "target" attribute. (#5074) - removeAttributes.push( 'target' ); - } else { - if ( data.target.type != 'notSet' && data.target.name ) - attributes.target = data.target.name; - else - removeAttributes.push( 'target' ); - - removeAttributes.push( 'data-cke-pa-onclick', 'onclick' ); - } - } - - // Advanced attributes. - if ( data.adv ) { - var advAttr = function( inputName, attrName ) { - var value = data.adv[ inputName ]; - if ( value ) - attributes[ attrName ] = value; - else - removeAttributes.push( attrName ); - }; - - advAttr( 'advId', 'id' ); - advAttr( 'advLangDir', 'dir' ); - advAttr( 'advAccessKey', 'accessKey' ); - - if ( data.adv[ 'advName' ] ) - attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ]; - else - removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] ); - - advAttr( 'advLangCode', 'lang' ); - advAttr( 'advTabIndex', 'tabindex' ); - advAttr( 'advTitle', 'title' ); - advAttr( 'advContentType', 'type' ); - advAttr( 'advCSSClasses', 'class' ); - advAttr( 'advCharset', 'charset' ); - advAttr( 'advStyles', 'style' ); - advAttr( 'advRel', 'rel' ); - } - - - var selection = editor.getSelection(); - - // Browser need the "href" fro copy/paste link to work. (#6641) - attributes.href = attributes[ 'data-cke-saved-href' ]; - - if ( !this._.selectedElement ) { - var range = selection.getRanges( 1 )[ 0 ]; - - // Use link URL as text with a collapsed cursor. - if ( range.collapsed ) { - // Short mailto link text view (#5736). - var text = new CKEDITOR.dom.text( data.type == 'email' ? data.email.address : attributes[ 'data-cke-saved-href' ], editor.document ); - range.insertNode( text ); - range.selectNodeContents( text ); - } - - // Apply style. - var style = new CKEDITOR.style({ element: 'a', attributes: attributes } ); - style.type = CKEDITOR.STYLE_INLINE; // need to override... dunno why. - style.applyToRange( range ); - range.select(); - } else { - // We're only editing an existing link, so just overwrite the attributes. - var element = this._.selectedElement, - href = element.data( 'cke-saved-href' ), - textView = element.getHtml(); - - element.setAttributes( attributes ); - element.removeAttributes( removeAttributes ); - - if ( data.adv && data.adv.advName && CKEDITOR.plugins.link.synAnchorSelector ) - element.addClass( element.getChildCount() ? 'cke_anchor' : 'cke_anchor_empty' ); - - // Update text view when user changes protocol (#4612). - if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 ) { - // Short mailto link text view (#5736). - element.setHtml( data.type == 'email' ? data.email.address : attributes[ 'data-cke-saved-href' ] ); - } - - selection.selectElement( element ); - delete this._.selectedElement; - } - }, - onLoad: function() { - if ( !editor.config.linkShowAdvancedTab ) - this.hidePage( 'advanced' ); //Hide Advanded tab. - - if ( !editor.config.linkShowTargetTab ) - this.hidePage( 'target' ); //Hide Target tab. - }, - // Inital focus on 'url' field if link is of type URL. - onFocus: function() { - var linkType = this.getContentElement( 'info', 'linkType' ), - urlField; - if ( linkType && linkType.getValue() == 'url' ) { - urlField = this.getContentElement( 'info', 'url' ); - urlField.select(); - } - } - }; -}); - -/** - * The e-mail address anti-spam protection option. The protection will be - * applied when creating or modifying e-mail links through the editor interface. - * - * Two methods of protection can be choosed: - * - * 1. The e-mail parts (name, domain and any other query string) are - * assembled into a function call pattern. Such function must be - * provided by the developer in the pages that will use the contents. - * 2. Only the e-mail address is obfuscated into a special string that - * has no meaning for humans or spam bots, but which is properly - * rendered and accepted by the browser. - * - * Both approaches require JavaScript to be enabled. - * - * // href="mailto:tester@ckeditor.com?subject=subject&body=body" - * config.emailProtection = ''; - * - * // href="<a href=\"javascript:void(location.href=\'mailto:\'+String.fromCharCode(116,101,115,116,101,114,64,99,107,101,100,105,116,111,114,46,99,111,109)+\'?subject=subject&body=body\')\">e-mail</a>" - * config.emailProtection = 'encode'; - * - * // href="javascript:mt('tester','ckeditor.com','subject','body')" - * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)'; - * - * @since 3.1 - * @cfg {String} [emailProtection='' (empty string = disabled)] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/anchor-rtl.png b/addons/website/static/lib/ckeditor/plugins/link/icons/anchor-rtl.png Binary files differdeleted file mode 100644 index 87d717d8287..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/anchor-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/anchor.png b/addons/website/static/lib/ckeditor/plugins/link/icons/anchor.png Binary files differdeleted file mode 100644 index 0ca085f7517..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/anchor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor-rtl.png b/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor-rtl.png Binary files differdeleted file mode 100644 index cd6d4ea64cd..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor.png b/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor.png Binary files differdeleted file mode 100644 index c5869db8356..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/anchor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/link.png b/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/link.png Binary files differdeleted file mode 100644 index bb8a0691fd9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/link.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/unlink.png b/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/unlink.png Binary files differdeleted file mode 100644 index 5af59c26a46..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/hidpi/unlink.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/link.png b/addons/website/static/lib/ckeditor/plugins/link/icons/link.png Binary files differdeleted file mode 100644 index 95092d03f94..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/link.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/icons/unlink.png b/addons/website/static/lib/ckeditor/plugins/link/icons/unlink.png Binary files differdeleted file mode 100644 index 33a159990d9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/icons/unlink.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/link/lang/en.js b/addons/website/static/lib/ckeditor/plugins/link/lang/en.js deleted file mode 100644 index efb7882c7b9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/lang/en.js +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'link', 'en', { - acccessKey: 'Access Key', - advanced: 'Advanced', - advisoryContentType: 'Advisory Content Type', - advisoryTitle: 'Advisory Title', - anchor: { - toolbar: 'Anchor', - menu: 'Edit Anchor', - title: 'Anchor Properties', - name: 'Anchor Name', - errorName: 'Please type the anchor name', - remove: 'Remove Anchor' - }, - anchorId: 'By Element Id', - anchorName: 'By Anchor Name', - charset: 'Linked Resource Charset', - cssClasses: 'Stylesheet Classes', - emailAddress: 'E-Mail Address', - emailBody: 'Message Body', - emailSubject: 'Message Subject', - id: 'Id', - info: 'Link Info', - langCode: 'Language Code', - langDir: 'Language Direction', - langDirLTR: 'Left to Right (LTR)', - langDirRTL: 'Right to Left (RTL)', - menu: 'Edit Link', - name: 'Name', - noAnchors: '(No anchors available in the document)', - noEmail: 'Please type the e-mail address', - noUrl: 'Please type the link URL', - other: '<other>', - popupDependent: 'Dependent (Netscape)', - popupFeatures: 'Popup Window Features', - popupFullScreen: 'Full Screen (IE)', - popupLeft: 'Left Position', - popupLocationBar: 'Location Bar', - popupMenuBar: 'Menu Bar', - popupResizable: 'Resizable', - popupScrollBars: 'Scroll Bars', - popupStatusBar: 'Status Bar', - popupToolbar: 'Toolbar', - popupTop: 'Top Position', - rel: 'Relationship', - selectAnchor: 'Select an Anchor', - styles: 'Style', - tabIndex: 'Tab Index', - target: 'Target', - targetFrame: '<frame>', - targetFrameName: 'Target Frame Name', - targetPopup: '<popup window>', - targetPopupName: 'Popup Window Name', - title: 'Link', - toAnchor: 'Link to anchor in the text', - toEmail: 'E-mail', - toUrl: 'URL', - toolbar: 'Link', - type: 'Link Type', - unlink: 'Unlink', - upload: 'Upload' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/link/plugin.js b/addons/website/static/lib/ckeditor/plugins/link/plugin.js deleted file mode 100755 index f3a1fb45278..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/link/plugin.js +++ /dev/null @@ -1,365 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'link', { - requires: 'dialog,fakeobjects', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'anchor,anchor-rtl,link,unlink', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - // Add the CSS styles for anchor placeholders. - var iconPath = CKEDITOR.getUrl( this.path + 'images' + ( CKEDITOR.env.hidpi ? '/hidpi' : '' ) + '/anchor.png' ), - baseStyle = 'background:url(' + iconPath + ') no-repeat %1 center;border:1px dotted #00f;background-size:16px;'; - - var template = '.%2 a.cke_anchor,' + - '.%2 a.cke_anchor_empty' + - ',.cke_editable.%2 a[name]' + - ',.cke_editable.%2 a[data-cke-saved-name]' + - '{' + - baseStyle + - 'padding-%1:18px;' + - // Show the arrow cursor for the anchor image (FF at least). - 'cursor:auto;' + - '}' + - ( CKEDITOR.env.ie ? ( 'a.cke_anchor_empty' + - '{' + - // Make empty anchor selectable on IE. - 'display:inline-block;' + - '}' - ) : '' ) + - '.%2 img.cke_anchor' + - '{' + - baseStyle + - 'width:16px;' + - 'min-height:15px;' + - // The default line-height on IE. - 'height:1.15em;' + - // Opera works better with "middle" (even if not perfect) - 'vertical-align:' + ( CKEDITOR.env.opera ? 'middle' : 'text-bottom' ) + ';' + - '}'; - - // Styles with contents direction awareness. - function cssWithDir( dir ) { - return template.replace( /%1/g, dir == 'rtl' ? 'right' : 'left' ).replace( /%2/g, 'cke_contents_' + dir ); - } - - CKEDITOR.addCss( cssWithDir( 'ltr' ) + cssWithDir( 'rtl' ) ); - }, - - init: function( editor ) { - var allowed = 'a[!href]', - required = 'a[href]'; - - if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'advanced' ) ) - allowed = allowed.replace( ']', ',accesskey,charset,dir,id,lang,name,rel,tabindex,title,type]{*}(*)' ); - if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'target' ) ) - allowed = allowed.replace( ']', ',target,onclick]' ); - - // Add the link and unlink buttons. - editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link', { - allowedContent: allowed, - requiredContent: required - } ) ); - editor.addCommand( 'anchor', new CKEDITOR.dialogCommand( 'anchor', { - allowedContent: 'a[!name,id]', - requiredContent: 'a[name]' - } ) ); - editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() ); - editor.addCommand( 'removeAnchor', new CKEDITOR.removeAnchorCommand() ); - - editor.setKeystroke( CKEDITOR.CTRL + 76 /*L*/, 'link' ); - - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Link', { - label: editor.lang.link.toolbar, - command: 'link', - toolbar: 'links,10' - }); - editor.ui.addButton( 'Unlink', { - label: editor.lang.link.unlink, - command: 'unlink', - toolbar: 'links,20' - }); - editor.ui.addButton( 'Anchor', { - label: editor.lang.link.anchor.toolbar, - command: 'anchor', - toolbar: 'links,30' - }); - } - - CKEDITOR.dialog.add( 'link', this.path + 'dialogs/link.js' ); - CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' ); - - editor.on( 'doubleclick', function( evt ) { - var element = CKEDITOR.plugins.link.getSelectedLink( editor ) || evt.data.element; - - if ( !element.isReadOnly() ) { - if ( element.is( 'a' ) ) { - evt.data.dialog = ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) ? 'anchor' : 'link'; - editor.getSelection().selectElement( element ); - } else if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) ) - evt.data.dialog = 'anchor'; - } - }); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - editor.addMenuItems({ - anchor: { - label: editor.lang.link.anchor.menu, - command: 'anchor', - group: 'anchor', - order: 1 - }, - - removeAnchor: { - label: editor.lang.link.anchor.remove, - command: 'removeAnchor', - group: 'anchor', - order: 5 - }, - - link: { - label: editor.lang.link.menu, - command: 'link', - group: 'link', - order: 1 - }, - - unlink: { - label: editor.lang.link.unlink, - command: 'unlink', - group: 'link', - order: 5 - } - }); - } - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - if ( !element || element.isReadOnly() ) - return null; - - var anchor = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ); - - if ( !anchor && !( anchor = CKEDITOR.plugins.link.getSelectedLink( editor ) ) ) - return null; - - var menu = {}; - - if ( anchor.getAttribute( 'href' ) && anchor.getChildCount() ) - menu = { link: CKEDITOR.TRISTATE_OFF, unlink: CKEDITOR.TRISTATE_OFF }; - - if ( anchor && anchor.hasAttribute( 'name' ) ) - menu.anchor = menu.removeAnchor = CKEDITOR.TRISTATE_OFF; - - return menu; - }); - } - }, - - afterInit: function( editor ) { - // Register a filter to displaying placeholders after mode change. - - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter, - htmlFilter = dataProcessor && dataProcessor.htmlFilter, - pathFilters = editor._.elementsPath && editor._.elementsPath.filters; - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - a: function( element ) { - var attributes = element.attributes; - if ( !attributes.name ) - return null; - - var isEmpty = !element.children.length; - - if ( CKEDITOR.plugins.link.synAnchorSelector ) { - // IE needs a specific class name to be applied - // to the anchors, for appropriate styling. - var ieClass = isEmpty ? 'cke_anchor_empty' : 'cke_anchor'; - var cls = attributes[ 'class' ]; - if ( attributes.name && ( !cls || cls.indexOf( ieClass ) < 0 ) ) - attributes[ 'class' ] = ( cls || '' ) + ' ' + ieClass; - - if ( isEmpty && CKEDITOR.plugins.link.emptyAnchorFix ) { - attributes.contenteditable = 'false'; - attributes[ 'data-cke-editable' ] = 1; - } - } else if ( CKEDITOR.plugins.link.fakeAnchor && isEmpty ) - return editor.createFakeParserElement( element, 'cke_anchor', 'anchor' ); - - return null; - } - } - }); - } - - if ( CKEDITOR.plugins.link.emptyAnchorFix && htmlFilter ) { - htmlFilter.addRules({ - elements: { - a: function( element ) { - delete element.attributes.contenteditable; - } - } - }); - } - - if ( pathFilters ) { - pathFilters.push( function( element, name ) { - if ( name == 'a' ) { - if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) || ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) ) { - return 'anchor'; - } - } - }); - } - } -}); - -/** - * Set of link plugin's helpers. - * - * @class - * @singleton - */ -CKEDITOR.plugins.link = { - /** - * Get the surrounding link element of current selection. - * - * CKEDITOR.plugins.link.getSelectedLink( editor ); - * - * // The following selection will all return the link element. - * - * <a href="#">li^nk</a> - * <a href="#">[link]</a> - * text[<a href="#">link]</a> - * <a href="#">li[nk</a>] - * [<b><a href="#">li]nk</a></b>] - * [<a href="#"><b>li]nk</b></a> - * - * @since 3.2.1 - * @param {CKEDITOR.editor} editor - */ - getSelectedLink: function( editor ) { - var selection = editor.getSelection(); - var selectedElement = selection.getSelectedElement(); - if ( selectedElement && selectedElement.is( 'a' ) ) - return selectedElement; - - var range = selection.getRanges( true )[ 0 ]; - - if ( range ) { - range.shrink( CKEDITOR.SHRINK_TEXT ); - return editor.elementPath( range.getCommonAncestor() ).contains( 'a', 1 ); - } - return null; - }, - - /** - * Opera and WebKit don't make it possible to select empty anchors. Fake - * elements must be used for them. - * - * @readonly - * @property {Boolean} - */ - fakeAnchor: CKEDITOR.env.opera || CKEDITOR.env.webkit, - - /** - * For browsers that don't support CSS3 `a[name]:empty()`, note IE9 is included because of #7783. - * - * @readonly - * @property {Boolean} - */ - synAnchorSelector: CKEDITOR.env.ie, - - /** - * For browsers that have editing issue with empty anchor. - * - * @readonly - * @property {Boolean} - */ - emptyAnchorFix: CKEDITOR.env.ie && CKEDITOR.env.version < 8, - - /** - * @param {CKEDITOR.editor} editor - * @param {CKEDITOR.dom.element} element - * @todo - */ - tryRestoreFakeAnchor: function( editor, element ) { - if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'anchor' ) { - var link = editor.restoreRealElement( element ); - if ( link.data( 'cke-saved-name' ) ) - return link; - } - } -}; - -// TODO Much probably there's no need to expose these as public objects. - -CKEDITOR.unlinkCommand = function() {}; -CKEDITOR.unlinkCommand.prototype = { - exec: function( editor ) { - var style = new CKEDITOR.style( { element:'a',type:CKEDITOR.STYLE_INLINE,alwaysRemoveElement:1 } ); - editor.removeStyle( style ); - }, - - refresh: function( editor, path ) { - // Despite our initial hope, document.queryCommandEnabled() does not work - // for this in Firefox. So we must detect the state by element paths. - - var element = path.lastElement && path.lastElement.getAscendant( 'a', true ); - - if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() ) - this.setState( CKEDITOR.TRISTATE_OFF ); - else - this.setState( CKEDITOR.TRISTATE_DISABLED ); - }, - - contextSensitive: 1, - startDisabled: 1, - requiredContent: 'a[href]' -}; - -CKEDITOR.removeAnchorCommand = function() {}; -CKEDITOR.removeAnchorCommand.prototype = { - exec: function( editor ) { - var sel = editor.getSelection(), - bms = sel.createBookmarks(), - anchor; - if ( sel && ( anchor = sel.getSelectedElement() ) && ( CKEDITOR.plugins.link.fakeAnchor && !anchor.getChildCount() ? CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, anchor ) : anchor.is( 'a' ) ) ) - anchor.remove( 1 ); - else { - if ( ( anchor = CKEDITOR.plugins.link.getSelectedLink( editor ) ) ) { - if ( anchor.hasAttribute( 'href' ) ) { - anchor.removeAttributes( { name:1,'data-cke-saved-name':1 } ); - anchor.removeClass( 'cke_anchor' ); - } else - anchor.remove( 1 ); - } - } - sel.selectBookmarks( bms ); - }, - requiredContent: 'a[name]' -}; - -CKEDITOR.tools.extend( CKEDITOR.config, { - /** - * @cfg {Boolean} [linkShowAdvancedTab=true] - * @member CKEDITOR.config - * @todo - */ - linkShowAdvancedTab: true, - - /** - * @cfg {Boolean} [linkShowTargetTab=true] - * @member CKEDITOR.config - * @todo - */ - linkShowTargetTab: true -}); diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist-rtl.png b/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist-rtl.png Binary files differdeleted file mode 100644 index 766814a9eda..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist.png b/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist.png Binary files differdeleted file mode 100644 index e57ec7a5a6c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/bulletedlist.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist-rtl.png b/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist-rtl.png Binary files differdeleted file mode 100644 index 50e31560fb8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist.png b/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist.png Binary files differdeleted file mode 100644 index 00f84d0d618..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/bulletedlist.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist-rtl.png b/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist-rtl.png Binary files differdeleted file mode 100644 index 1dff87d21ef..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist.png b/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist.png Binary files differdeleted file mode 100644 index c20b88f4efb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/hidpi/numberedlist.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist-rtl.png b/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist-rtl.png Binary files differdeleted file mode 100644 index 2c3985865a4..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist.png b/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist.png Binary files differdeleted file mode 100644 index f509a85b56a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/icons/numberedlist.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/list/lang/en.js b/addons/website/static/lib/ckeditor/plugins/list/lang/en.js deleted file mode 100644 index fdb0e90892e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'list', 'en', { - bulletedlist: 'Insert/Remove Bulleted List', - numberedlist: 'Insert/Remove Numbered List' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/list/plugin.js b/addons/website/static/lib/ckeditor/plugins/list/plugin.js deleted file mode 100755 index 6d9f5cd4864..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/list/plugin.js +++ /dev/null @@ -1,965 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Insert and remove numbered and bulleted lists. - */ - -(function() { - var listNodeNames = { ol:1,ul:1 }, - emptyTextRegex = /^[\n\r\t ]*$/; - - var whitespaces = CKEDITOR.dom.walker.whitespaces(), - bookmarks = CKEDITOR.dom.walker.bookmark(), - nonEmpty = function( node ) { - return !( whitespaces( node ) || bookmarks( node ) ); - }, - blockBogus = CKEDITOR.dom.walker.bogus(); - - function cleanUpDirection( element ) { - var dir, parent, parentDir; - if ( ( dir = element.getDirection() ) ) { - parent = element.getParent(); - while ( parent && !( parentDir = parent.getDirection() ) ) - parent = parent.getParent(); - - if ( dir == parentDir ) - element.removeAttribute( 'dir' ); - } - } - - // Inheirt inline styles from another element. - function inheirtInlineStyles( parent, el ) { - var style = parent.getAttribute( 'style' ); - - // Put parent styles before child styles. - style && el.setAttribute( 'style', style.replace( /([^;])$/, '$1;' ) + ( el.getAttribute( 'style' ) || '' ) ); - } - - CKEDITOR.plugins.list = { - /** - * Convert a DOM list tree into a data structure that is easier to - * manipulate. This operation should be non-intrusive in the sense that it - * does not change the DOM tree, with the exception that it may add some - * markers to the list item nodes when database is specified. - * - * @member CKEDITOR.plugins.list - * @todo params - */ - listToArray: function( listNode, database, baseArray, baseIndentLevel, grandparentNode ) { - if ( !listNodeNames[ listNode.getName() ] ) - return []; - - if ( !baseIndentLevel ) - baseIndentLevel = 0; - if ( !baseArray ) - baseArray = []; - - // Iterate over all list items to and look for inner lists. - for ( var i = 0, count = listNode.getChildCount(); i < count; i++ ) { - var listItem = listNode.getChild( i ); - - // Fixing malformed nested lists by moving it into a previous list item. (#6236) - if ( listItem.type == CKEDITOR.NODE_ELEMENT && listItem.getName() in CKEDITOR.dtd.$list ) - CKEDITOR.plugins.list.listToArray( listItem, database, baseArray, baseIndentLevel + 1 ); - - // It may be a text node or some funny stuff. - if ( listItem.$.nodeName.toLowerCase() != 'li' ) - continue; - - var itemObj = { 'parent': listNode, indent: baseIndentLevel, element: listItem, contents: [] }; - if ( !grandparentNode ) { - itemObj.grandparent = listNode.getParent(); - if ( itemObj.grandparent && itemObj.grandparent.$.nodeName.toLowerCase() == 'li' ) - itemObj.grandparent = itemObj.grandparent.getParent(); - } else - itemObj.grandparent = grandparentNode; - - if ( database ) - CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length ); - baseArray.push( itemObj ); - - for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount; j++ ) { - child = listItem.getChild( j ); - if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] ) - // Note the recursion here, it pushes inner list items with - // +1 indentation in the correct order. - CKEDITOR.plugins.list.listToArray( child, database, baseArray, baseIndentLevel + 1, itemObj.grandparent ); - else - itemObj.contents.push( child ); - } - } - return baseArray; - }, - - /** - * Convert our internal representation of a list back to a DOM forest. - * - * @member CKEDITOR.plugins.list - * @todo params - */ - arrayToList: function( listArray, database, baseIndex, paragraphMode, dir ) { - if ( !baseIndex ) - baseIndex = 0; - if ( !listArray || listArray.length < baseIndex + 1 ) - return null; - var i, - doc = listArray[ baseIndex ].parent.getDocument(), - retval = new CKEDITOR.dom.documentFragment( doc ), - rootNode = null, - currentIndex = baseIndex, - indentLevel = Math.max( listArray[ baseIndex ].indent, 0 ), - currentListItem = null, - orgDir, block, - paragraphName = ( paragraphMode == CKEDITOR.ENTER_P ? 'p' : 'div' ); - while ( 1 ) { - var item = listArray[ currentIndex ], - itemGrandParent = item.grandparent; - - orgDir = item.element.getDirection( 1 ); - - if ( item.indent == indentLevel ) { - if ( !rootNode || listArray[ currentIndex ].parent.getName() != rootNode.getName() ) { - rootNode = listArray[ currentIndex ].parent.clone( false, 1 ); - dir && rootNode.setAttribute( 'dir', dir ); - retval.append( rootNode ); - } - currentListItem = rootNode.append( item.element.clone( 0, 1 ) ); - - if ( orgDir != rootNode.getDirection( 1 ) ) - currentListItem.setAttribute( 'dir', orgDir ); - - for ( i = 0; i < item.contents.length; i++ ) - currentListItem.append( item.contents[ i ].clone( 1, 1 ) ); - currentIndex++; - } else if ( item.indent == Math.max( indentLevel, 0 ) + 1 ) { - // Maintain original direction (#6861). - var currDir = listArray[ currentIndex - 1 ].element.getDirection( 1 ), - listData = CKEDITOR.plugins.list.arrayToList( listArray, null, currentIndex, paragraphMode, currDir != orgDir ? orgDir : null ); - - // If the next block is an <li> with another list tree as the first - // child, we'll need to append a filler (<br>/NBSP) or the list item - // wouldn't be editable. (#6724) - if ( !currentListItem.getChildCount() && CKEDITOR.env.ie && !( doc.$.documentMode > 7 ) ) - currentListItem.append( doc.createText( '\xa0' ) ); - currentListItem.append( listData.listNode ); - currentIndex = listData.nextIndex; - } else if ( item.indent == -1 && !baseIndex && itemGrandParent ) { - if ( listNodeNames[ itemGrandParent.getName() ] ) { - currentListItem = item.element.clone( false, true ); - if ( orgDir != itemGrandParent.getDirection( 1 ) ) - currentListItem.setAttribute( 'dir', orgDir ); - } else - currentListItem = new CKEDITOR.dom.documentFragment( doc ); - - // Migrate all children to the new container, - // apply the proper text direction. - var dirLoose = itemGrandParent.getDirection( 1 ) != orgDir, - li = item.element, - className = li.getAttribute( 'class' ), - style = li.getAttribute( 'style' ); - - var needsBlock = currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && ( paragraphMode != CKEDITOR.ENTER_BR || dirLoose || style || className ); - - var child, - count = item.contents.length; - for ( i = 0; i < count; i++ ) { - child = item.contents[ i ]; - - if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() ) { - // Apply direction on content blocks. - if ( dirLoose && !child.getDirection() ) - child.setAttribute( 'dir', orgDir ); - - inheirtInlineStyles( li, child ); - - className && child.addClass( className ); - } else if ( needsBlock ) { - // Establish new block to hold text direction and styles. - if ( !block ) { - block = doc.createElement( paragraphName ); - dirLoose && block.setAttribute( 'dir', orgDir ); - } - - // Copy over styles to new block; - style && block.setAttribute( 'style', style ); - className && block.setAttribute( 'class', className ); - - block.append( child.clone( 1, 1 ) ); - } - - currentListItem.append( block || child.clone( 1, 1 ) ); - } - - if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && currentIndex != listArray.length - 1 ) { - var last = currentListItem.getLast(); - if ( last && last.type == CKEDITOR.NODE_ELEMENT && last.getAttribute( 'type' ) == '_moz' ) { - last.remove(); - } - - if ( !( last = currentListItem.getLast( nonEmpty ) && last.type == CKEDITOR.NODE_ELEMENT && last.getName() in CKEDITOR.dtd.$block ) ) { - currentListItem.append( doc.createElement( 'br' ) ); - } - } - - var currentListItemName = currentListItem.$.nodeName.toLowerCase(); - if ( !CKEDITOR.env.ie && ( currentListItemName == 'div' || currentListItemName == 'p' ) ) - currentListItem.appendBogus(); - retval.append( currentListItem ); - rootNode = null; - currentIndex++; - } else - return null; - - block = null; - - if ( listArray.length <= currentIndex || Math.max( listArray[ currentIndex ].indent, 0 ) < indentLevel ) - break; - } - - if ( database ) { - var currentNode = retval.getFirst(), - listRoot = listArray[ 0 ].parent; - - while ( currentNode ) { - if ( currentNode.type == CKEDITOR.NODE_ELEMENT ) { - // Clear marker attributes for the new list tree made of cloned nodes, if any. - CKEDITOR.dom.element.clearMarkers( database, currentNode ); - - // Clear redundant direction attribute specified on list items. - if ( currentNode.getName() in CKEDITOR.dtd.$listItem ) - cleanUpDirection( currentNode ); - } - - currentNode = currentNode.getNextSourceNode(); - } - } - - return { listNode: retval, nextIndex: currentIndex }; - } - }; - - function changeListType( editor, groupObj, database, listsCreated ) { - // This case is easy... - // 1. Convert the whole list into a one-dimensional array. - // 2. Change the list type by modifying the array. - // 3. Recreate the whole list by converting the array to a list. - // 4. Replace the original list with the recreated list. - var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ), - selectedListItems = []; - - for ( var i = 0; i < groupObj.contents.length; i++ ) { - var itemNode = groupObj.contents[ i ]; - itemNode = itemNode.getAscendant( 'li', true ); - if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) ) - continue; - selectedListItems.push( itemNode ); - CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true ); - } - - var root = groupObj.root, - doc = root.getDocument(), - listNode, newListNode; - - for ( i = 0; i < selectedListItems.length; i++ ) { - var listIndex = selectedListItems[ i ].getCustomData( 'listarray_index' ); - listNode = listArray[ listIndex ].parent; - - // Switch to new list node for this particular item. - if ( !listNode.is( this.type ) ) { - newListNode = doc.createElement( this.type ); - // Copy all attributes, except from 'start' and 'type'. - listNode.copyAttributes( newListNode, { start:1,type:1 } ); - // The list-style-type property should be ignored. - newListNode.removeStyle( 'list-style-type' ); - listArray[ listIndex ].parent = newListNode; - } - } - - var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode ); - var child, - length = newList.listNode.getChildCount(); - for ( i = 0; i < length && ( child = newList.listNode.getChild( i ) ); i++ ) { - if ( child.getName() == this.type ) - listsCreated.push( child ); - } - newList.listNode.replace( groupObj.root ); - } - - var headerTagRegex = /^h[1-6]$/; - - function createList( editor, groupObj, listsCreated ) { - var contents = groupObj.contents, - doc = groupObj.root.getDocument(), - listContents = []; - - // It is possible to have the contents returned by DomRangeIterator to be the same as the root. - // e.g. when we're running into table cells. - // In such a case, enclose the childNodes of contents[0] into a <div>. - if ( contents.length == 1 && contents[ 0 ].equals( groupObj.root ) ) { - var divBlock = doc.createElement( 'div' ); - contents[ 0 ].moveChildren && contents[ 0 ].moveChildren( divBlock ); - contents[ 0 ].append( divBlock ); - contents[ 0 ] = divBlock; - } - - // Calculate the common parent node of all content blocks. - var commonParent = groupObj.contents[ 0 ].getParent(); - for ( var i = 0; i < contents.length; i++ ) - commonParent = commonParent.getCommonAncestor( contents[ i ].getParent() ); - - var useComputedState = editor.config.useComputedState, - listDir, explicitDirection; - - useComputedState = useComputedState === undefined || useComputedState; - - // We want to insert things that are in the same tree level only, so calculate the contents again - // by expanding the selected blocks to the same tree level. - for ( i = 0; i < contents.length; i++ ) { - var contentNode = contents[ i ], - parentNode; - while ( ( parentNode = contentNode.getParent() ) ) { - if ( parentNode.equals( commonParent ) ) { - listContents.push( contentNode ); - - // Determine the lists's direction. - if ( !explicitDirection && contentNode.getDirection() ) - explicitDirection = 1; - - var itemDir = contentNode.getDirection( useComputedState ); - - if ( listDir !== null ) { - // If at least one LI have a different direction than current listDir, we can't have listDir. - if ( listDir && listDir != itemDir ) - listDir = null; - else - listDir = itemDir; - } - - break; - } - contentNode = parentNode; - } - } - - if ( listContents.length < 1 ) - return; - - // Insert the list to the DOM tree. - var insertAnchor = listContents[ listContents.length - 1 ].getNext(), - listNode = doc.createElement( this.type ); - - listsCreated.push( listNode ); - - var contentBlock, listItem; - - while ( listContents.length ) { - contentBlock = listContents.shift(); - listItem = doc.createElement( 'li' ); - - // Preserve preformat block and heading structure when converting to list item. (#5335) (#5271) - if ( contentBlock.is( 'pre' ) || headerTagRegex.test( contentBlock.getName() ) ) - contentBlock.appendTo( listItem ); - else { - contentBlock.copyAttributes( listItem ); - // Remove direction attribute after it was merged into list root. (#7657) - if ( listDir && contentBlock.getDirection() ) { - listItem.removeStyle( 'direction' ); - listItem.removeAttribute( 'dir' ); - } - contentBlock.moveChildren( listItem ); - contentBlock.remove(); - } - - listItem.appendTo( listNode ); - } - - // Apply list root dir only if it has been explicitly declared. - if ( listDir && explicitDirection ) - listNode.setAttribute( 'dir', listDir ); - - if ( insertAnchor ) - listNode.insertBefore( insertAnchor ); - else - listNode.appendTo( commonParent ); - } - - function removeList( editor, groupObj, database ) { - // This is very much like the change list type operation. - // Except that we're changing the selected items' indent to -1 in the list array. - var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ), - selectedListItems = []; - - for ( var i = 0; i < groupObj.contents.length; i++ ) { - var itemNode = groupObj.contents[ i ]; - itemNode = itemNode.getAscendant( 'li', true ); - if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) ) - continue; - selectedListItems.push( itemNode ); - CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true ); - } - - var lastListIndex = null; - for ( i = 0; i < selectedListItems.length; i++ ) { - var listIndex = selectedListItems[ i ].getCustomData( 'listarray_index' ); - listArray[ listIndex ].indent = -1; - lastListIndex = listIndex; - } - - // After cutting parts of the list out with indent=-1, we still have to maintain the array list - // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the - // list cannot be converted back to a real DOM list. - for ( i = lastListIndex + 1; i < listArray.length; i++ ) { - if ( listArray[ i ].indent > listArray[ i - 1 ].indent + 1 ) { - var indentOffset = listArray[ i - 1 ].indent + 1 - listArray[ i ].indent; - var oldIndent = listArray[ i ].indent; - while ( listArray[ i ] && listArray[ i ].indent >= oldIndent ) { - listArray[ i ].indent += indentOffset; - i++; - } - i--; - } - } - - var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, groupObj.root.getAttribute( 'dir' ) ); - - // Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836) - var docFragment = newList.listNode, - boundaryNode, siblingNode; - - function compensateBrs( isStart ) { - if ( ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() ) && !( boundaryNode.is && boundaryNode.isBlockBoundary() ) && ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ] - ( CKEDITOR.dom.walker.invisible( true ) ) ) && !( siblingNode.is && siblingNode.isBlockBoundary( { br:1 } ) ) ) - editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode ); - } - compensateBrs( true ); - compensateBrs(); - - docFragment.replace( groupObj.root ); - } - - function listCommand( name, type ) { - this.name = name; - this.type = type; - this.context = type; - this.allowedContent = type + ' li'; - this.requiredContent = type; - } - - var elementType = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT ); - - // Merge child nodes with direction preserved. (#7448) - function mergeChildren( from, into, refNode, forward ) { - var child, itemDir; - while ( ( child = from[ forward ? 'getLast' : 'getFirst' ]( elementType ) ) ) { - if ( ( itemDir = child.getDirection( 1 ) ) !== into.getDirection( 1 ) ) - child.setAttribute( 'dir', itemDir ); - - child.remove(); - - refNode ? child[ forward ? 'insertBefore' : 'insertAfter' ]( refNode ) : into.append( child, forward ); - } - } - - listCommand.prototype = { - exec: function( editor ) { - // Run state check first of all. - this.refresh( editor, editor.elementPath() ); - - var doc = editor.document, - config = editor.config, - selection = editor.getSelection(), - ranges = selection && selection.getRanges( true ); - - // Midas lists rule #1 says we can create a list even in an empty document. - // But DOM iterator wouldn't run if the document is really empty. - // So create a paragraph if the document is empty and we're going to create a list. - if ( this.state == CKEDITOR.TRISTATE_OFF ) { - var editable = editor.editable(); - if ( !editable.getFirst( nonEmpty ) ) { - config.enterMode == CKEDITOR.ENTER_BR ? editable.appendBogus() : ranges[ 0 ].fixBlock( 1, config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ); - - selection.selectRanges( ranges ); - } - // Maybe a single range there enclosing the whole list, - // turn on the list state manually(#4129). - else { - var range = ranges.length == 1 && ranges[ 0 ], - enclosedNode = range && range.getEnclosedNode(); - if ( enclosedNode && enclosedNode.is && this.type == enclosedNode.getName() ) - this.setState( CKEDITOR.TRISTATE_ON ); - } - } - - var bookmarks = selection.createBookmarks( true ); - - // Group the blocks up because there are many cases where multiple lists have to be created, - // or multiple lists have to be cancelled. - var listGroups = [], - database = {}, - rangeIterator = ranges.createIterator(), - index = 0; - - while ( ( range = rangeIterator.getNextRange() ) && ++index ) { - var boundaryNodes = range.getBoundaryNodes(), - startNode = boundaryNodes.startNode, - endNode = boundaryNodes.endNode; - - if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' ) - range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START ); - - if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' ) - range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END ); - - var iterator = range.createIterator(), - block; - - iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF ); - - while ( ( block = iterator.getNextParagraph() ) ) { - // Avoid duplicate blocks get processed across ranges. - if ( block.getCustomData( 'list_block' ) ) - continue; - else - CKEDITOR.dom.element.setMarker( database, block, 'list_block', 1 ); - - var path = editor.elementPath( block ), - pathElements = path.elements, - pathElementsCount = pathElements.length, - listNode = null, - processedFlag = 0, - blockLimit = path.blockLimit, - element; - - // First, try to group by a list ancestor. - for ( var i = pathElementsCount - 1; i >= 0 && ( element = pathElements[ i ] ); i-- ) { - if ( listNodeNames[ element.getName() ] && blockLimit.contains( element ) ) // Don't leak outside block limit (#3940). - { - // If we've encountered a list inside a block limit - // The last group object of the block limit element should - // no longer be valid. Since paragraphs after the list - // should belong to a different group of paragraphs before - // the list. (Bug #1309) - blockLimit.removeCustomData( 'list_group_object_' + index ); - - var groupObj = element.getCustomData( 'list_group_object' ); - if ( groupObj ) - groupObj.contents.push( block ); - else { - groupObj = { root: element, contents: [ block ] }; - listGroups.push( groupObj ); - CKEDITOR.dom.element.setMarker( database, element, 'list_group_object', groupObj ); - } - processedFlag = 1; - break; - } - } - - if ( processedFlag ) - continue; - - // No list ancestor? Group by block limit, but don't mix contents from different ranges. - var root = blockLimit; - if ( root.getCustomData( 'list_group_object_' + index ) ) - root.getCustomData( 'list_group_object_' + index ).contents.push( block ); - else { - groupObj = { root: root, contents: [ block ] }; - CKEDITOR.dom.element.setMarker( database, root, 'list_group_object_' + index, groupObj ); - listGroups.push( groupObj ); - } - } - } - - // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element. - // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking - // at the group that's not rooted at lists. So we have three cases to handle. - var listsCreated = []; - while ( listGroups.length > 0 ) { - groupObj = listGroups.shift(); - if ( this.state == CKEDITOR.TRISTATE_OFF ) { - if ( listNodeNames[ groupObj.root.getName() ] ) - changeListType.call( this, editor, groupObj, database, listsCreated ); - else - createList.call( this, editor, groupObj, listsCreated ); - } else if ( this.state == CKEDITOR.TRISTATE_ON && listNodeNames[ groupObj.root.getName() ] ) - removeList.call( this, editor, groupObj, database ); - } - - // For all new lists created, merge into adjacent, same type lists. - for ( i = 0; i < listsCreated.length; i++ ) - mergeListSiblings( listsCreated[ i ] ); - - // Clean up, restore selection and update toolbar button states. - CKEDITOR.dom.element.clearAllMarkers( database ); - selection.selectBookmarks( bookmarks ); - editor.focus(); - }, - - refresh: function( editor, path ) { - var list = path.contains( listNodeNames, 1 ), - limit = path.blockLimit || path.root; - - // 1. Only a single type of list activate. - // 2. Do not show list outside of block limit. - if ( list && limit.contains( list ) ) - this.setState( list.is( this.type ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - else - this.setState( CKEDITOR.TRISTATE_OFF ); - } - }; - - var dtd = CKEDITOR.dtd; - var tailNbspRegex = /[\t\r\n ]*(?: |\xa0)$/; - - // Merge list adjacent, of same type lists. - function mergeListSiblings( listNode ) - { - var mergeSibling; - ( mergeSibling = function( rtl ) - { - var sibling = listNode[ rtl ? 'getPrevious' : 'getNext' ]( nonEmpty ); - if ( sibling && - sibling.type == CKEDITOR.NODE_ELEMENT && - sibling.is( listNode.getName() ) ) - { - // Move children order by merge direction.(#3820) - mergeChildren( listNode, sibling, null, !rtl ); - - listNode.remove(); - listNode = sibling; - } - } )(); - mergeSibling( 1 ); - } - - function indexOfFirstChildElement( element, tagNameList ) { - var child, - children = element.children, - length = children.length; - - for ( var i = 0; i < length; i++ ) { - child = children[ i ]; - if ( child.name && ( child.name in tagNameList ) ) - return i; - } - - return length; - } - - // Check if node is block element that recieves text. - function isTextBlock( node ) { - return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in CKEDITOR.dtd.$block || node.getName() in CKEDITOR.dtd.$listItem ) && CKEDITOR.dtd[ node.getName() ][ '#' ]; - } - - // Join visually two block lines. - function joinNextLineToCursor( editor, cursor, nextCursor ) { - editor.fire( 'saveSnapshot' ); - - // Merge with previous block's content. - nextCursor.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ); - var frag = nextCursor.extractContents(); - - cursor.trim( false, true ); - var bm = cursor.createBookmark(); - - // Kill original bogus; - var currentPath = new CKEDITOR.dom.elementPath( cursor.startContainer ), - pathBlock = currentPath.block, - currentBlock = currentPath.lastElement.getAscendant( 'li', 1 ) || pathBlock, - nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ), - nextLi = nextPath.contains( CKEDITOR.dtd.$listItem ), - nextList = nextPath.contains( CKEDITOR.dtd.$list ), - last; - - // Remove bogus node the current block/pseudo block. - if ( pathBlock ) { - var bogus = pathBlock.getBogus(); - bogus && bogus.remove(); - } - else if ( nextList ) { - last = nextList.getPrevious( nonEmpty ); - if ( last && blockBogus( last ) ) - last.remove(); - } - - // Kill the tail br in extracted. - last = frag.getLast(); - if ( last && last.type == CKEDITOR.NODE_ELEMENT && last.is( 'br' ) ) - last.remove(); - - // Insert fragment at the range position. - var nextNode = cursor.startContainer.getChild( cursor.startOffset ); - if ( nextNode ) - frag.insertBefore( nextNode ); - else - cursor.startContainer.append( frag ); - - // Move the sub list nested in the next list item. - if ( nextLi ) { - var sublist = getSubList( nextLi ); - if ( sublist ) { - // If next line is in the sub list of the current list item. - if ( currentBlock.contains( nextLi ) ) { - mergeChildren( sublist, nextLi.getParent(), nextLi ); - sublist.remove(); - } - // Migrate the sub list to current list item. - else - currentBlock.append( sublist ); - } - } - - var nextBlock, parent; - // Remove any remaining zombies path blocks at the end after line merged. - while ( nextCursor.checkStartOfBlock() && nextCursor.checkEndOfBlock() ) { - nextPath = nextCursor.startPath(); - nextBlock = nextPath.block; - - // Check if also to remove empty list. - if ( nextBlock.is( 'li' ) ) { - parent = nextBlock.getParent(); - if ( nextBlock.equals( parent.getLast( nonEmpty ) ) && nextBlock.equals( parent.getFirst( nonEmpty ) ) ) - nextBlock = parent; - } - - nextCursor.moveToPosition( nextBlock, CKEDITOR.POSITION_BEFORE_START ); - nextBlock.remove(); - } - - // Check if need to further merge with the list resides after the merged block. (#9080) - var walkerRng = nextCursor.clone(), editable = editor.editable(); - walkerRng.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END ); - var walker = new CKEDITOR.dom.walker( walkerRng ); - walker.evaluator = function( node ) { return nonEmpty( node ) && !blockBogus( node ); }; - var next = walker.next(); - if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getName() in CKEDITOR.dtd.$list ) - mergeListSiblings( next ); - - cursor.moveToBookmark( bm ); - - // Make fresh selection. - cursor.select(); - - editor.fire( 'saveSnapshot' ); - } - - function getSubList( li ) { - var last = li.getLast( nonEmpty ); - return last && last.type == CKEDITOR.NODE_ELEMENT && last.getName() in listNodeNames ? last : null; - } - - CKEDITOR.plugins.add( 'list', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'bulletedlist,bulletedlist-rtl,numberedlist,numberedlist-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - requires: 'indentlist', - init: function( editor ) { - if ( editor.blockless ) - return; - - // Register commands. - editor.addCommand( 'numberedlist', new listCommand( 'numberedlist', 'ol' ) ); - editor.addCommand( 'bulletedlist', new listCommand( 'bulletedlist', 'ul' ) ); - - // Register the toolbar button. - if ( editor.ui.addButton ) { - editor.ui.addButton( 'NumberedList', { - label: editor.lang.list.numberedlist, - command: 'numberedlist', - directional: true, - toolbar: 'list,10' - }); - editor.ui.addButton( 'BulletedList', { - label: editor.lang.list.bulletedlist, - command: 'bulletedlist', - directional: true, - toolbar: 'list,20' - }); - } - - // Handled backspace/del key to join list items. (#8248,#9080) - editor.on( 'key', function( evt ) { - var key = evt.data.keyCode; - - // DEl/BACKSPACE - if ( editor.mode == 'wysiwyg' && key in { 8:1,46:1 } ) { - var sel = editor.getSelection(), - range = sel.getRanges()[ 0 ], - path = range && range.startPath(); - - if ( !range || !range.collapsed ) - return; - - path = new CKEDITOR.dom.elementPath( range.startContainer ); - var isBackspace = key == 8; - var editable = editor.editable(); - var walker = new CKEDITOR.dom.walker( range.clone() ); - walker.evaluator = function( node ) { - return nonEmpty( node ) && !blockBogus( node ); - }; - // Backspace/Del behavior at the start/end of table is handled in core. - walker.guard = function( node, isOut ) { - return !( isOut && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'table' ) ); - }; - - var cursor = range.clone(); - - if ( isBackspace ) { - var previous, joinWith; - - // Join a sub list's first line, with the previous visual line in parent. - if ( ( previous = path.contains( listNodeNames ) ) && - range.checkBoundaryOfElement( previous, CKEDITOR.START ) && - ( previous = previous.getParent() ) && previous.is( 'li' ) && - ( previous = getSubList( previous ) ) ) { - joinWith = previous; - previous = previous.getPrevious( nonEmpty ); - // Place cursor before the nested list. - cursor.moveToPosition( - previous && blockBogus( previous ) ? previous : joinWith, - CKEDITOR.POSITION_BEFORE_START ); - } - // Join any line following a list, with the last visual line of the list. - else { - walker.range.setStartAt( editable, CKEDITOR.POSITION_AFTER_START ); - walker.range.setEnd( range.startContainer, range.startOffset ); - - previous = walker.previous(); - - if ( previous && previous.type == CKEDITOR.NODE_ELEMENT && - ( previous.getName() in listNodeNames || - previous.is( 'li' ) ) ) { - if ( !previous.is( 'li' ) ) { - walker.range.selectNodeContents( previous ); - walker.reset(); - walker.evaluator = isTextBlock; - previous = walker.previous(); - } - - joinWith = previous; - // Place cursor at the end of previous block. - cursor.moveToElementEditEnd( joinWith ); - } - } - - if ( joinWith ) { - joinNextLineToCursor( editor, cursor, range ); - evt.cancel(); - } - else { - var list = path.contains( listNodeNames ); - // Backspace pressed at the start of list outdents the first list item. (#9129) - if ( list && range.checkBoundaryOfElement( list, CKEDITOR.START ) ) { - li = list.getFirst( nonEmpty ); - - if ( range.checkBoundaryOfElement( li, CKEDITOR.START ) ) { - previous = list.getPrevious( nonEmpty ); - - // Only if the list item contains a sub list, do nothing but - // simply move cursor backward one character. - if ( getSubList( li ) ) { - if ( previous ) { - range.moveToElementEditEnd( previous ); - range.select(); - } - - evt.cancel(); - } - else { - editor.execCommand( 'outdent' ); - evt.cancel(); - } - } - } - } - - } else { - - var next, nextLine, li = path.contains( 'li' ); - - if ( li ) { - walker.range.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END ); - - var last = li.getLast( nonEmpty ); - var block = last && isTextBlock( last ) ? last : li; - - // Indicate cursor at the visual end of an list item. - var isAtEnd = 0; - - next = walker.next(); - - // When list item contains a sub list. - if ( next && next.type == CKEDITOR.NODE_ELEMENT && - next.getName() in listNodeNames && - next.equals( last ) ) - { - isAtEnd = 1; - - // Move to the first item in sub list. - next = walker.next(); - } - // Right at the end of list item. - else if ( range.checkBoundaryOfElement( block, CKEDITOR.END ) ) - isAtEnd = 1; - - - if ( isAtEnd && next ) { - // Put cursor range there. - nextLine = range.clone(); - nextLine.moveToElementEditStart( next ); - - joinNextLineToCursor( editor, cursor, nextLine ); - evt.cancel(); - } - } - else - { - // Handle Del key pressed before the list. - walker.range.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END ); - next = walker.next(); - - if ( next && next.type == CKEDITOR.NODE_ELEMENT && - next.is( listNodeNames ) ) { - // The start <li> - next = next.getFirst( nonEmpty ); - - // Simply remove the current empty block, move cursor to the - // subsequent list. - if ( path.block && - range.checkStartOfBlock() && - range.checkEndOfBlock() ) { - path.block.remove(); - range.moveToElementEditStart( next ); - range.select(); - evt.cancel(); - } - // Preventing the default (merge behavior), but simply move - // the cursor one character forward if subsequent list item - // contains sub list. - else if ( getSubList( next ) ) { - range.moveToElementEditStart( next ); - range.select(); - evt.cancel(); - } - // Merge the first list item with the current line. - else { - nextLine = range.clone(); - nextLine.moveToElementEditStart( next ); - joinNextLineToCursor( editor, cursor, nextLine ); - evt.cancel(); - } - } - } - - } - - // The backspace/del could potentially put cursor at a bad position, - // being it handled or not, check immediately the selection to have it fixed. - setTimeout( function() { editor.selectionChange( 1 ); } ); - } - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/listblock/plugin.js b/addons/website/static/lib/ckeditor/plugins/listblock/plugin.js deleted file mode 100644 index 977212af62a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/listblock/plugin.js +++ /dev/null @@ -1,243 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'listblock', { - requires: 'panel', - - onLoad: function() { - var list = CKEDITOR.addTemplate( 'panel-list', '<ul role="presentation" class="cke_panel_list">{items}</ul>' ), - listItem = CKEDITOR.addTemplate( 'panel-list-item', '<li id="{id}" class="cke_panel_listItem" role=presentation>' + - '<a id="{id}_option" _cke_focus=1 hidefocus=true' + - ' title="{title}"' + - ' href="javascript:void(\'{val}\')" ' + - ' {onclick}="CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;"' + // #188 - ' role="option">' + - '{text}' + - '</a>' + - '</li>' ), - listGroup = CKEDITOR.addTemplate( 'panel-list-group', '<h1 id="{id}" class="cke_panel_grouptitle" role="presentation" >{label}</h1>' ); - - CKEDITOR.ui.panel.prototype.addListBlock = function( name, definition ) { - return this.addBlock( name, new CKEDITOR.ui.listBlock( this.getHolderElement(), definition ) ); - }; - - CKEDITOR.ui.listBlock = CKEDITOR.tools.createClass({ - base: CKEDITOR.ui.panel.block, - - $: function( blockHolder, blockDefinition ) { - blockDefinition = blockDefinition || {}; - - var attribs = blockDefinition.attributes || ( blockDefinition.attributes = {} ); - ( this.multiSelect = !!blockDefinition.multiSelect ) && ( attribs[ 'aria-multiselectable' ] = true ); - // Provide default role of 'listbox'. - !attribs.role && ( attribs.role = 'listbox' ); - - // Call the base contructor. - this.base.apply( this, arguments ); - - // Set the proper a11y attributes. - this.element.setAttribute( 'role', attribs.role ); - - var keys = this.keys; - keys[ 40 ] = 'next'; // ARROW-DOWN - keys[ 9 ] = 'next'; // TAB - keys[ 38 ] = 'prev'; // ARROW-UP - keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB - keys[ 32 ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // SPACE - CKEDITOR.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (#8041). - - this._.pendingHtml = []; - this._.pendingList = []; - this._.items = {}; - this._.groups = {}; - }, - - _: { - close: function() { - if ( this._.started ) { - var output = list.output({ items: this._.pendingList.join( '' ) } ); - this._.pendingList = []; - this._.pendingHtml.push( output ); - delete this._.started; - } - }, - - getClick: function() { - if ( !this._.click ) { - this._.click = CKEDITOR.tools.addFunction( function( value ) { - var marked = this.toggle( value ); - if ( this.onClick ) - this.onClick( value, marked ); - }, this ); - } - return this._.click; - } - }, - - proto: { - add: function( value, html, title ) { - var id = CKEDITOR.tools.getNextId(); - - if ( !this._.started ) { - this._.started = 1; - this._.size = this._.size || 0; - } - - this._.items[ value ] = id; - - var data = { - id: id, - val: value, - onclick: CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick', - clickFn: this._.getClick(), - title: title || value, - text: html || value - }; - - this._.pendingList.push( listItem.output( data ) ); - }, - - startGroup: function( title ) { - this._.close(); - - var id = CKEDITOR.tools.getNextId(); - - this._.groups[ title ] = id; - - this._.pendingHtml.push( listGroup.output({ id: id, label: title } ) ); - }, - - commit: function() { - this._.close(); - this.element.appendHtml( this._.pendingHtml.join( '' ) ); - delete this._.size; - - this._.pendingHtml = []; - }, - - toggle: function( value ) { - var isMarked = this.isMarked( value ); - - if ( isMarked ) - this.unmark( value ); - else - this.mark( value ); - - return !isMarked; - }, - - hideGroup: function( groupTitle ) { - var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ), - list = group && group.getNext(); - - if ( group ) { - group.setStyle( 'display', 'none' ); - - if ( list && list.getName() == 'ul' ) - list.setStyle( 'display', 'none' ); - } - }, - - hideItem: function( value ) { - this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' ); - }, - - showAll: function() { - var items = this._.items, - groups = this._.groups, - doc = this.element.getDocument(); - - for ( var value in items ) { - doc.getById( items[ value ] ).setStyle( 'display', '' ); - } - - for ( var title in groups ) { - var group = doc.getById( groups[ title ] ), - list = group.getNext(); - - group.setStyle( 'display', '' ); - - if ( list && list.getName() == 'ul' ) - list.setStyle( 'display', '' ); - } - }, - - mark: function( value ) { - if ( !this.multiSelect ) - this.unmarkAll(); - - var itemId = this._.items[ value ], - item = this.element.getDocument().getById( itemId ); - item.addClass( 'cke_selected' ); - - this.element.getDocument().getById( itemId + '_option' ).setAttribute( 'aria-selected', true ); - this.onMark && this.onMark( item ); - }, - - unmark: function( value ) { - var doc = this.element.getDocument(), - itemId = this._.items[ value ], - item = doc.getById( itemId ); - - item.removeClass( 'cke_selected' ); - doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' ); - - this.onUnmark && this.onUnmark( item ); - }, - - unmarkAll: function() { - var items = this._.items, - doc = this.element.getDocument(); - - for ( var value in items ) { - var itemId = items[ value ]; - - doc.getById( itemId ).removeClass( 'cke_selected' ); - doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' ); - } - - this.onUnmark && this.onUnmark(); - }, - - isMarked: function( value ) { - return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' ); - }, - - focus: function( value ) { - this._.focusIndex = -1; - - var links = this.element.getElementsByTag( 'a' ), - link, - selected, - i = -1; - - if ( value ) { - selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst(); - - while ( ( link = links.getItem( ++i ) ) ) { - if ( link.equals( selected ) ) { - this._.focusIndex = i; - break; - } - } - } - else { - var scrollTop = CKEDITOR.document.getWindow().getScrollPosition().y; - - this.element.focus(); - - // #10623 - restore the viewport's scroll position after focusing list element. - if ( CKEDITOR.env.webkit ) - CKEDITOR.document[ CKEDITOR.env.webkit ? 'getBody' : 'getDocumentElement' ]().$.scrollTop = scrollTop; - } - - selected && setTimeout( function() { - selected.focus(); - }, 0 ); - } - } - }); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/liststyle/dialogs/liststyle.js b/addons/website/static/lib/ckeditor/plugins/liststyle/dialogs/liststyle.js deleted file mode 100644 index 6403f8f553d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/liststyle/dialogs/liststyle.js +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - function getListElement( editor, listTag ) { - var range; - try { - range = editor.getSelection().getRanges()[ 0 ]; - } catch ( e ) { - return null; - } - - range.shrink( CKEDITOR.SHRINK_TEXT ); - return editor.elementPath( range.getCommonAncestor() ).contains( listTag, 1 ); - } - - var listItem = function( node ) { - return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' ); - }; - - var mapListStyle = { - 'a': 'lower-alpha', - 'A': 'upper-alpha', - 'i': 'lower-roman', - 'I': 'upper-roman', - '1': 'decimal', - 'disc': 'disc', - 'circle': 'circle', - 'square': 'square' - }; - - function listStyle( editor, startupPage ) { - var lang = editor.lang.liststyle; - if ( startupPage == 'bulletedListStyle' ) { - return { - title: lang.bulletedTitle, - minWidth: 300, - minHeight: 50, - contents: [ - { - id: 'info', - accessKey: 'I', - elements: [ - { - type: 'select', - label: lang.type, - id: 'type', - align: 'center', - style: 'width:150px', - items: [ - [ lang.notset, '' ], - [ lang.circle, 'circle' ], - [ lang.disc, 'disc' ], - [ lang.square, 'square' ] - ], - setup: function( element ) { - var value = element.getStyle( 'list-style-type' ) || mapListStyle[ element.getAttribute( 'type' ) ] || element.getAttribute( 'type' ) || ''; - - this.setValue( value ); - }, - commit: function( element ) { - var value = this.getValue(); - if ( value ) - element.setStyle( 'list-style-type', value ); - else - element.removeStyle( 'list-style-type' ); - } - } - ] - } - ], - onShow: function() { - var editor = this.getParentEditor(), - element = getListElement( editor, 'ul' ); - - element && this.setupContent( element ); - }, - onOk: function() { - var editor = this.getParentEditor(), - element = getListElement( editor, 'ul' ); - - element && this.commitContent( element ); - } - }; - } else if ( startupPage == 'numberedListStyle' ) { - - var listStyleOptions = [ - [ lang.notset, '' ], - [ lang.lowerRoman, 'lower-roman' ], - [ lang.upperRoman, 'upper-roman' ], - [ lang.lowerAlpha, 'lower-alpha' ], - [ lang.upperAlpha, 'upper-alpha' ], - [ lang.decimal, 'decimal' ] - ]; - - if ( !CKEDITOR.env.ie || CKEDITOR.env.version > 7 ) { - listStyleOptions.concat( [ - [ lang.armenian, 'armenian' ], - [ lang.decimalLeadingZero, 'decimal-leading-zero' ], - [ lang.georgian, 'georgian' ], - [ lang.lowerGreek, 'lower-greek' ] - ] ); - } - - return { - title: lang.numberedTitle, - minWidth: 300, - minHeight: 50, - contents: [ - { - id: 'info', - accessKey: 'I', - elements: [ - { - type: 'hbox', - widths: [ '25%', '75%' ], - children: [ - { - label: lang.start, - type: 'text', - id: 'start', - validate: CKEDITOR.dialog.validate.integer( lang.validateStartNumber ), - setup: function( element ) { - // List item start number dominates. - var value = element.getFirst( listItem ).getAttribute( 'value' ) || element.getAttribute( 'start' ) || 1; - value && this.setValue( value ); - }, - commit: function( element ) { - var firstItem = element.getFirst( listItem ); - var oldStart = firstItem.getAttribute( 'value' ) || element.getAttribute( 'start' ) || 1; - - // Force start number on list root. - element.getFirst( listItem ).removeAttribute( 'value' ); - var val = parseInt( this.getValue(), 10 ); - if ( isNaN( val ) ) - element.removeAttribute( 'start' ); - else - element.setAttribute( 'start', val ); - - // Update consequent list item numbering. - var nextItem = firstItem, - conseq = oldStart, - startNumber = isNaN( val ) ? 1 : val; - while ( ( nextItem = nextItem.getNext( listItem ) ) && conseq++ ) { - if ( nextItem.getAttribute( 'value' ) == conseq ) - nextItem.setAttribute( 'value', startNumber + conseq - oldStart ); - } - } - }, - { - type: 'select', - label: lang.type, - id: 'type', - style: 'width: 100%;', - items: listStyleOptions, - setup: function( element ) { - var value = element.getStyle( 'list-style-type' ) || mapListStyle[ element.getAttribute( 'type' ) ] || element.getAttribute( 'type' ) || ''; - - this.setValue( value ); - }, - commit: function( element ) { - var value = this.getValue(); - if ( value ) - element.setStyle( 'list-style-type', value ); - else - element.removeStyle( 'list-style-type' ); - } - } - ] - } - ] - } - ], - onShow: function() { - var editor = this.getParentEditor(), - element = getListElement( editor, 'ol' ); - - element && this.setupContent( element ); - }, - onOk: function() { - var editor = this.getParentEditor(), - element = getListElement( editor, 'ol' ); - - element && this.commitContent( element ); - } - }; - } - } - - CKEDITOR.dialog.add( 'numberedListStyle', function( editor ) { - return listStyle( editor, 'numberedListStyle' ); - }); - - CKEDITOR.dialog.add( 'bulletedListStyle', function( editor ) { - return listStyle( editor, 'bulletedListStyle' ); - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/liststyle/lang/en.js b/addons/website/static/lib/ckeditor/plugins/liststyle/lang/en.js deleted file mode 100644 index 8592adda105..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/liststyle/lang/en.js +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'liststyle', 'en', { - armenian: 'Armenian numbering', - bulletedTitle: 'Bulleted List Properties', - circle: 'Circle', - decimal: 'Decimal (1, 2, 3, etc.)', - decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)', - disc: 'Disc', - georgian: 'Georgian numbering (an, ban, gan, etc.)', - lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)', - lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)', - lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)', - none: 'None', - notset: '<not set>', - numberedTitle: 'Numbered List Properties', - square: 'Square', - start: 'Start', - type: 'Type', - upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)', - upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)', - validateStartNumber: 'List start number must be a whole number.' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/liststyle/plugin.js b/addons/website/static/lib/ckeditor/plugins/liststyle/plugin.js deleted file mode 100644 index 8cc1b9c5bfb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/liststyle/plugin.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.liststyle = { - requires: 'dialog,contextmenu', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - var def, cmd; - - def = new CKEDITOR.dialogCommand( 'numberedListStyle', { - requiredContent: 'ol', - allowedContent: 'ol{list-style-type}[start]' - } ); - cmd = editor.addCommand( 'numberedListStyle', def ); - editor.addFeature( cmd ); - CKEDITOR.dialog.add( 'numberedListStyle', this.path + 'dialogs/liststyle.js' ); - - def = new CKEDITOR.dialogCommand( 'bulletedListStyle', { - requiredContent: 'ul', - allowedContent: 'ul{list-style-type}' - } ); - cmd = editor.addCommand( 'bulletedListStyle', def ); - editor.addFeature( cmd ); - CKEDITOR.dialog.add( 'bulletedListStyle', this.path + 'dialogs/liststyle.js' ); - - //Register map group; - editor.addMenuGroup( "list", 108 ); - - editor.addMenuItems({ - numberedlist: { - label: editor.lang.liststyle.numberedTitle, - group: 'list', - command: 'numberedListStyle' - }, - bulletedlist: { - label: editor.lang.liststyle.bulletedTitle, - group: 'list', - command: 'bulletedListStyle' - } - }); - - editor.contextMenu.addListener( function( element, selection ) { - if ( !element || element.isReadOnly() ) - return null; - - while ( element ) { - var name = element.getName(); - if ( name == 'ol' ) - return { numberedlist: CKEDITOR.TRISTATE_OFF }; - else if ( name == 'ul' ) - return { bulletedlist: CKEDITOR.TRISTATE_OFF }; - - element = element.getParent(); - } - return null; - }); - } - }; - - CKEDITOR.plugins.add( 'liststyle', CKEDITOR.plugins.liststyle ); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/magicline/dev/magicline.html b/addons/website/static/lib/ckeditor/plugins/magicline/dev/magicline.html deleted file mode 100644 index 511730c60c9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/magicline/dev/magicline.html +++ /dev/null @@ -1,594 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license ---> -<html> -<head> - <meta charset="utf-8"> - <title>Magicline muddy trenches – CKEditor Sample</title> - <script src="../../../ckeditor.js"></script> - <link href="../../../samples/sample.css" rel="stylesheet"> - <style> - body { - margin: 0 0 130px; - } - #dev { - border-top: 1px solid #555; - position: fixed; - bottom: 0px; - left: 0px; - right: 0px; - height: 110px; - background: #B5E5EE; - font-size: 15px; - } - #dev .hl { - color: red; - } - #tr_upper, #tr_lower { - padding: 3px 6px; - } - #tr_upper { - background: rgba(255,0,0,.3); - } - #tr_lower { - background: rgba(0,255,0,.3); - } - - #dev p { - margin: 0; - padding: 0; - } - - #timeData, - #triggerData, - #mouseData, - #hiddenData { - position: absolute; - } - #timeData { - right: 10px; - top: 10px; - } - #hiddenData { - right: 10px; - top: 40px; - } - #mouseData { - left: 10px; - top: 10px; - } - #dev h2 { - top: 10px; - left: 10px; - } - #triggerData { - bottom: 10px; - left: 10px; - } - </style> -</head> -<body> - <h1 class="samples"> - CKEditor Sample — magicline muddy trenches - </h1> - - <h2>Various cases</h2> - <textarea cols="80" id="editor1" name="editor1" rows="10"> - <div style="padding: 20px; background: gray; width: 300px" class="1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim.</div> - <div style="background: violet; padding: 30px" class="static">Position static</div> - <dl class="2"> - <dt>Key</dt><dd>Value</dd> - </dl> - <div>Whatever</div> - <hr id="hr"> - <div style=" - display: block; - cursor: pointer; - background: green; - height: 50px; width: 50px;" >aasd - </div> - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <hr> - <hr> - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <table border="1" class="first"> - <tbody><tr> - <td> - Table Cell 1 - </td> - </tr> - <tr> - <td> - Table Cell 2<br> - Table Cell 2<br> - </td> - </tr> - </tbody> - </table> - <div style="border: 1px solid red; padding: 50px"> - Parent - <div style="border: 10px solid green; padding: 10px">Child</div> - </div> - I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. - I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <table border="1" style="margin: 15px 0 100px" class="outer"> - <tbody> - <tr> - <td>Table Cell 1</td> - <td>Table Cell 1</td> - </tr> - <tr> - <td> - <table border="10" class="inner"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - <table border="1" style="margin: 15px" class="third"> - <tbody><tr> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - </tr> - <tr> - <td> - Table Cell 2 - </td> - </tr> - </tbody> - </table> - <table border="1" style="margin: 15px" class="fourth"> - <tbody><tr> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - <td> - Table Cell 1 - </td> - </tr> - <tr> - <td> - Table Cell 2 - </td> - </tr> - </tbody> - </table> - <ul style="" class="fifth"> - <li name="ul_first">List item</li> - <li name="ul_second"> - <ol style=""> - <li name="ol_first">Nested item</li> - <li>Nested item</li> - <li>Nested item</li> - </ol> - </li> - <li>List item</li> - </ul> - <table border="1" class="table#123"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <table border="1" align="right" class="aligned"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <table border="1" style="float: right" class="floated"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <table border="1" align=""class="table#124"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <table border="1"class="table#125"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <p> enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas male</p> - <table border="1"class="table#126"> - <tbody> - <tr> - <td>Table Cell 1</td> - </tr> - <tr> - <td>Table Cell 2<br> Table Cell 2<br></td> - </tr> - </tbody> - </table> - <div style="background: orange; margin: 20px">Upper div</div> - <table style="background: blue; margin: 20px"><tr><td>Lower table</td></tr></table> - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <div><strong>I'm a div. Let me stay here.</strong></div><dl> - <dt>Key</dt> - <dd>pendisse a pellentesque dui, non felis</dd> - <dt>Key</dt> - <dd>pendisse a pellentesque dui, non felis</dd> - </dl> - <div class="11" style="padding: 20px; background: pink; width: 400px"> - Parent - <div class="12" style="padding: 20px; background: orange"> - <!-- comment --> - <!-- another comment --> - <div class="13" style="padding: 20px; background: green"> - Child#2 - </div> - </div> - </div> - </textarea> - - <h2>Odd case: first (last) element at the very beginning, short editable</h2> - <textarea cols="80" id="editor2" name="editor1a" rows="10"> - <table border="1" style="width: 300px"> - <tbody> - <tr> - <td> - Test</td> - </tr> - </tbody> - </table> - </textarea> - - <h2>Large document, put everywhere</h2> - <textarea id="editor3"> - <p><div class="navbar" align="center" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><a accesskey="p" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">previous</a> <a accesskey="n" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/idl-definitions.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">next</a> <a accesskey="c" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/Overview.html#contents" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">contents</a> <a accesskey="i" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/def-index.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">index</a><hr title="Navigation area separator"></div><div class="noprint" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;text-align: right;"><p style="font-family: monospace;font-size: small;">13 November, 2000</p></div><div class="div1" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><a id="Range" name="Range"></a><h1 id="Range-h1" class="div1" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 27px;font-weight: normal; background-color: violet">2. Document Object Model Range</h1><dl style="background: green"><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><i>Editors</i></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Peter Sharpe, SoftQuad Software Inc.</dd><dd style="margin-top: 0px;margin-bottom: 0px;">Vidur Apparao, Netscape Communications Corp.</dd><dd style="margin-top: 0px;margin-bottom: 0px;">Lauren Wood, SoftQuad Software Inc.</dd></dl><div class="noprint"><h2 id="table-of-contents" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">Table of contents</h2><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-introduction" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.1. Introduction</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Definitions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial; background: red">2.2. Definitions and Notation</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.1. Position</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Containment" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.2. Selection and Partial Selection</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Notation" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.3. Notation</a></li></ul></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Creating" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.3. Creating a Range</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Changing" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.4. Changing a Range's Position</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.5. Comparing Range Boundary-Points</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Deleting-Content" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.6. Deleting Content with a Range</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Extracting" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.7. Extracting Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Cloning" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.8. Cloning Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Inserting" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.9. Inserting Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Surrounding" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.10. Surrounding Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Misc" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.11. Miscellaneous Members</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Mutation" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12. Range modification under document mutation</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Insertions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12.1. Insertions</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Deletions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12.2. Deletions</a></li></ul></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Interface" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.13. Formal Description of the Range Interface</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">Range</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-DocumentRange-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DocumentRange</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">RangeException</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeExceptionCode" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">RangeExceptionCode</a></li></ul></li></ul></div><div class="div2"><a id="Level-2-Range-introduction" name="Level-2-Range-introduction"></a><h2 id="Level-2-Range-introduction-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.1. Introduction</h2><p>A Range identifies a range of content in a Document, DocumentFragment or Attr. It is contiguous in the sense that it can be characterized as selecting all of the content between a pair of boundary-points.</p><p><b>Note:</b> In a text editor or a word processor, a user can make a selection by pressing down the mouse at one point in a document, moving the mouse to another point, and releasing the mouse. The resulting selection is contiguous and consists of the content between the two points.</p><p>The term 'selecting' does not mean that every Range corresponds to a selection made by a GUI user;however, such a selection can be returned to a DOM user as a Range.</p><p><b>Note:</b> In bidirectional writing (Arabic, Hebrew), a range may correspond to a logical selection that is not necessarily contiguous when displayed. A visually contiguous selection, also used in some cases, may not correspond to a single logical selection, and may therefore have to be represented by more than one range.</p><p>The Range interface provides methods for accessing and manipulating the document tree at a higher level than similar methods in the Node interface. The expectation is that each of the methods provided by the Range interface for the insertion, deletion and copying of content can be directly mapped to a series of Node editing operations enabled by DOM Core. In this sense, the Range operations can be viewed as convenience methods that also enable the implementation to optimize common editing patterns.</p><p>This chapter describes the Range interface, including methods for creating and moving a Range and methods for manipulating content with Ranges.</p><p>The interfaces found within this section are not mandatory. A DOM application may use the <code>hasFeature(feature, version)</code> method of the <code>DOMImplementation</code> interface with parameter values "Range" and "2.0" (respectively) to determine whether or not this module is supported by the implementation. In order to fully support this module, an implementation must also support the "Core" feature defined defined in the DOM Level 2 Core specification [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>]. Please refer to additional information about <a href="http://www.w3.org/TR/DOM-Level-2-Core/introduction.html#ID-Conformance" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>conformance</em></a> in the DOM Level 2 Core specification [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>].</p></div><div class="div2" style="background: blue;"><a id="Level-2-Range-Definitions" name="Level-2-Range-Definitions"></a><h2 id="Level-2-Range-Definitions-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal; background: red">2.2. Definitions and Notation</h2><div style="background: yellow" class="div3"><a id="Level-2-Range-Position" name="Level-2-Range-Position"></a><h3 id="Level-2-Range-Position-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.1. Position</h3><p>This chapter refers to two different representations of a document: the text or source form that includes the document markup and the tree representation similar to the one described in the introduction section of the DOM Level 2 Core [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>].</p><p>A Range consists of two <i>boundary-points</i> corresponding to the start and the end of the Range. <a id="td-boundarypoint" name="td-boundarypoint"></a>A boundary-point's position in a Document or DocumentFragment tree can be characterized by a node and an offset. <a id="td-container" name="td-container"></a>The node is called the <i>container</i> of the boundary-point and of its position. <a id="td-ancestor-container" name="td-ancestor-container"></a>The container and its ancestors are the <i>ancestor container</i>s of the boundary-point and of its position.<a id="td-offset" name="td-offset"></a>The offset within the node is called the <i>offset</i> of the boundary-point and its position. If the container is an Attr, Document, DocumentFragment, Element or EntityReference node, the offset is between its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-child" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>child</em></a> nodes. If the container is a CharacterData, Comment or ProcessingInstruction node, the offset is between the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> of the UTF-16 encoded string contained by it.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of a Range must have a common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> which is either a Document, DocumentFragment or Attr node. That is, the content of a Range must be entirely within the subtree rooted by a single Document, DocumentFragment or Attr Node. <a id="td-root-container" name="td-root-container"></a>This common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> is known as the <i>root container</i> of the Range. <a id="td-context-tree" name="td-context-tree"></a>The tree rooted by the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a> is known as the Range's <i>context tree</i>.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range must be an Element, Comment, ProcessingInstruction, EntityReference, CDATASection, Document, DocumentFragment, Attr, or Text node. None of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a>s of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range can be a DocumentType, Entity or Notation node.</p><p>In terms of the text representation of a document, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of a Range can only be on token boundaries. That is, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the text range cannot be in the middle of a start- or end-tag of an element or within the name of an entity or character reference. A Range locates a contiguous portion of the content of the structure model.</p><p>The relationship between locations in a text representation of the document and in the Node tree interface of the DOM is illustrated in the following diagram:<br></p><div align="center"><hr width="90%" size="2"><img src="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/images/RangeExample.gif" alt="Range Example"><hr width="90%" size="2"><b>Range Example</b><hr width="90%" size="2"></div><p>In this diagram, four different Ranges are illustrated. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of each Range are labelled with <i>s#</i> (the start of the Range) and <i>e#</i> (the end of the Range), where # is the number of the Range. For Range 2, the start is in the BODY element and is immediately after the H1 element and immediately before the P element, so its position is between the H1 and P children of BODY. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> whose <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is not a CharacterData node is 0 if it is before the first child, 1 if between the first and second child, and so on. So, for the start of the Range 2, the<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is BODY and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is 1. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> whose <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is a CharacterData node is obtained similarly but using <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a> positions instead. For example, the<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> labelled s1 of the Range 1 has a Text node (the one containing "Title") as its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of 2 since it is between the second and third <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a>.</p><p>Notice that the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of Ranges 3 and 4 correspond to the same location in the text representation. An important feature of the Range is that a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range can unambiguously represent every position within the document tree.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a>s of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s can be obtained through the following read-only Range attributes:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute Node startContainer;readonly attribute long startOffset;readonly attribute Node endContainer;readonly attribute long endOffset;</pre></div><p><a id="td-collapsed" name="td-collapsed"></a>If the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of a Range have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a>s, the Range is said to be a <i>collapsed</i> Range. (This is often referred to as an insertion point in a user agent.)</p></div><div class="div3"><a id="Level-2-Range-Containment" name="Level-2-Range-Containment"></a><h3 id="Level-2-Range-Containment-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.2. Selection and Partial Selection</h3><p><a id="td-selected" name="td-selected"></a>A node or <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a> unit is said to be <i>selected</i> by a Range if it is between the two <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of the Range, that is, if the position immediately before the node or 16-bit unit is before the end of the Range and the position immediately after the node or 16-bit unit is after the start of the range. For example, in terms of a text representation of the document, an element would be <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selected</em></a>by a Range if its corresponding start-tag was located after the start of the Range and its end-tag was located before the end of the Range. In the examples in the above diagram, the Range 2<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selects</em></a> the P node and the Range 3 <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selects</em></a> the text node containing the text "Blah xyz."</p><p><a id="td-partially-selected" name="td-partially-selected"></a>A node is said to be <i>partially selected</i> by a Range if it is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of exactly one <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range. For example, consider Range 1 in the above diagram. The element H1 is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by that Range since the start of the Range is within one of its children.</p></div><div class="div3"><a id="Level-2-Range-Notation" name="Level-2-Range-Notation"></a><h3 id="Level-2-Range-Notation-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.3. Notation</h3><p>Many of the examples in this chapter are illustrated using a text representation of a document. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of a Range are indicated by displaying the characters (be they markup or data characters) between the two <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s in bold, as in</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>BC<BAR>DE</b>F</BAR></FOO></pre></div><p>When both <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s are at the same position, they are indicated with a bold caret ('<b>^</b>'), as in</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>^</b>BC<BAR>DEF</BAR></FOO></pre></div></div></div><div class="div2"><a id="Level-2-Range-Creating" name="Level-2-Range-Creating"></a><h2 id="Level-2-Range-Creating-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.3. Creating a Range</h2><p>A Range is created by calling the <code>createRange()</code> method on the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-DocumentRange-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>DocumentRange</code></a> interface. This interface can be obtained from the object implementing the <code>Document</code> interface using binding-specific casting methods.</p><div class="eg"><pre style="margin-left: 2em;"> interface DocumentRange{Range createRange();}</pre></div><p>The initial state of the Range returned from this method is such that both of its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s are positioned at the beginning of the corresponding Document, before any content. In other words, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of each <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> is the Document node and the offset within that node is 0.</p><p>Like some objects created using methods in the Document interface (such as Nodes and DocumentFragments), Ranges created via a particular document instance can select only content associated with that Document, or with DocumentFragments and Attrs for which that Document is the <code>ownerDocument</code>. Such Ranges, then, can not be used with other Document instances.</p></div><div class="div2"><a id="Level-2-Range-Changing" name="Level-2-Range-Changing"></a><h2 id="Level-2-Range-Changing-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.4. Changing a Range's Position</h2><p>A Range's position can be specified by setting the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of each boundary-point with the <code>setStart</code> and <code>setEnd</code> methods.</p><div class="eg"><pre style="margin-left: 2em;"> void setStart(in Node parent, in long offset) raises(RangeException);void setEnd(in Node parent, in long offset) raises(RangeException);</pre></div><p>If one boundary-point of a Range is set to have a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a> other than the current one for the Range, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to the new position. This enforces the restriction that both boundary-points of a Range must have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a>.</p><p>The start position of a Range is guaranteed to never be after the end position. To enforce this restriction, if the start is set to be at a position after the end, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to that position. Similarly, if the end is set to be at a position before the start, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to that position.</p><p>It is also possible to set a Range's position relative to nodes in the tree:</p><div class="eg"><pre style="margin-left: 2em;"> void setStartBefore(in Node node);raises(RangeException);void setStartAfter(in Node node);raises(RangeException);void setEndBefore(in Node node);raises(RangeException);void setEndAfter(in Node node);raises(RangeException);</pre></div><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-parent" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>parent</em></a> of the node becomes the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> and the Range is subject to the same restrictions as given above in the description of <code>setStart()</code>and <code>setEnd()</code>.</p><p>A Range can be <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to either boundary-point:</p><div class="eg"><pre style="margin-left: 2em;"> void collapse(in boolean toStart);</pre></div><p>Passing <code>TRUE</code> as the parameter <code>toStart</code> will <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapse</em></a> the Range to its start, <code>FALSE</code> to its end.</p><p>Testing whether a Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> can be done by examining the <code>collapsed</code> attribute:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute boolean collapsed;</pre></div><p>The following methods can be used to make a Range select the contents of a node or the node itself.</p><div class="eg"><pre style="margin-left: 2em;"> void selectNode(in Node n);void selectNodeContents(in Node n);</pre></div><p>The following examples demonstrate the operation of the methods <code>selectNode</code> and <code>selectNodeContents</code>:</p><div class="eg"><pre style="margin-left: 2em;">Before: <b>^</b><BAR><FOO>A<MOO>B</MOO>C</FOO></BAR>After Range.selectNodeContents(FOO): <BAR><FOO><b>A<MOO>B</MOO>C</b></FOO></BAR>(In this case, FOO is the parent of both boundary-points)After Range.selectNode(FOO):<BAR><b><FOO>A<MOO>B</MOO>C</FOO></b></BAR></pre></div></div><div class="div2"><a id="Level-2-Range-Comparing" name="Level-2-Range-Comparing"></a><h2 id="Level-2-Range-Comparing-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.5. Comparing Range Boundary-Points</h2><p>It is possible to compare two Ranges by comparing their boundary-points:</p><div class="eg"><pre style="margin-left: 2em;"> short compareBoundaryPoints(in CompareHow how, in Range sourceRange) raises(RangeException);</pre></div><p>where <code>CompareHow</code> is one of four values: <code>START_TO_START</code>, <code>START_TO_END</code>, <code>END_TO_END</code> and <code>END_TO_START</code>. The return value is -1, 0 or 1 depending on whether the corresponding boundary-point of the Range is before, equal to, or after the corresponding boundary-point of <code>sourceRange</code>. An exception is thrown if the two Ranges have different <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a>s.</p><p>The result of comparing two boundary-points (or positions) is specified below. An informal but not always correct specification is that an boundary-point is before, equal to, or after another if it corresponds to a location in a text representation before, equal to, or after the other's corresponding location.</p><p><a id="td-comparison" name="td-comparison"></a>Let A and B be two boundary-points or positions. Then one of the following holds: A is <i>before</i> B, A is <i>equal to</i> B, or A is <i>after</i> B. Which one holds is specified in the following by examining four cases:</p><p>In the first case the boundary-points have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>. A is <i>before</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B, A is <i>equal to</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is equal to the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B, and A is <i>after</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is greater than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B.</p><p>In the second case a child node C of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of A is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of B. In this case, A is <i>before</i> B if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of A is less than or equal to the index of the child node C and A is <i>after</i>B otherwise.</p><p>In the third case a child node C of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of B is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of A. In this case, A is <i>before</i> B if the index of the child node C is less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B and A is <i>after</i> B otherwise.</p><p>In the fourth case, none of three other cases hold: the containers of A and B are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-sibling" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>siblings</em></a> or <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-descendant" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>descendants</em></a> of sibling nodes. In this case, A is <i>before</i> B if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of A is before the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of B in a pre-order traversal of the Ranges' <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> and A is <i>after</i> B otherwise.</p><p>Note that because the same location in a text representation of the document can correspond to two different positions in the DOM tree, it is possible for two boundary-points to not compare equal even though they would be equal in the text representation. For this reason, the informal definition above can sometimes be incorrect.</p></div><div class="div2"><a id="Level-2-Range-Deleting-Content" name="Level-2-Range-Deleting-Content"></a><h2 id="Level-2-Range-Deleting-Content-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.6. Deleting Content with a Range</h2><p>One can delete the contents selected by a Range with:</p><div class="eg"><pre style="margin-left: 2em;"> void deleteContents();</pre></div><p><code>deleteContents()</code> deletes all nodes and characters selected by the Range. All other nodes and characters remain in the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> of the Range. Some examples of this deletion operation are:</p><div class="eg"><pre style="margin-left: 2em;">(1) <FOO>A<b>B<MOO>CD</MOO></b>CD</FOO>--><FOO>A<b>^</b>CD</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(2) <FOO>A<MOO>B<b>C</MOO>D</b>E</FOO>--><FOO>A<MOO>B</MOO><b>^</b>E</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(3) <FOO>X<b>Y<BAR>Z</b>W</BAR>Q</FOO>--><FOO>X<b>^</b><BAR>W</BAR>Q</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(4) <FOO><BAR1>A<b>B</BAR1><BAR2/><BAR3>C</b>D</BAR3></FOO>--><FOO><BAR1>A</BAR1><b>^</b><BAR3>D</BAR3></pre></div><p>After <code>deleteContents()</code> is invoked on a Range, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a>. If no node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range, then it is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to its original start point, as in example (1). If a node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range and was an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the start of the Range and no <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-ancestor" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor</em></a> of the node satisfies these two conditions, then the Range is collapsed to the position immediately after the node, as in examples (2) and (4). If a node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range and was an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the end of the Range and no ancestor of the node satisfies these two conditions, then the Range is collapsed to the position immediately before the node, as in examples (3) and (4).</p><p>Note that if deletion of a Range leaves adjacent Text nodes, they are not automatically merged, and empty Text nodes are not automatically removed. Two Text nodes should be joined only if each is the container of one of the boundary-points of a Range whose contents are deleted. To merge adjacent Text nodes, or remove empty text nodes, the <code>normalize()</code> method on the <code>Node</code>interface should be used.</p></div><div class="div2"><a id="Level-2-Range-Extracting" name="Level-2-Range-Extracting"></a><h2 id="Level-2-Range-Extracting-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.7. Extracting Content</h2><p>If the contents of a Range need to be extracted rather than deleted, the following method may be used:</p><div class="eg"><pre style="margin-left: 2em;"> DocumentFragment extractContents();</pre></div><p>The <code>extractContents()</code> method removes nodes from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> similarly to the <code>deleteContents()</code> method. In addition, it places the deleted contents in a new <code>DocumentFragment</code>. The following examples illustrate the contents of the returned DocumentFragment:</p><div class="eg"><pre style="margin-left: 2em;">(1) <FOO>A<b>B<MOO>CD</MOO></b>CD</FOO>-->B<MOO>CD</MOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(2) <FOO>A<MOO>B<b>C</MOO>D</b>E</FOO>--><MOO>C<MOO>D</pre></div><div class="eg"><pre style="margin-left: 2em;">(3) <FOO>X<b>Y<BAR>Z</b>W</BAR>Q</FOO>-->Y<BAR>Z</BAR></pre></div><div class="eg"><pre style="margin-left: 2em;">(4)<FOO><BAR1>A<b>B</BAR1><BAR2/><BAR3>C</b>D</BAR3></FOO>--><BAR1>B</BAR1><BAR2/><BAR3>C</BAR3></pre></div><p>It is important to note that nodes that are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range are cloned. Since part of such a node's contents must remain in the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> and part of the contents must be moved to the new DocumentFragment, a clone of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> node is included in the new DocumentFragment. Note that cloning does not take place for <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selected</em></a> elements;these nodes are moved to the new DocumentFragment.</p></div><div class="div2"><a id="Level-2-Range-Cloning" name="Level-2-Range-Cloning"></a><h2 id="Level-2-Range-Cloning-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.8. Cloning Content</h2><p>The contents of a Range may be duplicated using the following method:</p><div class="eg"><pre style="margin-left: 2em;"> DocumentFragment cloneContents();</pre></div><p>This method returns a <code>DocumentFragment</code> that is similar to the one returned by the method <code>extractContents()</code>. However, in this case, the original nodes and character data in the Range are not removed from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a>. Instead, all of the nodes and text content within the returned <code>DocumentFragment</code> are cloned.</p></div><div class="div2"><a id="Level-2-Range-Inserting" name="Level-2-Range-Inserting"></a><h2 id="Level-2-Range-Inserting-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.9. Inserting Content</h2><p>A node may be inserted into a Range using the following method:</p><div class="eg"><pre style="margin-left: 2em;"> void insertNode(in Node n) raises(RangeException);</pre></div><p>The <code>insertNode()</code> method inserts the specified node into the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a>. The node is inserted at the start <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range, without modifying it.</p><p>If the start boundary point of the Range is in a <code>Text</code> node, the <code>insertNode</code> operation splits the <code>Text</code> node at the boundary point. If the node to be inserted is also a <code>Text</code> node, the resulting adjacent<code>Text</code> nodes are not normalized automatically;this operation is left to the application.</p><p>The Node passed into this method can be a <code>DocumentFragment</code>. In that case, the contents of the <code>DocumentFragment</code> are inserted at the start <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range, but the <code>DocumentFragment</code>itself is not. Note that if the Node represents the root of a sub-tree, the entire sub-tree is inserted.</p><p>The same rules that apply to the <code>insertBefore()</code> method on the Node interface apply here. Specifically, the Node passed in, if it already has a parent, will be removed from its existing position.</p></div><div class="div2"><a id="Level-2-Range-Surrounding" name="Level-2-Range-Surrounding"></a><h2 id="Level-2-Range-Surrounding-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.10. Surrounding Content</h2><p>The insertion of a single node to subsume the content selected by a Range can be performed with:</p><div class="eg"><pre style="margin-left: 2em;"> void surroundContents(in Node newParent);</pre></div><p>The <code>surroundContents()</code> method causes all of the content selected by the Range to be rooted by the specified node. The nodes may not be Attr, Entity, DocumentType, Notation, Document, or DocumentFragment nodes. Calling <code>surroundContents()</code> with the Element node FOO in the following examples yields:</p><div class="eg"><pre style="margin-left: 2em;"> Before: <BAR>A<b>B<MOO>C</MOO>D</b>E</BAR>After surroundContents(FOO):<BAR>A<b><FOO>B<MOO>C</MOO>D</FOO></b>E</BAR></pre></div><p>Another way of describing the effect of this method on the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> is to decompose it in terms of other operations:</p><ol><li>Remove the contents selected by the Range with a call to <code>extractContents()</code>.</li><li>Insert the node <code>newParent</code> where the Range is collapsed (after the extraction) with <code>insertNode().</code></li><li>Insert the entire contents of the extracted DocumentFragment into <code>newParent</code>. Specifically, invoke the <code>appendChild()</code> on <code>newParent</code> passing in the DocumentFragment returned as a result of the call to <code>extractContents()</code></li><li>Select <code>newParent</code> and all of its contents with <code>selectNode()</code>.</li></ol><p>The <code>surroundContents()</code> method raises an exception if the Range <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selects</em></a> a non-Text node. An example of a Range for which <code>surroundContents()</code>raises an exception is:</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>B<BAR>C</b>D</BAR>E</FOO></pre></div><p>If the node <code>newParent</code> has any children, those children are removed before its insertion. Also, if the node <code>newParent</code> already has a parent, it is removed from the original parent's <code>childNodes</code> list.</p></div><div class="div2"><a id="Level-2-Range-Misc" name="Level-2-Range-Misc"></a><h2 id="Level-2-Range-Misc-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.11. Miscellaneous Members</h2><p>One can clone a Range:</p><div class="eg"><pre style="margin-left: 2em;"> Range cloneRange();</pre></div><p>This creates a new Range which selects exactly the same content as that selected by the Range on which the method <code>cloneRange</code> was invoked. No content is affected by this operation.</p><p>Because the boundary-points of a Range do not necessarily have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s, use:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute Node commonAncestorContainer;</pre></div><p>to get the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of both boundary-points that is furthest down from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a></p><p>One can get a copy of all the character data selected or partially selected by a Range with:</p><div class="eg"><pre style="margin-left: 2em;"> DOMString toString();</pre></div><p>This does nothing more than simply concatenate all the character data selected by the Range. This includes character data in both <code>Text</code> and <code>CDATASection</code> nodes.</p></div><div class="div2"><a id="Level-2-Range-Mutation" name="Level-2-Range-Mutation"></a><h2 id="Level-2-Range-Mutation-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.12. Range modification under document mutation</h2><p>As a document is modified, the Ranges within the document need to be updated. For example, if one boundary-point of a Range is within a node and that node is removed from the document, then the Range would be invalid unless it is fixed up in some way. This section describes how Ranges are modified under document mutations so that they remain valid.</p><p>There are two general principles which apply to Ranges under document mutation: The first is that all Ranges in a document will remain valid after any mutation operation and the second is that, as much as possible, all Ranges will select the same portion of the document after any mutation operation.</p><p>Any mutation of the document tree which affect Ranges can be considered to be a combination of basic deletion and insertion operations. In fact, it can be convenient to think of those operations as being accomplished using the <code>deleteContents()</code> and <code>insertNode()</code> Range methods and, in the case of Text mutations, the <code>splitText()</code> and <code>normalize()</code> methods.</p><div class="div3"><a id="Level-2-Range-Insertions" name="Level-2-Range-Insertions"></a><h3 id="Level-2-Range-Insertions-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.12.1. Insertions</h3><p>An insertion occurs at a single point, the insertion point, in the document. For any Range in the document tree, consider each boundary-point. The only case in which the boundary-point will be changed after the insertion is when the boundary-point and the insertion point have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the insertion point is strictly less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the Range's boundary-point. In that case the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the Range's boundary-point will be increased so that it is between the same nodes or characters as it was before the insertion.</p><p>Note that when content is inserted at a boundary-point, it is ambiguous as to where the boundary-point should be repositioned if its relative position is to be maintained. There are two possibilities: at the start or at the end of the newly inserted content. We have chosen that in this case neither the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> nor <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the boundary-point is changed. As a result, the boundary-point will be positioned at the start of the newly inserted content.</p><p><em>Examples:</em></p><p>Suppose the Range selects the following:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd efgh X<b>Y blah i</b>jkl</P></pre></div><p>Consider the insertion of the text "<i>inserted text</i>" at the following positions:</p><div class="eg"><pre style="margin-left: 2em;">1. Before the 'X':<P>Abcd efgh <i>inserted text</i>X<b>Y blah i</b>jkl</P>2. After the 'X':<P>Abcd efgh X<b><i>inserted text</i>Y blah i</b>jkl</P>3. After the 'Y':<P>Abcd efgh X<b>Y<i>inserted text</i> blah i</b>jkl</P>4. After the 'h' in "Y blah":<P>Abcd efgh X<b>Y blah<i>inserted text</i> i</b>jkl</P></pre></div></div><div class="div3"><a id="Level-2-Range-Deletions" name="Level-2-Range-Deletions"></a><h3 id="Level-2-Range-Deletions-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.12.2. Deletions</h3><p>Any deletion from the document tree can be considered as a sequence of <code>deleteContents()</code> operations applied to a minimal set of disjoint Ranges. To specify how a Range is modified under deletions we need only consider what happens to a Range under a single <code>deleteContents()</code>operation of another Range. And, in fact, we need only consider what happens to a single boundary-point of the Range since both boundary-points are modified using the same algorithm.</p><p>If a boundary-point of the original Range is within the content being deleted, then after the deletion it will be at the same position as the resulting boundary-point of the (now <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a>) Range used to delete the contents.</p><p>If a boundary-point is after the content being deleted then it is not affected by the deletion unless its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is also the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of one of the boundary-points of the Range being deleted. If there is such a common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>, then the index of the boundary-point is modified so that the boundary-point maintains its position relative to the content of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>.</p><p>If a boundary-point is before the content being deleted then it is not affected by the deletion at all.</p><p><em>Examples:</em></p><p>In these examples, the Range on which <code>deleteContents()</code>is invoked is indicated by the underline.</p><p><em>Example 1.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u>efgh T</u><b><u>he</u> Range i</b>jkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>Range i</b>jkl</P></pre></div><p><em>Example 2.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><p>Abcd <u>efgh T<b>he Range i</b>j</u>kl</p></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><p>Abcd <b>^</b>kl</p></pre></div><p><em>Example 3.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>ABCD <u>efgh T</u><b><u>he <EM>R</u>ange</b></EM>ijkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>ABCD <EM><b>ange</b></EM>ijkl</P></pre></div><p>In this example, the container of the start boundary-point after the deletion is the Text node holding the string "ange".</p><p><em>Example 4.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u>efgh T</u><b>he Range i</b>jkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>he Range i</b>jkl</P></pre></div><p><em>Example 5.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u><EM>efgh T<b>he Range i</b>j</EM></u>kl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>^</b>kl</P></pre></div></div></div><div class="div2"><a id="Level-2-Range-Interface" name="Level-2-Range-Interface"></a><h2 id="Level-2-Range-Interface-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.13. Formal Description of the Range Interface</h2><p>To summarize, the complete, formal description of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a> interface is given below:</p><dl ><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Interface <i><a id="Level-2-Range-idl" name="Level-2-Range-idl">Range</a></i></b> (introduced in <b class="since">DOM Level 2</b>)</dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:interface Range{readonly attribute Node startContainer;// raises(DOMException) on retrieval readonly attribute long startOffset;// raises(DOMException) on retrieval readonly attribute Node endContainer;// raises(DOMException) on retrieval readonly attribute long endOffset;// raises(DOMException) on retrieval readonly attribute boolean collapsed;// raises(DOMException) on retrieval readonly attribute Node commonAncestorContainer;// raises(DOMException) on retrieval void setStart(in Node refNode, in long offset) raises(RangeException, DOMException);void setEnd(in Node refNode, in long offset) raises(RangeException, DOMException);void setStartBefore(in Node refNode) raises(RangeException, DOMException);void setStartAfter(in Node refNode) raises(RangeException, DOMException);void setEndBefore(in Node refNode) raises(RangeException, DOMException);void setEndAfter(in Node refNode) raises(RangeException, DOMException);void collapse(in boolean toStart) raises(DOMException);void selectNode(in Node refNode) raises(RangeException, DOMException);void selectNodeContents(in Node refNode) raises(RangeException, DOMException);// CompareHow const unsigned short START_TO_START=0;const unsigned short START_TO_END=1;const unsigned short END_TO_END=2;const unsigned short END_TO_START=3;short compareBoundaryPoints(in unsigned short how, in Range sourceRange) raises(DOMException);void deleteContents() raises(DOMException);DocumentFragment extractContents() raises(DOMException);DocumentFragment cloneContents() raises(DOMException);void insertNode(in Node newNode) raises(DOMException, RangeException);void surroundContents(in Node newParent) raises(DOMException, RangeException);Range cloneRange() raises(DOMException);DOMString toString() raises(DOMException);void detach() raises(DOMException);};</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Definition group <i><a id="Level2-Range-compareHow" name="Level2-Range-compareHow">CompareHow</a></i></b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>Passed as a parameter to the <code>compareBoundaryPoints</code> method.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Defined Constants</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">END_TO_END</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare end boundary-point of <code>sourceRange</code> to end boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">END_TO_START</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare end boundary-point of <code>sourceRange</code> to start boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">START_TO_END</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare start boundary-point of <code>sourceRange</code> to end boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">START_TO_START</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare start boundary-point of <code>sourceRange</code> to start boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Attributes</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-collapsed" name="Level-2-Range-attr-collapsed">collapsed</a></code> of type <code>boolean</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">TRUE if the Range is collapsed<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-commonParent" name="Level-2-Range-attr-commonParent">commonAncestorContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-deepest" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>deepest</em></a> common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the Range's two boundary-points.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-endParent" name="Level-2-Range-attr-endParent">endContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node within which the Range ends<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-endOffset" name="Level-2-Range-attr-endOffset">endOffset</a></code> of type <code>long</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Offset within the ending node of the Range.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-startParent" name="Level-2-Range-attr-startParent">startContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node within which the Range begins<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-startOffset" name="Level-2-Range-attr-startOffset">startOffset</a></code> of type <code>long</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Offset within the starting node of the Range.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Methods</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-cloneContents" name="Level2-Range-method-cloneContents">cloneContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Duplicates the contents of a Range<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DocumentFragment</code></p></td><td><p>A DocumentFragment that contains content equivalent to this Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-clone" name="Level2-Range-method-clone">cloneRange</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Produces a new Range whose boundary-points are equal to the boundary-points of the Range.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></p></td><td><p>The duplicated Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-collapse" name="Level2-Range-method-collapse">collapse</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Collapse a Range onto one of its boundary-points<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">toStart</code> of type <code>boolean</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If TRUE, collapses the Range onto its start;if FALSE, collapses it onto its end.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-compareBoundaryPoints" name="Level2-Range-method-compareBoundaryPoints">compareBoundaryPoints</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Compare the boundary-points of two Ranges in a document.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">how</code> of type <code>unsigned short</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">A code representing the type of comparison, as defined above.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">sourceRange</code> of type <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>Range</code> on which this current <code>Range</code> is compared to.<br></dd></dl></div></div><div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>short</code></p></td><td><p>-1, 0 or 1 depending on whether the corresponding boundary-point of the Range is respectively before, equal to, or after the corresponding boundary-point of<code>sourceRange</code>.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same Document or DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-deleteContents" name="Level2-Range-method-deleteContents">deleteContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Removes the contents of a Range from the containing document or document fragment without returning a reference to the removed content.<div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes that contain any of the content of the Range are read-only.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-detach" name="Level2-Range-method-detach">detach</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Called to indicate that the Range is no longer in use and that the implementation may relinquish any resources associated with this Range. Subsequent calls to any methods or attribute getters on this Range will result in a <code>DOMException</code> being thrown with an error code of <code>INVALID_STATE_ERR</code>.<div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-extractContents" name="Level2-Range-method-extractContents">extractContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Moves the contents of a Range from the containing document or document fragment to a new DocumentFragment.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DocumentFragment</code></p></td><td><p>A DocumentFragment containing the extracted contents.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes which contain any of the content of the Range are read-only.</p><p>HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-insertNode" name="Level2-Range-method-insertNode">insertNode</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Inserts a node into the Document or DocumentFragment at the start of the Range. If the container is a Text node, this will be split at the start of the Range (as if the Text node's splitText method was performed at the insertion point) and the insertion will occur between the two resulting Text nodes. Adjacent Text nodes will not be automatically merged. If the node to be inserted is a DocumentFragment node, the children will be inserted rather than the DocumentFragment node itself.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">newNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to insert at the start of the Range<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the start of the Range is read-only.</p><p>WRONG_DOCUMENT_ERR: Raised if <code>newNode</code> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range were not created from the same document.</p><p>HIERARCHY_REQUEST_ERR: Raised if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range is of a type that does not allow children of the type of <code>newNode</code> or if <code>newNode</code>is an ancestor of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>newNode</code> is an Attr, Entity, Notation, or Document node.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-selectNode" name="Level2-Range-method-selectNode">selectNode</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Select a node and its contents<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to select.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code> is an Entity, Notation or DocumentType node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-selectNodeContents" name="Level2-Range-method-selectNodeContents">selectNodeContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Select the contents within a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node to select from<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEnd" name="Level2-Range-method-setEnd">setEnd</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the attributes describing the end of a Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>refNode</code> value. This parameter must be different from <code>null</code>.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">offset</code> of type <code>long</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>endOffset</code> value.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation, or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater than the number of child units in <code>refNode</code>. Child units are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> if <code>refNode</code> is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction node. Child units are Nodes in all other cases.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEndAfter" name="Level2-Range-method-setEndAfter">setEndAfter</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the end of a Range to be after a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range ends after <code>refNode</code>.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEndBefore" name="Level2-Range-method-setEndBefore">setEndBefore</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the end position to be before a node.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range ends before <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setStart" name="Level2-Range-method-setStart">setStart</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the attributes describing the start of the Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>refNode</code> value. This parameter must be different from <code>null</code>.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">offset</code> of type <code>long</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>startOffset</code> value.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation, or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater than the number of child units in <code>refNode</code>. Child units are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> if <code>refNode</code> is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction node. Child units are Nodes in all other cases.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setStartAfter" name="Level2-Range-method-setStartAfter">setStartAfter</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the start position to be after a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range starts after <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-setStartBefore" name="Level2-Range-setStartBefore">setStartBefore</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the start position to be before a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range starts before <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-surroundContents" name="Level2-Range-method-surroundContents">surroundContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Reparents the contents of the Range to the given node and inserts the node at the position of the start of the Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">newParent</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to surround the contents with.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of either boundary-point of the Range is read-only.</p><p>WRONG_DOCUMENT_ERR: Raised if <code>newParent</code> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range were not created from the same document.</p><p>HIERARCHY_REQUEST_ERR: Raised if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range is of a type that does not allow children of the type of <code>newParent</code> or if<code>newParent</code> is an ancestor of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> or if <code>node</code> would end up with a child node of a type not allowed by the type of <code>node</code>.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>BAD_BOUNDARYPOINTS_ERR: Raised if the Range <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selects</em></a> a non-text node.</p><p>INVALID_NODE_TYPE_ERR: Raised if <code>node</code> is an Attr, Entity, DocumentType, Notation, Document, or DocumentFragment node.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-toString" name="Level2-Range-method-toString">toString</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Returns the contents of a Range as a string. This string contains only the data characters, not any markup.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMString</code></p></td><td><p>The contents of the Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Interface <i><a id="Level-2-DocumentRange-idl" name="Level-2-DocumentRange-idl">DocumentRange</a></i></b> (introduced in <b class="since">DOM Level 2</b>)</dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:interface DocumentRange{Range createRange();};</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Methods</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-DocumentRange-method-createRange" name="Level2-DocumentRange-method-createRange">createRange</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">This interface can be obtained from the object implementing the <code>Document</code> interface using binding-specific casting methods.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></p></td><td><p>The initial state of the Range returned from this method is such that both of its boundary-points are positioned at the beginning of the corresponding Document, before any content. The Range returned can only be used to select content associated with this Document, or with DocumentFragments and Attrs for which this Document is the <code>ownerDocument</code>.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Exceptions</b></div></div></dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Exception <i><a id="RangeException" name="RangeException">RangeException</a></i></b> introduced in <b class="version">DOM Level 2</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>Range operations may throw a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a> as specified in their method descriptions.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:exception RangeException{unsigned short code;};// RangeExceptionCodeconst unsigned short BAD_BOUNDARYPOINTS_ERR=1;const unsigned short INVALID_NODE_TYPE_ERR=2;</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Definition group <i><a id="RangeExceptionCode" name="RangeExceptionCode">RangeExceptionCode</a></i></b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>An integer indicating the type of error generated.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Defined Constants</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">BAD_BOUNDARYPOINTS_ERR</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If the boundary-points of a Range do not meet specific requirements.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">INVALID_NODE_TYPE_ERR</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of an boundary-point of a Range is being set to either a node of an invalid type or a node with an ancestor of an invalid type.</dd></dl></dd></dl></dd></dl></dd></dl></div></div><div class="navbar" align="center" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><hr title="Navigation area separator"><a accesskey="p" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">previous</a> <a accesskey="n" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/idl-definitions.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">next</a> <a accesskey="c" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/Overview.html#contents" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">contents</a> <a accesskey="i" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/def-index.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">index</a></div></p><dl></dl> - </textarea> - - <h2>Deeply nested divs</h2> - <textarea name="editor4"> - <p> </p><h1 id="mainHeader" style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-weight: normal; font-size: 26px; color: rgb(7, 130, 193); font-family: Arial, Helvetica, sans-serif; background-color: rgb(226, 226, 226); ">Jobs</h1><div id="node-438" class="node node-type-page" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 18px; color: rgb(85, 85, 85); font-family: Arial, Helvetica, sans-serif; background-color: rgb(226, 226, 226); "><div class="node-inner" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><div class="meta" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "> </div><div class="content" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><div class="contentBox" style="margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; padding-top: 15px; padding-right: 15px; padding-bottom: 1px; padding-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; background-color: rgb(239, 239, 239); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(226, 226, 226); border-right-color: rgb(226, 226, 226); border-bottom-color: rgb(226, 226, 226); border-left-color: rgb(226, 226, 226); position: relative; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">CKSource is a successful company with thousands of customers all around the world, including top names like IBM and Oracle. Our company is growing fast, with impressive sales results. This strong growth expands our range of opportunities, followed by the growth of our team. Take this chance and <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">join us!</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Working in a <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">successful Open Source project </strong>is certainly a lot of fun. CKEditor is one of the most frequently used text editors out there, and this success means new responsibilities. We are providing a key component for the software that is powering the Web today. It is downloaded daily by thousands of people all around the world and used by hundreds of thousands out there.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are constantly looking for top-notch, creative, and enthusiastic professionals ready to join our international team.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We offer a work culture where ideas are free to fly and diversity is our everyday life.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">There is no need to relocate. No matter where you are, as long as you love what you do, you are the right person for us!</p><div class="post joboffer" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 5px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); " id=""><h2 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-size: 15px; color: rgb(0, 0, 0); ">AJD - Advanced JavaScript Developer</h2><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Location: <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Europe and Its Neighbourhood</strong> (from GMT 0 to GMT +2).</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Employment type: <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Full time</strong>.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are looking for talented people to join our team. Ideal candidates will have:</p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Several years of experience with professional JavaScript programming, which we consider is;<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Writing pure, object-oriented JavaScript applications.</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Ability to create complex JavaScript applications based on your own skills only (excluding usage of external libraries such as jQuery, Prototype, Dojo, or MooTools).</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Being aware and able to solving asynchronous issues.</li></ul></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">In-depth knowledge of core Web standards, like HTML, XML, DOM, and CSS — including their intrinsic implementation differences among browsers (with IE6 also);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Ability to understand and fix complicated DOM manipulation problems.</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Good (enough) English speaking and writing skills. This is the language used in the company.</li></ul><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">"Wow" candidates will also have (not required though):</p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with CKEditor or FCKeditor, having possibly collaborated with the project;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with rich text editors;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with HTML5, CSS3 development;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with Test Cases (like YUI Test);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">A Bachelor's or Master's degree in Computer Science;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Passion for Open Source.</li></ul></div><div class="post" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 30px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); " id=""><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-size: 14px; ">In return we offer:</h3><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Permanent full time employment contract;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Flexible working hours;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Competitive salary;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Work </strong>from <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">home</strong> (you will forget what a traffic jam is);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Working with smart and motivated <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">professionals</strong>;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Becoming a <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">part of great team</strong> who delivers worldwide known software.</li></ul><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Let us start talking. Tell us about the projects you have worked on and your role in them; point to your experience and anything you think might make you a perfect candidate. Contact us with your CV at: <a href="" title="jobs at (spam protection) cksource dot com" id="jobmail1" style="color: rgb(24, 157, 225); ">jobs@cksource.com</a> now!</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are sure you will enjoy it!</p></div><div class="post" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 30px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Please note we only accept CV's in English. Your application must include the following note:</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">"I hereby authorize you to process my personal data included in my job application for the needs of the recruitment process (in accordance to the Personal Data Protection Act 29.08.1997 no 133 position 883).”</p></div></div></div></div></div><dl></dl> - </textarea> - - <h2>Line custom look</h2> - <div id="hood"> - <h1> - <img alt="" src="http://a.cksource.com/c/1/inc/img/demo-little-red.jpg" style="margin-left: 10px; margin-right: 10px; float: left; width: 120px; height: 168px;" />Little Red Riding Hood</h1> - <p> - "<b>Little Red Riding Hood</b>" is a famous <a href="http://en.wikipedia.org/wiki/Fairy_tale" title="Fairy tale">fairy tale</a> about a young girl's encounter with a wolf. The story has been changed considerably in its history and subject to numerous modern adaptations and readings.</p> - <table align="right" border="1" cellpadding="1" cellspacing="1" style="width: 200px;"> - <caption> - <strong>International Names</strong></caption> - <tbody> - <tr> - <td> - Chinese</td> - <td> - <i>小紅帽</i></td> - </tr> - <tr> - <td> - Italian</td> - <td> - <i>Cappuccetto Rosso</i></td> - </tr> - <tr> - <td> - Spanish</td> - <td> - <i>Caperucita Roja</i></td> - </tr> - </tbody> - </table> - <hr> - <hr> - <p> - The version most widely known today is based on the <a href="http://en.wikipedia.org/wiki/Brothers_Grimm" title="Brothers Grimm">Brothers Grimm</a> variant. It is about a girl called Little Red Riding Hood, after the red <a href="http://en.wikipedia.org/wiki/Hood_%28headgear%29" title="Hood (headgear)">hooded</a> <a href="http://en.wikipedia.org/wiki/Cape" title="Cape">cape</a> or <a href="http://en.wikipedia.org/wiki/Cloak" title="Cloak">cloak</a> she wears. The girl walks through the woods to deliver food to her sick grandmother.</p> - <p> - A wolf wants to eat the girl but is afraid to do so in public. He approaches the girl, and she naïvely tells him where she is going. He suggests the girl pick some flowers, which she does. In the meantime, he goes to the grandmother's house and gains entry by pretending to be the girl. He swallows the grandmother whole, and waits for the girl, disguised as the grandmother.</p> - <p> - When the girl arrives, she notices he looks very strange to be her grandma. In most retellings, this eventually culminates with Little Red Riding Hood saying, "My, what big teeth you have!"<br /> - To which the wolf replies, "The better to eat you with," and swallows her whole, too.</p> - <p> - A <a href="http://en.wikipedia.org/wiki/Hunter" title="Hunter">hunter</a>, however, comes to the rescue and cuts the wolf open. Little Red Riding Hood and her grandmother emerge unharmed. They fill the wolf's body with heavy stones, which drown him when he falls into a well. Other versions of the story have had the grandmother shut in the closet instead of eaten, and some have Little Red Riding Hood saved by the hunter as the wolf advances on her rather than after she is eaten.</p> - <p> - The tale makes the clearest contrast between the safe world of the village and the dangers of the <a href="http://en.wikipedia.org/wiki/Enchanted_forest" title="Enchanted forest">forest</a>, conventional antitheses that are essentially medieval, though no written versions are as old as that.</p> - </div> - - <h2>Extreme inline editing</h2> - <div id="interpret" contenteditable="true" style="left: 123px; outline: 1px solid red; border: 15px solid green; position: relative; top: 30; left: 30px;"> - <div style="padding: 20px; background: gray; width: 300px" class="1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim.</div> - <div style="background: violet; padding: 30px;" class="static"> - Position static - <div style="background: green; padding: 30px; border: 14px solid orange">foo</div> - </div> - <dl class="2"> - <dt>Key</dt><dd>Value</dd> - </dl> - <div>Whatever</div> - <hr id="hr"> - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <hr> - <hr> - <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p> - <div style="background: green; padding: 30px; width: 200px">foo</div> - </div> - - <h2>Enter mode: BR</h2> - <textarea cols="80" id="editor5" name="editor5" rows="10"> - Foo<br /> - <hr style="margin: 50px" /> - <hr style="margin: 50px" /> - Foo - </textarea> - - <div id="dev"> - <p id="mouseData"> - <span>Mouse over: <strong id="over"></strong></span> - <span style="display: block">Mouse Y-pos.: <span id="my"></span></span> - </p> - <p id="triggerData"> - <span id="tr_type"></span> - <span id="tr_upper"></span> - <span id="tr_lower"></span> - <span id="tr_edge"></span> - </dl> - <p id="timeData">Time: <span id="time"></span></p> - <p id="hiddenData">Hidden state: <span id="hid"></span></p> - </div> - <script> - - 'use strict'; - - function fixedWidthNumber( text, chars ) { - return ( Array( chars ).join( 0 ) + text ).slice( -chars ); - } - - var DEBUG = { - startTimer: function() { - DEBUG.timer = new Date().getTime(); - }, - - stopTimer: (function() { - var label = CKEDITOR.document.getById( 'time' ), - max = 0, - count = 0, - values = [], - mean = 0, - time = 0; - - return function() { - time = new Date().getTime() - DEBUG.timer; - max = Math.max( time, max ); - - values.unshift( time ); - ( 20 in values ) && values.pop(); - mean = 0; - - for( var i = 0 ; i < values.length ; i++ ) - mean += values[ i ]; - - mean = mean / i; - - label.setText( fixedWidthNumber( time, 3 ) + - ' ms, mean: ' + fixedWidthNumber( 0 | mean, 3 ) + - ' ms, max: ' + fixedWidthNumber( max, 3 ) + - ' ms' ) - count++; - } - })(), - - mousePos: (function( y, element ) - { - var my = CKEDITOR.document.getById( 'my' ), - over = CKEDITOR.document.getById( 'over' ), - name; - - return function( y, element ) { - my.setText( y ); - - if( element && element.$ && element.type == CKEDITOR.NODE_ELEMENT ) { - try { - name = element.getName(); - over.setText( name + '.' + element.getAttribute( 'class' ) ); - } catch( e ) {} - } - else - over.setText( '-' ); - } - })(), - - showTrigger: (function( trigger ) - { - var tr_type = CKEDITOR.document.getById( 'tr_type' ), - tr_upper = CKEDITOR.document.getById( 'tr_upper' ), - tr_lower = CKEDITOR.document.getById( 'tr_lower' ), - tr_edge = CKEDITOR.document.getById( 'tr_edge' ), - tup, tbo, upper, lower; - - return function( trigger ) { - tup && tup.removeAttribute('id') && ( tup = null ); - tbo && tbo.removeAttribute('id') && ( tbo = null ); - - if ( !trigger ) - return tr_type.setText( '-' ) && - tr_upper.setText( '-' ) && - tr_lower.setText( '-' ) && - tr_edge.setText( '-' ); - - upper = trigger.upper, - lower = trigger.lower; - - tr_type.setText( trigger.type == 2 ? 'EXPAND': 'EDGE' ); - tr_upper.setText( upper ? upper.getName() + '.' + upper.getAttribute( 'class' ): 'NULL' ); - tr_lower.setText( lower ? lower.getName() + '.' + lower.getAttribute( 'class' ): 'NULL' ); - tr_edge.setText( trigger.edge ? [ 'EDGE_TOP', 'EDGE_BOTTOM', 'EDGE_MIDDLE' ][ trigger.edge - 1 ]: 'NULL' ); - - upper && ( tup = upper ) && tup.setAttribute( 'id', 'tup' ); - lower && ( tbo = lower ) && tbo.setAttribute( 'id', 'tbo' ); - } - })(), - - showHidden: (function( state ) - { - var cnt = CKEDITOR.document.getById( 'hid' ); - - return function( state ) { - cnt[ state ? 'addClass': 'removeClass' ]( 'hl' ); - cnt.setText( state ? 'enabled': 'disabled' ); - } - })(), - - markElement: function( element ) { - if( !isHtml( element )) - return; - - DEBUG.marked && DEBUG.marked.setStyles( { - 'outline': 'none' - } ); - - DEBUG.marked = element; - - element.setStyles( { - 'outline': 'red solid 2px' - } ); - }, - - // Log functions. - log: function() {}, - logElements: function() {}, - groupStart: function() {}, - groupEnd: function() {}, - logEnd: function() {}, - logElementsEnd: function() {} - }; - - var logEnable = { - log: function() { - var args = []; - for( var i = 0; i < arguments.length ; i++ ) - args.push( arguments[ i ] ); - - console.log.apply( console, args ); - }, - - logElements: function( elements, labels, info ) { - var log = {}, - label; - - for ( var i = 0 ; i < elements.length; i++ ) { - label = labels ? labels [ i ] : i; - - if( !elements[ i ] ) { - log[ label ] = { - 'name': 'null', - 'class': 'null' - } - } - else { - log[ labels ? labels [ i ]: i ] = { - 'name': elements[ i ].is ? elements[ i ].getName(): 'null', - 'class': elements[ i ].is ? elements[ i ].getAttribute( 'class' ): 'null' - } - } - } - - typeof JSON != 'undefined' && DEBUG.log( ( info ? info.toUpperCase() + ' ': '' ) + JSON.stringify( log ) ); - }, - - groupStart: function( label ) { - console.group( label ); - }, - - groupEnd: function() { - console.groupEnd(); - }, - - logEnd: function() { - DEBUG.log.apply( null, arguments ); - DEBUG.groupEnd(); - }, - - logElementsEnd: function() { - DEBUG.logElements.apply( null, arguments ); - DEBUG.groupEnd(); - } - } - - // Enable console.log debugging with ?debug address parameter. - window.location.href.match( /debug$/g ) ? CKEDITOR.tools.extend( DEBUG, logEnable, true ): null; - - // CKEDITOR.addCss('\ - // #tup { outline: #FEB2B2 solid 2px; box-shadow: 3px 3px 0 #FEB2B2; } \ - // #tbo { outline: #B2FEB2 solid 2px; box-shadow: 3px 3px 0 #B2FEB2; } \ - // p { background: pink }\ - // '); - - CKEDITOR.replace( 'editor1' ); - - CKEDITOR.replace( 'editor2', { height: 150 } ); - - CKEDITOR.replace( 'editor3', { - magicline_everywhere: 1, - magicline_holdDistance: .2, - language: 'pl' - }); - - CKEDITOR.replace( 'editor4' ); - - CKEDITOR.replace( 'hood', { - magicline_color: 'green' - }); - - CKEDITOR.replace( 'editor5', { - enterMode : CKEDITOR.ENTER_BR - }); - - </script> -</body> -</html> diff --git a/addons/website/static/lib/ckeditor/plugins/magicline/lang/en.js b/addons/website/static/lib/ckeditor/plugins/magicline/lang/en.js deleted file mode 100644 index 8111a671569..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/magicline/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'magicline', 'en', { - title: 'Insert paragraph here' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/magicline/plugin.js b/addons/website/static/lib/ckeditor/plugins/magicline/plugin.js deleted file mode 100644 index 85eee75135d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/magicline/plugin.js +++ /dev/null @@ -1,1768 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Allows accessing difficult focus spaces. - */ - -'use strict'; - -(function() { - CKEDITOR.plugins.add( 'magicline', { - lang: 'ar,bg,ca,cs,cy,de,el,en,eo,es,et,eu,fa,fi,fr,fr-ca,gl,he,hr,hu,id,it,ja,ko,ku,lv,nb,nl,no,pl,pt,pt-br,ru,si,sk,sl,sq,sv,tr,ug,uk,vi,zh-cn', // %REMOVE_LINE_CORE% - init: initPlugin - }); - - // Activates the box inside of an editor. - function initPlugin( editor ) { - - var enterBehaviors = {}; - enterBehaviors[ CKEDITOR.ENTER_BR ] = 'br'; - enterBehaviors[ CKEDITOR.ENTER_P ] = 'p'; - enterBehaviors[ CKEDITOR.ENTER_DIV ] = 'div'; - - // Configurables - var config = editor.config, - triggerOffset = config.magicline_triggerOffset || 30, - enterMode = config.enterMode, - that = { - // Global stuff is being initialized here. - editor: editor, - enterBehavior: enterBehaviors[ enterMode ], // A tag which is to be inserted by the magicline. - enterMode: enterMode, - triggerOffset: triggerOffset, - holdDistance: 0 | triggerOffset * ( config.magicline_holdDistance || 0.5 ), - boxColor: config.magicline_color || '#ff0000', - rtl: config.contentsLangDirection == 'rtl', - tabuList: [ 'data-widget-wrapper' ].concat( config.magicline_tabuList || [] ), - triggers: config.magicline_everywhere ? DTD_BLOCK : { table:1,hr:1,div:1,ul:1,ol:1,dl:1,form:1,blockquote:1 } - }, - scrollTimeout, checkMouseTimeoutPending, checkMouseTimeout, checkMouseTimer; - - // %REMOVE_START% - // Internal DEBUG uses tools located in the topmost window. - - // (#9701) Due to security limitations some browsers may throw - // errors when accessing window.top object. Do it safely first then. - try { - that.debug = window.top.DEBUG; - } - catch ( e ) {} - - that.debug = that.debug || { - groupEnd: function() {}, - groupStart: function() {}, - log: function() {}, - logElements: function() {}, - logElementsEnd: function() {}, - logEnd: function() {}, - mousePos: function() {}, - showHidden: function() {}, - showTrigger: function() {}, - startTimer: function() {}, - stopTimer: function() {} - }; - // %REMOVE_END% - - // Simple irrelevant elements filter. - that.isRelevant = function( node ) { - return isHtml( node ) // -> Node must be an existing HTML element. - && !isLine( that, node ) // -> Node can be neither the box nor its child. - && !isFlowBreaker( node ); // -> Node can be neither floated nor positioned nor aligned. - }; - - editor.on( 'contentDom', addListeners, this ); - - function addListeners() { - var editable = editor.editable(), - doc = editor.document, - win = editor.window, - listener; - - // Global stuff is being initialized here. - extend( that, { - editable: editable, - inInlineMode: editable.isInline(), - doc: doc, - win: win - }, true ); - - // This is the boundary of the editor. For inline the boundary is editable itself. - // For framed editor, the HTML element is a real boundary. - that.boundary = that.inInlineMode ? that.editable : that.doc.getDocumentElement(); - - // Enabling the box inside of inline editable is pointless. - // There's no need to access spaces inside paragraphs, links, spans, etc. - if ( editable.is( dtd.$inline ) ) - return; - - // Handle in-line editing by setting appropriate position. - // If current position is static, make it relative and clear top/left coordinates. - if ( that.inInlineMode && !isPositioned( editable ) ) { - editable.setStyles({ - position: 'relative', - top: null, - left: null - }); - } - // Enable the box. Let it produce children elements, initialize - // event handlers and own methods. - initLine.call( this, that ); - - // Get view dimensions and scroll positions. - // At this stage (before any checkMouse call) it is used mostly - // by tests. Nevertheless it a crucial thing. - updateWindowSize( that ); - - // Remove the box before an undo image is created. - // This is important. If we didn't do that, the *undo thing* would revert the box into an editor. - // Thanks to that, undo doesn't even know about the existence of the box. - editable.attachListener( editor, 'beforeUndoImage', function() { - that.line.detach(); - }); - - // Removes the box HTML from editor data string if getData is called. - // Thanks to that, an editor never yields data polluted by the box. - // Listen with very high priority, so line will be removed before other - // listeners will see it. - editable.attachListener( editor, 'beforeGetData', function() { - // If the box is in editable, remove it. - if ( that.line.wrap.getParent() ) { - that.line.detach(); - - // Restore line in the last listener for 'getData'. - editor.once( 'getData', function() { - that.line.attach(); - }, null, null, 1000 ); - } - }, null, null, 0 ); - - // Hide the box on mouseout if mouse leaves document. - editable.attachListener( that.inInlineMode ? doc : doc.getWindow().getFrame(), 'mouseout', function( event ) { - if ( editor.mode != 'wysiwyg' ) - return; - - // Check for inline-mode editor. If so, check mouse position - // and remove the box if mouse outside of an editor. - if ( that.inInlineMode ) { - var mouse = { - x: event.data.$.clientX, - y: event.data.$.clientY - }; - - updateWindowSize( that ); - updateEditableSize( that, true ); - - var size = that.view.editable, - scroll = that.view.scroll; - - // If outside of an editor... - if ( !inBetween( mouse.x, size.left - scroll.x, size.right - scroll.x ) || !inBetween( mouse.y, size.top - scroll.y, size.bottom - scroll.y ) ) { - clearTimeout( checkMouseTimer ); - checkMouseTimer = null; - that.line.detach(); - } - } - - else { - clearTimeout( checkMouseTimer ); - checkMouseTimer = null; - that.line.detach(); - } - }); - - // This one deactivates hidden mode of an editor which - // prevents the box from being shown. - editable.attachListener( editable, 'keyup', function( event ) { - that.hiddenMode = 0; - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - }); - - editable.attachListener( editable, 'keydown', function( event ) { - if ( editor.mode != 'wysiwyg' ) - return; - - var keyStroke = event.data.getKeystroke(), - selection = editor.getSelection(), - selected = selection.getStartElement(); - - switch ( keyStroke ) { - // Shift pressed - case 2228240: // IE - case 16: - that.hiddenMode = 1; - that.line.detach(); - } - - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - }); - - // This method ensures that checkMouse aren't executed - // in parallel and no more frequently than specified in timeout function. - // In framed editor, document is used as a trigger, to provide magicline - // functionality when mouse is below the body (short content, short body). - editable.attachListener( that.inInlineMode ? editable : doc, 'mousemove', function( event ) { - checkMouseTimeoutPending = true; - - if ( editor.mode != 'wysiwyg' || editor.readOnly || checkMouseTimer ) - return; - - // IE<9 requires this event-driven object to be created - // outside of the setTimeout statement. - // Otherwise it loses the event object with its properties. - var mouse = { - x: event.data.$.clientX, - y: event.data.$.clientY - }; - - checkMouseTimer = setTimeout( function() { - checkMouse( mouse ); - }, 30 ); // balances performance and accessibility - }); - - // This one removes box on scroll event. - // It is to avoid box displacement. - editable.attachListener( win, 'scroll', function( event ) { - if ( editor.mode != 'wysiwyg' ) - return; - - that.line.detach(); - - // To figure this out just look at the mouseup - // event handler below. - if ( env.webkit ) { - that.hiddenMode = 1; - - clearTimeout( scrollTimeout ); - scrollTimeout = setTimeout( function() { - that.hiddenMode = 0; - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - }, 50 ); - - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - } - }); - - // Those event handlers remove the box on mousedown - // and don't reveal it until the mouse is released. - // It is to prevent box insertion e.g. while scrolling - // (w/ scrollbar), selecting and so on. - editable.attachListener( win, 'mousedown', function( event ) { - if ( editor.mode != 'wysiwyg' ) - return; - - that.line.detach(); - that.hiddenMode = 1; - - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - }); - - // Google Chrome doesn't trigger this on the scrollbar (since 2009...) - // so it is totally useless to check for scroll finish - // see: http://code.google.com/p/chromium/issues/detail?id=14204 - editable.attachListener( win, 'mouseup', function( event ) { - that.hiddenMode = 0; - that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE% - }); - - // Editor commands for accessing difficult focus spaces. - editor.addCommand( 'accessPreviousSpace', accessFocusSpaceCmd( that ) ); - editor.addCommand( 'accessNextSpace', accessFocusSpaceCmd( that, true ) ); - - editor.setKeystroke( [ - [ config.magicline_keystrokePrevious, 'accessPreviousSpace' ], - [ config.magicline_keystrokeNext, 'accessNextSpace' ] - ] ); - - // Revert magicline hot node on undo/redo. - editor.on( 'loadSnapshot', function( event ) { - var elements = editor.document.getElementsByTag( that.enterBehavior ), - element; - - for ( var i = elements.count(); i--; ) { - if ( ( element = elements.getItem( i ) ).hasAttribute( 'data-cke-magicline-hot' ) ) { - // Restore hotNode - that.hotNode = element; - // Restore last access direction - that.lastCmdDirection = element.getAttribute( 'data-cke-magicline-dir' ) === 'true' ? true : false; - break; - } - } - } ); - - // This method handles mousemove mouse for box toggling. - // It uses mouse position to determine underlying element, then - // it tries to use different trigger type in order to place the box - // in correct place. The following procedure is executed periodically. - function checkMouse( mouse ) { - that.debug.groupStart( 'CheckMouse' ); // %REMOVE_LINE% - that.debug.startTimer(); // %REMOVE_LINE% - - that.mouse = mouse; - that.trigger = null; - - checkMouseTimer = null; - updateWindowSize( that ); - - if ( checkMouseTimeoutPending // -> There must be an event pending. - && !that.hiddenMode // -> Can't be in hidden mode. - && editor.focusManager.hasFocus // -> Editor must have focus. - && !that.line.mouseNear() // -> Mouse pointer can't be close to the box. - && ( that.element = elementFromMouse( that, true ) ) ) // -> There must be valid element. - { - // If trigger exists, and trigger is correct -> show the box. - // Don't show the line if trigger is a descendant of some tabu-list element. - if ( ( that.trigger = triggerEditable( that ) || triggerEdge( that ) || triggerExpand( that ) ) && - !isInTabu( that, that.trigger.upper || that.trigger.lower ) ) { - that.line.attach().place(); - } - - // Otherwise remove the box - else { - that.trigger = null; - that.line.detach(); - } - - that.debug.showTrigger( that.trigger ); // %REMOVE_LINE% - that.debug.mousePos( mouse.y, that.element ); // %REMOVE_LINE% - - checkMouseTimeoutPending = false; - } - - that.debug.stopTimer(); // %REMOVE_LINE% - that.debug.groupEnd(); // %REMOVE_LINE% - } - - // This one allows testing and debugging. It reveals some - // inner methods to the world. - this.backdoor = { - accessFocusSpace: accessFocusSpace, - boxTrigger: boxTrigger, - isLine: isLine, - getAscendantTrigger: getAscendantTrigger, - getNonEmptyNeighbour: getNonEmptyNeighbour, - getSize: getSize, - that: that, - triggerEdge: triggerEdge, - triggerEditable: triggerEditable, - triggerExpand: triggerExpand - }; - } - } - - // Some shorthands for common methods to save bytes - var extend = CKEDITOR.tools.extend, - newElement = CKEDITOR.dom.element, - newElementFromHtml = newElement.createFromHtml, - env = CKEDITOR.env, - dtd = CKEDITOR.dtd, - - // Constant values, types and so on. - EDGE_TOP = 128, - EDGE_BOTTOM = 64, - EDGE_MIDDLE = 32, - TYPE_EDGE = 16, - TYPE_EXPAND = 8, - LOOK_TOP = 4, - LOOK_BOTTOM = 2, - LOOK_NORMAL = 1, - WHITE_SPACE = '\u00A0', - DTD_LISTITEM = dtd.$listItem, - DTD_TABLECONTENT = dtd.$tableContent, - DTD_NONACCESSIBLE = extend( {}, dtd.$nonEditable, dtd.$empty ), - DTD_BLOCK = dtd.$block, - - // Minimum time that must elapse between two update*Size calls. - // It prevents constant getComuptedStyle calls and improves performance. - CACHE_TIME = 100, - - // Shared CSS stuff for box elements - CSS_COMMON = 'width:0px;height:0px;padding:0px;margin:0px;display:block;' + 'z-index:9999;color:#fff;position:absolute;font-size: 0px;line-height:0px;', - CSS_TRIANGLE = CSS_COMMON + 'border-color:transparent;display:block;border-style:solid;', - TRIANGLE_HTML = '<span>' + WHITE_SPACE + '</span>'; - - function areSiblings( that, upper, lower ) { - return isHtml( upper ) && isHtml( lower ) && lower.equals( upper.getNext( function( node ) { - return !( isEmptyTextNode( node ) || isComment( node ) || isFlowBreaker( node ) ); - }) ); - } - - // boxTrigger is an abstract type which describes - // the relationship between elements that may result - // in showing the box. - // - // The following type is used by numerous methods - // to share information about the hypothetical box placement - // and look by referring to boxTrigger properties. - function boxTrigger( triggerSetup ) { - this.upper = triggerSetup[ 0 ]; - this.lower = triggerSetup[ 1 ]; - this.set.apply( this, triggerSetup.slice( 2 ) ); - } - - boxTrigger.prototype = { - set: function( edge, type, look ) { - this.properties = edge + type + ( look || LOOK_NORMAL ); - return this; - }, - - is: function( property ) { - return ( this.properties & property ) == property; - } - }; - - var elementFromMouse = ( function() { - function elementFromPoint( doc, mouse ) { - return new CKEDITOR.dom.element( doc.$.elementFromPoint( mouse.x, mouse.y ) ); - } - - return function( that, ignoreBox, forceMouse ) { - if ( !that.mouse ) - return null; - - var doc = that.doc, - lineWrap = that.line.wrap, - mouse = forceMouse || that.mouse, - element = elementFromPoint( doc, mouse ); - - // If ignoreBox is set and element is the box, it means that we - // need to hide the box for a while, repeat elementFromPoint - // and show it again. - if ( ignoreBox && isLine( that, element ) ) { - lineWrap.hide(); - element = elementFromPoint( doc, mouse ); - lineWrap.show(); - } - - // Return nothing if: - // \-> Element is not HTML. - if ( !( element && element.type == CKEDITOR.NODE_ELEMENT && element.$ ) ) { - return null; - } - - // Also return nothing if: - // \-> We're IE<9 and element is out of the top-level element (editable for inline and HTML for framed). - // This is due to the bug which allows IE<9 firing mouse events on element - // with contenteditable=true while doing selection out (far, away) of the element. - // Thus we must always be sure that we stay in editable or HTML. - if ( env.ie && env.version < 9 ) { - if ( !( that.boundary.equals( element ) || that.boundary.contains( element ) ) ) - return null; - } - - return element; - }; - })(); - - // Gets the closest parent node that belongs to triggers group. - function getAscendantTrigger( that ) { - var node = that.element, - trigger; - - if ( node && isHtml( node ) ) { - return ( trigger = node.getAscendant( that.triggers, true ) ) && - !trigger.contains( that.editable ) && - !trigger.equals( that.editable ) ? trigger : null; - } - - return null; - } - - function getMidpoint( that, upper, lower ) { - updateSize( that, upper ); - updateSize( that, lower ); - - var upperSizeBottom = upper.size.bottom, - lowerSizeTop = lower.size.top; - - return upperSizeBottom && lowerSizeTop ? 0 | ( upperSizeBottom + lowerSizeTop ) / 2 : upperSizeBottom || lowerSizeTop; - } - - // Get nearest node (either text or HTML), but: - // \-> Omit all empty text nodes (containing white characters only). - // \-> Omit BR elements - // \-> Omit flow breakers. - function getNonEmptyNeighbour( that, node, goBack ) { - node = node[ goBack ? 'getPrevious' : 'getNext' ]( function( node ) { - return ( isTextNode( node ) && !isEmptyTextNode( node ) ) || - ( isHtml( node ) && !isFlowBreaker( node ) && !isLine( that, node ) ); - }); - - return node; - } - - function inBetween( val, lower, upper ) { - return val > lower && val < upper; - } - - // Access space line consists of a few elements (spans): - // \-> Line wrapper. - // \-> Line. - // \-> Line triangles: left triangle (LT), right triangle (RT). - // \-> Button handler (BTN). - // - // +--------------------------------------------------- line.wrap (span) -----+ - // | +---------------------------------------------------- line (span) -----+ | - // | | +- LT \ +- BTN -+ / RT -+ | | - // | | | \ | | | / | | | - // | | | / | <__| | \ | | | - // | | +-----/ +-------+ \-----+ | | - // | +----------------------------------------------------------------------+ | - // +--------------------------------------------------------------------------+ - // - function initLine( that ) { - var doc = that.doc, - // This the main box element that holds triangles and the insertion button - line = newElementFromHtml( '<span contenteditable="false" style="' + CSS_COMMON + 'position:absolute;border-top:1px dashed ' + that.boxColor + '"></span>', doc ), - iconPath = this.path + 'images/' + ( env.hidpi ? 'hidpi/' : '' ) + 'icon.png'; - - extend( line, { - - attach: function() { - // Only if not already attached - if ( !this.wrap.getParent() ) - this.wrap.appendTo( that.editable, true ); - - return this; - }, - - // Looks are as follows: [ LOOK_TOP, LOOK_BOTTOM, LOOK_NORMAL ]. - lineChildren: [ - extend( - newElementFromHtml( '<span title="' + that.editor.lang.magicline.title + - '" contenteditable="false">↵</span>', doc ), { - base: CSS_COMMON + 'height:17px;width:17px;' + ( that.rtl ? 'left' : 'right' ) + ':17px;' - + 'background:url(' + iconPath + ') center no-repeat ' + that.boxColor + ';cursor:pointer;' - + ( env.hc ? 'font-size: 15px;line-height:14px;border:1px solid #fff;text-align:center;' : '' ) - + ( env.hidpi ? 'background-size: 9px 10px;' : '' ), - looks: [ - 'top:-8px;' + CKEDITOR.tools.cssVendorPrefix( 'border-radius', '2px', 1 ), - 'top:-17px;' + CKEDITOR.tools.cssVendorPrefix( 'border-radius', '2px 2px 0px 0px', 1 ), - 'top:-1px;' + CKEDITOR.tools.cssVendorPrefix( 'border-radius', '0px 0px 2px 2px', 1 ) - ] - }), - extend( newElementFromHtml( TRIANGLE_HTML, doc ), { - base: CSS_TRIANGLE + 'left:0px;border-left-color:' + that.boxColor + ';', - looks: [ - 'border-width:8px 0 8px 8px;top:-8px', - 'border-width:8px 0 0 8px;top:-8px', - 'border-width:0 0 8px 8px;top:0px' - ] - }), - extend( newElementFromHtml( TRIANGLE_HTML, doc ), { - base: CSS_TRIANGLE + 'right:0px;border-right-color:' + that.boxColor + ';', - looks: [ - 'border-width:8px 8px 8px 0;top:-8px', - 'border-width:8px 8px 0 0;top:-8px', - 'border-width:0 8px 8px 0;top:0px' - ] - }) - ], - - detach: function() { - // Detach only if already attached. - if ( this.wrap.getParent() ) - this.wrap.remove(); - - return this; - }, - - // Checks whether mouseY is around an element by comparing boundaries and considering - // an offset distance. - mouseNear: function() { - that.debug.groupStart( 'mouseNear' ); // %REMOVE_LINE% - - updateSize( that, this ); - var offset = that.holdDistance, - size = this.size; - - // Determine neighborhood by element dimensions and offsets. - if ( size && inBetween( that.mouse.y, size.top - offset, size.bottom + offset ) && inBetween( that.mouse.x, size.left - offset, size.right + offset ) ) { - that.debug.logEnd( 'Mouse is near.' ); // %REMOVE_LINE% - return true; - } - - that.debug.logEnd( 'Mouse isn\'t near.' ); // %REMOVE_LINE% - return false; - }, - - // Adjusts position of the box according to the trigger properties. - // If also affects look of the box depending on the type of the trigger. - place: function() { - var view = that.view, - editable = that.editable, - trigger = that.trigger, - upper = trigger.upper, - lower = trigger.lower, - any = upper || lower, - parent = any.getParent(), - styleSet = {}; - - // Save recent trigger for further insertion. - // It is necessary due to the fact, that that.trigger may - // contain different boxTrigger at the moment of insertion - // or may be even null. - this.trigger = trigger; - - upper && updateSize( that, upper, true ); - lower && updateSize( that, lower, true ); - updateSize( that, parent, true ); - - // Yeah, that's gonna be useful in inline-mode case. - if ( that.inInlineMode ) - updateEditableSize( that, true ); - - // Set X coordinate (left, right, width). - if ( parent.equals( editable ) ) { - styleSet.left = view.scroll.x; - styleSet.right = -view.scroll.x; - styleSet.width = ''; - } else { - styleSet.left = any.size.left - any.size.margin.left + view.scroll.x - ( that.inInlineMode ? view.editable.left + view.editable.border.left : 0 ); - styleSet.width = any.size.outerWidth + any.size.margin.left + any.size.margin.right + view.scroll.x; - styleSet.right = ''; - } - - // Set Y coordinate (top) for trigger consisting of two elements. - if ( upper && lower ) { - // No margins at all or they're equal. Place box right between. - if ( upper.size.margin.bottom === lower.size.margin.top ) - styleSet.top = 0 | ( upper.size.bottom + upper.size.margin.bottom / 2 ); - else { - // Upper margin < lower margin. Place at lower margin. - if ( upper.size.margin.bottom < lower.size.margin.top ) - styleSet.top = upper.size.bottom + upper.size.margin.bottom; - // Upper margin > lower margin. Place at upper margin - lower margin. - else - styleSet.top = upper.size.bottom + upper.size.margin.bottom - lower.size.margin.top; - } - } - // Set Y coordinate (top) for single-edge trigger. - else if ( !upper ) - styleSet.top = lower.size.top - lower.size.margin.top; - else if ( !lower ) - styleSet.top = upper.size.bottom + upper.size.margin.bottom; - - // Set box button modes if close to the viewport horizontal edge - // or look forced by the trigger. - if ( trigger.is( LOOK_TOP ) || inBetween( styleSet.top, view.scroll.y - 15, view.scroll.y + 5 ) ) { - styleSet.top = that.inInlineMode ? 0 : view.scroll.y; - this.look( LOOK_TOP ); - } else if ( trigger.is( LOOK_BOTTOM ) || inBetween( styleSet.top, view.pane.bottom - 5, view.pane.bottom + 15 ) ) { - styleSet.top = that.inInlineMode ? - view.editable.height + view.editable.padding.top + view.editable.padding.bottom - : - view.pane.bottom - 1; - - this.look( LOOK_BOTTOM ); - } else { - if ( that.inInlineMode ) - styleSet.top -= view.editable.top + view.editable.border.top; - - this.look( LOOK_NORMAL ); - } - - if ( that.inInlineMode ) { - // 1px bug here... - styleSet.top--; - - // Consider the editable to be an element with overflow:scroll - // and non-zero scrollTop/scrollLeft value. - // For example: divarea editable. (#9383) - styleSet.top += view.editable.scroll.top; - styleSet.left += view.editable.scroll.left; - } - - // Append `px` prefixes. - for ( var style in styleSet ) - styleSet[ style ] = CKEDITOR.tools.cssLength( styleSet[ style ] ); - - this.setStyles( styleSet ); - }, - - // Changes look of the box according to current needs. - // Three different styles are available: [ LOOK_TOP, LOOK_BOTTOM, LOOK_NORMAL ]. - look: function( look ) { - if ( this.oldLook == look ) - return; - - for ( var i = this.lineChildren.length, child; i--; ) - ( child = this.lineChildren[ i ] ).setAttribute( 'style', child.base + child.looks[ 0 | look / 2 ] ); - - this.oldLook = look; - }, - - wrap: new newElement( 'span', that.doc ) - - }); - - // Insert children into the box. - for ( var i = line.lineChildren.length; i--; ) - line.lineChildren[ i ].appendTo( line ); - - // Set default look of the box. - line.look( LOOK_NORMAL ); - - // Using that wrapper prevents IE (8,9) from resizing editable area at the moment - // of box insertion. This works thanks to the fact, that positioned box is wrapped by - // an inline element. So much tricky. - line.appendTo( line.wrap ); - - // Make the box unselectable. - line.unselectable(); - - // Handle accessSpace node insertion. - line.lineChildren[ 0 ].on( 'mouseup', function( event ) { - line.detach(); - - accessFocusSpace( that, function( accessNode ) { - // Use old trigger that was saved by 'place' method. Look: line.place - var trigger = that.line.trigger; - - accessNode[ trigger.is( EDGE_TOP ) ? 'insertBefore' : 'insertAfter' ] - ( trigger.is( EDGE_TOP ) ? trigger.lower : trigger.upper ); - }, true ); - - that.editor.focus(); - - if ( !env.ie && that.enterMode != CKEDITOR.ENTER_BR ) - that.hotNode.scrollIntoView(); - - event.data.preventDefault( true ); - }); - - // Prevents IE9 from displaying the resize box and disables drag'n'drop functionality. - line.on( 'mousedown', function( event ) { - event.data.preventDefault( true ); - }); - - that.line = line; - } - - // This function allows accessing any focus space according to the insert function: - // * For enterMode ENTER_P it creates P element filled with dummy white-space. - // * For enterMode ENTER_DIV it creates DIV element filled with dummy white-space. - // * For enterMode ENTER_BR it creates BR element or in IE. - // - // The node is being inserted according to insertFunction. Finally the method - // selects the non-breaking space making the node ready for typing. - function accessFocusSpace( that, insertFunction, doSave ) { - var range = new CKEDITOR.dom.range( that.doc ), - editor = that.editor, - accessNode; - - // IE requires text node of in ENTER_BR mode. - if ( env.ie && that.enterMode == CKEDITOR.ENTER_BR ) - accessNode = that.doc.createText( WHITE_SPACE ); - - // In other cases a regular element is used. - else { - accessNode = new newElement( that.enterBehavior, that.doc ); - - if ( that.enterMode != CKEDITOR.ENTER_BR ) { - var dummy = that.doc.createText( WHITE_SPACE ); - dummy.appendTo( accessNode ); - } - } - - doSave && editor.fire( 'saveSnapshot' ); - - insertFunction( accessNode ); - //dummy.appendTo( accessNode ); - range.moveToPosition( accessNode, CKEDITOR.POSITION_AFTER_START ); - editor.getSelection().selectRanges( [ range ] ); - that.hotNode = accessNode; - - doSave && editor.fire( 'saveSnapshot' ); - } - - // Access focus space on demand by taking an element under the caret as a reference. - // The space is accessed provided the element under the caret is trigger AND: - // - // 1. First/last-child of its parent: - // +----------------------- Parent element -+ - // | +------------------------------ DIV -+ | <-- Access before - // | | Foo^ | | - // | | | | - // | +------------------------------------+ | <-- Access after - // +----------------------------------------+ - // - // OR - // - // 2. It has a direct sibling element, which is also a trigger: - // +-------------------------------- DIV#1 -+ - // | Foo^ | - // | | - // +----------------------------------------+ - // <-- Access here - // +-------------------------------- DIV#2 -+ - // | Bar | - // | | - // +----------------------------------------+ - // - // OR - // - // 3. It has a direct sibling, which is a trigger and has a valid neighbour trigger, - // but belongs to dtd.$.empty/nonEditable: - // +------------------------------------ P -+ - // | Foo^ | - // | | - // +----------------------------------------+ - // +----------------------------------- HR -+ - // <-- Access here - // +-------------------------------- DIV#2 -+ - // | Bar | - // | | - // +----------------------------------------+ - // - function accessFocusSpaceCmd( that, insertAfter ) { - return { - canUndo: true, - modes: { wysiwyg: 1 }, - exec: ( function() { - - // Inserts line (accessNode) at the position by taking target node as a reference. - function doAccess( target ) { - // Remove old hotNode under certain circumstances. - var hotNodeChar = ( env.ie && env.version < 9 ? ' ' : WHITE_SPACE ), - removeOld = that.hotNode && // Old hotNode must exist. - that.hotNode.getText() == hotNodeChar && // Old hotNode hasn't been changed. - that.element.equals( that.hotNode ) && // Caret is inside old hotNode. - that.lastCmdDirection === !!insertAfter; // Command is executed in the same direction. - - accessFocusSpace( that, function( accessNode ) { - if ( removeOld && that.hotNode ) - that.hotNode.remove(); - - accessNode[ insertAfter ? 'insertAfter' : 'insertBefore' ]( target ); - - // Make this element distinguishable. Also remember the direction - // it's been inserted into document. - accessNode.setAttributes( { - 'data-cke-magicline-hot': 1, - 'data-cke-magicline-dir': !!insertAfter - } ); - - // Save last direction of the command (is insertAfter?). - that.lastCmdDirection = !!insertAfter; - } ); - - if( !env.ie && that.enterMode != CKEDITOR.ENTER_BR ) - that.hotNode.scrollIntoView(); - - // Detach the line if was visible (previously triggered by mouse). - that.line.detach(); - } - - return function( editor ) { - var selected = editor.getSelection().getStartElement(); - - // (#9833) Go down to the closest non-inline element in DOM structure - // since inline elements don't participate in in magicline. - selected = selected.getAscendant( DTD_BLOCK, 1 ); - - // Stop if selected is a child of a tabu-list element. - if ( isInTabu( that, selected ) ) - return; - - // Sometimes it may happen that there's no parent block below selected element - // or, for example, getAscendant reaches editable or editable parent. - // We must avoid such pathological cases. - if ( !selected || selected.equals( that.editable ) || selected.contains( that.editable ) ) - return; - - // That holds element from mouse. Replace it with the - // element under the caret. - that.element = selected; - - // (3.) Handle the following cases where selected neighbour - // is a trigger inaccessible for the caret AND: - // - Is first/last-child - // OR - // - Has a sibling, which is also a trigger. - var neighbor = getNonEmptyNeighbour( that, selected, !insertAfter ), - neighborSibling; - - // Check for a neighbour that belongs to triggers. - // Consider only non-accessible elements (they cannot have any children) - // since they cannot be given a caret inside, to run the command - // the regular way (1. & 2.). - if ( isHtml( neighbor ) && neighbor.is( that.triggers ) && neighbor.is( DTD_NONACCESSIBLE ) && - ( - // Check whether neighbor is first/last-child. - !getNonEmptyNeighbour( that, neighbor, !insertAfter ) - || - // Check for a sibling of a neighbour that also is a trigger. - ( - ( neighborSibling = getNonEmptyNeighbour( that, neighbor, !insertAfter ) ) && - isHtml( neighborSibling ) && - neighborSibling.is( that.triggers ) - ) - ) - ) { - doAccess( neighbor ); - return; - } - - // Look for possible target element DOWN "selected" DOM branch (towards editable) - // that belong to that.triggers - var target = getAscendantTrigger( that, selected ); - - // No HTML target -> no access. - if ( !isHtml( target ) ) - return; - - // (1.) Target is first/last child -> access. - if ( !getNonEmptyNeighbour( that, target, !insertAfter ) ) { - doAccess( target ); - return; - } - - var sibling = getNonEmptyNeighbour( that, target, !insertAfter ); - - // (2.) Target has a sibling that belongs to that.triggers -> access. - if ( sibling && isHtml( sibling ) && sibling.is( that.triggers ) ) { - doAccess( target ); - return; - } - }; - })() - }; - } - - function isLine( that, node ) { - if ( !( node && node.type == CKEDITOR.NODE_ELEMENT && node.$ ) ) - return false; - - var line = that.line; - - return line.wrap.equals( node ) || line.wrap.contains( node ); - } - - // Is text node containing white-spaces only? - var isEmptyTextNode = CKEDITOR.dom.walker.whitespaces(); - - // Is fully visible HTML node? - function isHtml( node ) { - return node && node.type == CKEDITOR.NODE_ELEMENT && node.$; // IE requires that - } - - function isFloated( element ) { - if ( !isHtml( element ) ) - return false; - - var options = { left:1,right:1,center:1 }; - - return !!( options[ element.getComputedStyle( 'float' ) ] || options[ element.getAttribute( 'align' ) ] ); - } - - function isFlowBreaker( element ) { - if ( !isHtml( element ) ) - return false; - - return isPositioned( element ) || isFloated( element ); - } - - // Isn't node of NODE_COMMENT type? - var isComment = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_COMMENT ); - - function isPositioned( element ) { - return !!{ absolute:1,fixed:1,relative:1 }[ element.getComputedStyle( 'position' ) ]; - } - - // Is text node? - function isTextNode( node ) { - return node && node.type == CKEDITOR.NODE_TEXT; - } - - function isTrigger( that, element ) { - return isHtml( element ) ? element.is( that.triggers ) : null; - } - - function isInTabu( that, element ) { - if ( !element ) - return false; - - var parents = element.getParents( 1 ); - - for ( var i = parents.length ; i-- ; ) { - for ( var j = that.tabuList.length ; j-- ; ) { - if ( parents[ i ].hasAttribute( that.tabuList[ j ] ) ) - return true; - } - } - - return false; - } - - // This function checks vertically is there's a relevant child between element's edge - // and the pointer. - // \-> Table contents are omitted. - function isChildBetweenPointerAndEdge( that, parent, edgeBottom ) { - var edgeChild = parent[ edgeBottom ? 'getLast' : 'getFirst' ]( function( node ) { - return that.isRelevant( node ) && !node.is( DTD_TABLECONTENT ); - }); - - if ( !edgeChild ) - return false; - - updateSize( that, edgeChild ); - - return edgeBottom ? edgeChild.size.top > that.mouse.y : edgeChild.size.bottom < that.mouse.y; - } - - // This method handles edge cases: - // \-> Mouse is around upper or lower edge of view pane. - // \-> Also scroll position is either minimal or maximal. - // \-> It's OK to show LOOK_TOP(BOTTOM) type line. - // - // This trigger doesn't need additional post-filtering. - // - // +----------------------------- Editable -+ /-- - // | +---------------------- First child -+ | | <-- Top edge (first child) - // | | | | | - // | | | | | * Mouse activation area * - // | | | | | - // | | ... | | \-- Top edge + trigger offset - // | . . | - // | | - // | . . | - // | | ... | | /-- Bottom edge - trigger offset - // | | | | | - // | | | | | * Mouse activation area * - // | | | | | - // | +----------------------- Last child -+ | | <-- Bottom edge (last child) - // +----------------------------------------+ \-- - // - function triggerEditable( that ) { - that.debug.groupStart( 'triggerEditable' ); // %REMOVE_LINE% - - var editable = that.editable, - mouse = that.mouse, - view = that.view, - triggerOffset = that.triggerOffset, - triggerLook; - - // Update editable dimensions. - updateEditableSize( that ); - - // This flag determines whether checking bottom trigger. - var bottomTrigger = mouse.y > ( that.inInlineMode ? - view.editable.top + view.editable.height / 2 - : - // This is to handle case when editable.height / 2 <<< pane.height. - Math.min( view.editable.height, view.pane.height ) / 2 ), - - // Edge node according to bottomTrigger. - edgeNode = editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( function( node ) { - return !( isEmptyTextNode( node ) || isComment( node ) ); - }); - - // There's no edge node. Abort. - if ( !edgeNode ) { - that.debug.logEnd( 'ABORT. No edge node found.' ); // %REMOVE_LINE% - return null; - } - - // If the edgeNode in editable is ML, get the next one. - if ( isLine( that, edgeNode ) ) { - edgeNode = that.line.wrap[ bottomTrigger ? 'getPrevious' : 'getNext' ]( function( node ) { - return !( isEmptyTextNode( node ) || isComment( node ) ); - }); - } - - // Exclude bad nodes (no ML needed then): - // \-> Edge node is text. - // \-> Edge node is floated, etc. - // - // Edge node *must be* a valid trigger at this stage as well. - if ( !isHtml( edgeNode ) || isFlowBreaker( edgeNode ) || !isTrigger( that, edgeNode ) ) { - that.debug.logEnd( 'ABORT. Invalid edge node.' ); // %REMOVE_LINE% - return null; - } - - // Update size of edge node. Dimensions will be necessary. - updateSize( that, edgeNode ); - - // Return appropriate trigger according to bottomTrigger. - // \-> Top edge trigger case first. - if ( !bottomTrigger && // Top trigger case. - edgeNode.size.top >= 0 && // Check if the first element is fully visible. - inBetween( mouse.y, 0, edgeNode.size.top + triggerOffset ) ) { // Check if mouse in [0, edgeNode.top + triggerOffset]. - - // Determine trigger look. - triggerLook = that.inInlineMode || view.scroll.y === 0 ? - LOOK_TOP : LOOK_NORMAL; - - that.debug.logEnd( 'SUCCESS. Created box trigger. EDGE_TOP.' ); // %REMOVE_LINE% - - return new boxTrigger( [ null, edgeNode, - EDGE_TOP, - TYPE_EDGE, - triggerLook - ] ); - } - - // \-> Bottom case. - else if ( bottomTrigger && - edgeNode.size.bottom <= view.pane.height && // Check if the last element is fully visible - inBetween( mouse.y, // Check if mouse in... - edgeNode.size.bottom - triggerOffset, view.pane.height ) ) { // [ edgeNode.bottom - triggerOffset, paneHeight ] - - // Determine trigger look. - triggerLook = that.inInlineMode || - inBetween( edgeNode.size.bottom, view.pane.height - triggerOffset, view.pane.height ) ? - LOOK_BOTTOM : LOOK_NORMAL; - - that.debug.logEnd( 'SUCCESS. Created box trigger. EDGE_BOTTOM.' ); // %REMOVE_LINE% - - return new boxTrigger( [ edgeNode, null, - EDGE_BOTTOM, - TYPE_EDGE, - triggerLook - ] ); - } - - that.debug.logEnd( 'ABORT. No trigger created.' ); // %REMOVE_LINE% - return null; - } - - // This method covers cases *inside* of an element: - // \-> The pointer is in the top (bottom) area of an element and there's - // HTML node before (after) this element. - // \-> An element being the first or last child of its parent. - // - // +----------------------- Parent element -+ - // | +----------------------- Element #1 -+ | /-- - // | | | | | * Mouse activation area (as first child) * - // | | | | \-- - // | | | | /-- - // | | | | | * Mouse activation area (Element #2) * - // | +------------------------------------+ | \-- - // | | - // | +----------------------- Element #2 -+ | /-- - // | | | | | * Mouse activation area (Element #1) * - // | | | | \-- - // | | | | - // | +------------------------------------+ | - // | | - // | Text node is here. | - // | | - // | +----------------------- Element #3 -+ | - // | | | | - // | | | | - // | | | | /-- - // | | | | | * Mouse activation area (as last child) * - // | +------------------------------------+ | \-- - // +----------------------------------------+ - // - function triggerEdge( that ) { - that.debug.groupStart( 'triggerEdge' ); // %REMOVE_LINE% - - var mouse = that.mouse, - view = that.view, - triggerOffset = that.triggerOffset; - - // Get the ascendant trigger basing on elementFromMouse. - var element = getAscendantTrigger( that ); - - that.debug.logElements( [ element ], [ 'Ascendant trigger' ], 'First stage' ); // %REMOVE_LINE% - - // Abort if there's no appropriate element. - if ( !element ) { - that.debug.logEnd( 'ABORT. No element, element is editable or element contains editable.' ); // %REMOVE_LINE% - return null; - } - - // Dimensions will be necessary. - updateSize( that, element ); - - // If triggerOffset is larger than a half of element's height, - // use an offset of 1/2 of element's height. If the offset wasn't reduced, - // top area would cover most (all) cases. - var fixedOffset = Math.min( triggerOffset, - 0 | ( element.size.outerHeight / 2 ) ), - - // This variable will hold the trigger to be returned. - triggerSetup = [], - triggerLook, - - // This flag determines whether dealing with a bottom trigger. - bottomTrigger; - - // \-> Top trigger. - if ( inBetween( mouse.y, element.size.top - 1, element.size.top + fixedOffset ) ) - bottomTrigger = false; - // \-> Bottom trigger. - else if ( inBetween( mouse.y, element.size.bottom - fixedOffset, element.size.bottom + 1 ) ) - bottomTrigger = true; - // \-> Abort. Not in a valid trigger space. - else { - that.debug.logEnd( 'ABORT. Not around of any edge.' ); // %REMOVE_LINE% - return null; - } - - // Reject wrong elements. - // \-> Reject an element which is a flow breaker. - // \-> Reject an element which has a child above/below the mouse pointer. - // \-> Reject an element which belongs to list items. - if( isFlowBreaker( element ) || - isChildBetweenPointerAndEdge( that, element, bottomTrigger ) || - element.getParent().is( DTD_LISTITEM ) ) { - that.debug.logEnd( 'ABORT. element is wrong', element ); // %REMOVE_LINE% - return null; - } - - // Get sibling according to bottomTrigger. - var elementSibling = getNonEmptyNeighbour( that, element, !bottomTrigger ); - - // No sibling element. - // This is a first or last child case. - if ( !elementSibling ) { - // No need to reject the element as it has already been done before. - // Prepare a trigger. - - // Determine trigger look. - if ( element.equals( that.editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( that.isRelevant ) ) ) { - updateEditableSize( that ); - - if ( bottomTrigger && inBetween( mouse.y, - element.size.bottom - fixedOffset, view.pane.height ) && - inBetween( element.size.bottom, view.pane.height - fixedOffset, view.pane.height ) ) { - triggerLook = LOOK_BOTTOM; - } - else if ( inBetween( mouse.y, 0, element.size.top + fixedOffset ) ) { - triggerLook = LOOK_TOP; - } - } - else - triggerLook = LOOK_NORMAL; - - triggerSetup = [ null, element ][ bottomTrigger ? 'reverse' : 'concat' ]().concat( [ - bottomTrigger ? EDGE_BOTTOM : EDGE_TOP, - TYPE_EDGE, - triggerLook, - element.equals( that.editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( that.isRelevant ) ) ? - ( bottomTrigger ? LOOK_BOTTOM : LOOK_TOP ) : LOOK_NORMAL - ] ); - - that.debug.log( 'Configured edge trigger of ' + ( bottomTrigger ? 'EDGE_BOTTOM' : 'EDGE_TOP' ) ); // %REMOVE_LINE% - } - - // Abort. Sibling is a text element. - else if ( isTextNode( elementSibling ) ) { - that.debug.logEnd( 'ABORT. Sibling is non-empty text element' ); // %REMOVE_LINE% - return null; - } - - // Check if the sibling is a HTML element. - // If so, create an TYPE_EDGE, EDGE_MIDDLE trigger. - else if ( isHtml( elementSibling ) ) { - // Reject wrong elementSiblings. - // \-> Reject an elementSibling which is a flow breaker. - // \-> Reject an elementSibling which isn't a trigger. - // \-> Reject an elementSibling which belongs to list items. - if( isFlowBreaker( elementSibling ) || - !isTrigger( that, elementSibling ) || - elementSibling.getParent().is( DTD_LISTITEM ) ) { - that.debug.logEnd( 'ABORT. elementSibling is wrong', elementSibling ); // %REMOVE_LINE% - return null; - } - - // Prepare a trigger. - triggerSetup = [ elementSibling, element ][ bottomTrigger ? 'reverse' : 'concat' ]().concat( [ - EDGE_MIDDLE, - TYPE_EDGE - ] ); - - that.debug.log( 'Configured edge trigger of EDGE_MIDDLE' ); // %REMOVE_LINE% - } - - if ( 0 in triggerSetup ) { - that.debug.logEnd( 'SUCCESS. Returning a trigger.' ); // %REMOVE_LINE% - return new boxTrigger( triggerSetup ); - } - - that.debug.logEnd( 'ABORT. No trigger generated.' ); // %REMOVE_LINE% - return null; - } - - // Checks iteratively up and down in search for elements using elementFromMouse method. - // Useful if between two triggers. - // - // +----------------------- Parent element -+ - // | +----------------------- Element #1 -+ | - // | | | | - // | | | | - // | | | | - // | +------------------------------------+ | - // | | /-- - // | . | | - // | . +-- Floated -+ | | - // | | | | | | * Mouse activation area * - // | | | IGNORE | | | - // | X | | | | Method searches vertically for sibling elements. - // | | +------------+ | | Start point is X (mouse-y coordinate). - // | | | | Floated elements, comments and empty text nodes are omitted. - // | . | | - // | . | | - // | | \-- - // | +----------------------- Element #2 -+ | - // | | | | - // | | | | - // | | | | - // | | | | - // | +------------------------------------+ | - // +----------------------------------------+ - // - var triggerExpand = ( function() { - // The heart of the procedure. This method creates triggers that are - // filtered by expandFilter method. - function expandEngine( that ) { - that.debug.groupStart( 'expandEngine' ); // %REMOVE_LINE% - - var startElement = that.element, - upper, lower, trigger; - - if ( !isHtml( startElement ) || startElement.contains( that.editable ) ) { - that.debug.logEnd( 'ABORT. No start element, or start element contains editable.' ); // %REMOVE_LINE% - return null; - } - - trigger = verticalSearch( that, - function( current, startElement ) { - return !startElement.equals( current ); // stop when start element and the current one differ - }, function( that, mouse ) { - return elementFromMouse( that, true, mouse ); - }, startElement ), - - upper = trigger.upper, - lower = trigger.lower; - - that.debug.logElements( [ upper, lower ], [ 'Upper', 'Lower' ], 'Pair found' ); // %REMOVE_LINE% - - // Success: two siblings have been found - if ( areSiblings( that, upper, lower ) ) { - that.debug.logEnd( 'SUCCESS. Expand trigger created.' ); // %REMOVE_LINE% - return trigger.set( EDGE_MIDDLE, TYPE_EXPAND ); - } - - that.debug.logElements( [ startElement, upper, lower ], // %REMOVE_LINE% - [ 'Start', 'Upper', 'Lower' ], 'Post-processing' ); // %REMOVE_LINE% - - // Danger. Dragons ahead. - // No siblings have been found during previous phase, post-processing may be necessary. - // We can traverse DOM until a valid pair of elements around the pointer is found. - - // Prepare for post-processing: - // 1. Determine if upper and lower are children of startElement. - // 1.1. If so, find their ascendants that are closest to startElement (one level deeper than startElement). - // 1.2. Otherwise use first/last-child of the startElement as upper/lower. Why?: - // a) upper/lower belongs to another branch of the DOM tree. - // b) verticalSearch encountered an edge of the viewport and failed. - // 1.3. Make sure upper and lower still exist. Why?: - // a) Upper and lower may be not belong to the branch of the startElement (may not exist at all) and - // startElement has no children. - // 2. Perform the post-processing. - // 2.1. Gather dimensions of an upper element. - // 2.2. Abort if lower edge of upper is already under the mouse pointer. Why?: - // a) We expect upper to be above and lower below the mouse pointer. - // 3. Perform iterative search while upper != lower. - // 3.1. Find the upper-next element. If there's no such element, break current search. Why?: - // a) There's no point in further search if there are only text nodes ahead. - // 3.2. Calculate the distance between the middle point of ( upper, upperNext ) and mouse-y. - // 3.3. If the distance is shorter than the previous best, save it (save upper, upperNext as well). - // 3.4. If the optimal pair is found, assign it back to the trigger. - - // 1.1., 1.2. - if ( upper && startElement.contains( upper ) ) { - while ( !upper.getParent().equals( startElement ) ) - upper = upper.getParent(); - } else { - upper = startElement.getFirst( function( node ) { - return expandSelector( that, node ); - }); - } - - if ( lower && startElement.contains( lower ) ) { - while ( !lower.getParent().equals( startElement ) ) - lower = lower.getParent(); - } else { - lower = startElement.getLast( function( node ) { - return expandSelector( that, node ); - }); - } - - // 1.3. - if ( !upper || !lower ) { - that.debug.logEnd( 'ABORT. There is no upper or no lower element.' ); // %REMOVE_LINE% - return null; - } - - // 2.1. - updateSize( that, upper ); - updateSize( that, lower ); - - if ( !checkMouseBetweenElements( that, upper, lower ) ) { - that.debug.logEnd( 'ABORT. Mouse is already above upper or below lower.' ); // %REMOVE_LINE% - return null; - } - - var minDistance = Number.MAX_VALUE, - currentDistance, upperNext, minElement, minElementNext; - - while ( lower && !lower.equals( upper ) ) { - // 3.1. - if ( !( upperNext = upper.getNext( that.isRelevant ) ) ) - break; - - // 3.2. - currentDistance = Math.abs( getMidpoint( that, upper, upperNext ) - that.mouse.y ); - - // 3.3. - if ( currentDistance < minDistance ) { - minDistance = currentDistance; - minElement = upper; - minElementNext = upperNext; - } - - upper = upperNext; - updateSize( that, upper ); - } - - that.debug.logElements( [ minElement, minElementNext ], // %REMOVE_LINE% - [ 'Min', 'MinNext' ], 'Post-processing results' ); // %REMOVE_LINE% - - // 3.4. - if ( !minElement || !minElementNext ) { - that.debug.logEnd( 'ABORT. No Min or MinNext' ); // %REMOVE_LINE% - return null; - } - - if ( !checkMouseBetweenElements( that, minElement, minElementNext ) ) { - that.debug.logEnd( 'ABORT. Mouse is already above minElement or below minElementNext.' ); // %REMOVE_LINE% - return null; - } - - // An element of minimal distance has been found. Assign it to the trigger. - trigger.upper = minElement; - trigger.lower = minElementNext; - - // Success: post-processing revealed a pair of elements. - that.debug.logEnd( 'SUCCESSFUL post-processing. Trigger created.' ); // %REMOVE_LINE% - return trigger.set( EDGE_MIDDLE, TYPE_EXPAND ); - } - - // This is default element selector used by the engine. - function expandSelector( that, node ) { - return !( isTextNode( node ) - || isComment( node ) - || isFlowBreaker( node ) - || isLine( that, node ) - || ( node.type == CKEDITOR.NODE_ELEMENT && node.$ && node.is( 'br' ) ) ); - } - - // This method checks whether mouse-y is between the top edge of upper - // and bottom edge of lower. - // - // NOTE: This method assumes that updateSize has already been called - // for the elements and is up-to-date. - // - // +---------------------------- Upper -+ /-- - // | | | - // +------------------------------------+ | - // | - // ... | - // | - // X | * Return true for mouse-y in this range * - // | - // ... | - // | - // +---------------------------- Lower -+ | - // | | | - // +------------------------------------+ \-- - // - function checkMouseBetweenElements( that, upper, lower ) { - return inBetween( that.mouse.y, upper.size.top, lower.size.bottom ); - } - - // A method for trigger filtering. Accepts or rejects trigger pairs - // by their location in DOM etc. - function expandFilter( that, trigger ) { - that.debug.groupStart( 'expandFilter' ); // %REMOVE_LINE% - - var upper = trigger.upper, - lower = trigger.lower; - - if ( !upper || !lower // NOT: EDGE_MIDDLE trigger ALWAYS has two elements. - || isFlowBreaker( lower ) || isFlowBreaker( upper ) // NOT: one of the elements is floated or positioned - || lower.equals( upper ) || upper.equals( lower ) // NOT: two trigger elements, one equals another. - || lower.contains( upper ) || upper.contains( lower ) ) { // NOT: two trigger elements, one contains another. - that.debug.logEnd( 'REJECTED. No upper or no lower or they contain each other.' ); // %REMOVE_LINE% - - return false; - } - - // YES: two trigger elements, pure siblings. - else if ( isTrigger( that, upper ) && isTrigger( that, lower ) && areSiblings( that, upper, lower ) ) { - that.debug.logElementsEnd( [ upper, lower ], // %REMOVE_LINE% - [ 'upper', 'lower' ], 'APPROVED EDGE_MIDDLE' ); // %REMOVE_LINE% - - return true; - } - - that.debug.logElementsEnd( [ upper, lower ], // %REMOVE_LINE% - [ 'upper', 'lower' ], 'Rejected unknown pair' ); // %REMOVE_LINE% - - return false; - } - - // Simple wrapper for expandEngine and expandFilter. - return function( that ) { - that.debug.groupStart( 'triggerExpand' ); // %REMOVE_LINE% - - var trigger = expandEngine( that ); - - that.debug.groupEnd(); // %REMOVE_LINE% - return trigger && expandFilter( that, trigger ) ? trigger : null; - }; - })(); - - // Collects dimensions of an element. - var sizePrefixes = [ 'top', 'left', 'right', 'bottom' ]; - - function getSize( that, element, ignoreScroll, force ) { - var getStyle = (function() { - // Better "cache and reuse" than "call again and again". - var computed = env.ie ? element.$.currentStyle : that.win.$.getComputedStyle( element.$, '' ); - - return env.ie ? - function( propertyName ) { - return computed[ CKEDITOR.tools.cssStyleToDomStyle( propertyName ) ]; - } : function( propertyName ) { - return computed.getPropertyValue( propertyName ); - }; - })(), - docPosition = element.getDocumentPosition(), - border = {}, - margin = {}, - padding = {}, - box = {}; - - for ( var i = sizePrefixes.length; i--; ) { - border[ sizePrefixes[ i ] ] = parseInt( getStyle( 'border-' + sizePrefixes[ i ] + '-width' ), 10 ) || 0; - padding[ sizePrefixes[ i ] ] = parseInt( getStyle( 'padding-' + sizePrefixes[ i ] ), 10 ) || 0; - margin[ sizePrefixes[ i ] ] = parseInt( getStyle( 'margin-' + sizePrefixes[ i ] ), 10 ) || 0; - } - - // updateWindowSize if forced to do so OR NOT ignoring scroll. - if ( !ignoreScroll || force ) - updateWindowSize( that, force ); - - box.top = docPosition.y - ( ignoreScroll ? 0 : that.view.scroll.y ), box.left = docPosition.x - ( ignoreScroll ? 0 : that.view.scroll.x ), - - // w/ borders and paddings. - box.outerWidth = element.$.offsetWidth, box.outerHeight = element.$.offsetHeight, - - // w/o borders and paddings. - box.height = box.outerHeight - ( padding.top + padding.bottom + border.top + border.bottom ), box.width = box.outerWidth - ( padding.left + padding.right + border.left + border.right ), - - box.bottom = box.top + box.outerHeight, box.right = box.left + box.outerWidth; - - if ( that.inInlineMode ) { - box.scroll = { - top: element.$.scrollTop, - left: element.$.scrollLeft - }; - } - - return extend({ - border: border, - padding: padding, - margin: margin, - ignoreScroll: ignoreScroll - }, box, true ); - } - - function updateSize( that, element, ignoreScroll ) { - if ( !isHtml( element ) ) // i.e. an element is hidden - return ( element.size = null ); // -> reset size to make it useless for other methods - - if ( !element.size ) - element.size = {}; - - // Abort if there was a similar query performed recently. - // This kind of caching provides great performance improvement. - else if ( element.size.ignoreScroll == ignoreScroll && element.size.date > new Date() - CACHE_TIME ) { - that.debug.log( 'element.size: get from cache' ); // %REMOVE_LINE% - return null; - } - - that.debug.log( 'element.size: capture' ); // %REMOVE_LINE% - - return extend( element.size, getSize( that, element, ignoreScroll ), { - date: +new Date() - }, true ); - } - - // Updates that.view.editable object. - // This one must be called separately outside of updateWindowSize - // to prevent cyclic dependency getSize<->updateWindowSize. - // It calls getSize with force flag to avoid getWindowSize cache (look: getSize). - function updateEditableSize( that, ignoreScroll ) { - that.view.editable = getSize( that, that.editable, ignoreScroll, true ); - } - - function updateWindowSize( that, force ) { - if ( !that.view ) - that.view = {}; - - var view = that.view; - - if ( !force && view && view.date > new Date() - CACHE_TIME ) { - that.debug.log( 'win.size: get from cache' ); // %REMOVE_LINE% - return; - } - - that.debug.log( 'win.size: capturing' ); // %REMOVE_LINE% - - var win = that.win, - scroll = win.getScrollPosition(), - paneSize = win.getViewPaneSize(); - - extend( that.view, { - scroll: { - x: scroll.x, - y: scroll.y, - width: that.doc.$.documentElement.scrollWidth - paneSize.width, - height: that.doc.$.documentElement.scrollHeight - paneSize.height - }, - pane: { - width: paneSize.width, - height: paneSize.height, - bottom: paneSize.height + scroll.y - }, - date: +new Date() - }, true ); - } - - // This method searches document vertically using given - // select criterion until stop criterion is fulfilled. - function verticalSearch( that, stopCondition, selectCriterion, startElement ) { - var upper = startElement, - lower = startElement, - mouseStep = 0, - upperFound = false, - lowerFound = false, - viewPaneHeight = that.view.pane.height, - mouse = that.mouse; - - while ( mouse.y + mouseStep < viewPaneHeight && mouse.y - mouseStep > 0 ) { - if ( !upperFound ) - upperFound = stopCondition( upper, startElement ); - - if ( !lowerFound ) - lowerFound = stopCondition( lower, startElement ); - - // Still not found... - if ( !upperFound && mouse.y - mouseStep > 0 ) - upper = selectCriterion( that, { x: mouse.x, y: mouse.y - mouseStep } ); - - if ( !lowerFound && mouse.y + mouseStep < viewPaneHeight ) - lower = selectCriterion( that, { x: mouse.x, y: mouse.y + mouseStep } ); - - if ( upperFound && lowerFound ) - break; - - // Instead of ++ to reduce the number of invocations by half. - // It's trades off accuracy in some edge cases for improved performance. - mouseStep += 2; - } - - return new boxTrigger( [ upper, lower, null, null ] ); - } - -})(); - -/** - * Sets the default vertical distance between element edge and mouse pointer that - * causes the box to appear. The distance is expressed in pixels (px). - * - * // Changes the offset to 15px. - * CKEDITOR.config.magicline_triggerOffset = 15; - * - * @cfg {Number} [magicline_triggerOffset=30] - * @member CKEDITOR.config - * @see CKEDITOR.config#magicline_holdDistance - */ - -/** - * Defines the distance between mouse pointer and the box, within - * which the box stays revealed and no other focus space is offered to be accessed. - * The value is relative to {@link #magicline_triggerOffset}. - * - * // Increases the distance to 80% of CKEDITOR.config.magicline_triggerOffset. - * CKEDITOR.config.magicline_holdDistance = .8; - * - * @cfg {Number} [magicline_holdDistance=0.5] - * @member CKEDITOR.config - * @see CKEDITOR.config#magicline_triggerOffset - */ - -/** - * Defines default keystroke that access the closest unreachable focus space **before** - * the caret (start of the selection). If there's no any focus space, selection remains. - * - * // Changes keystroke to CTRL + , - * CKEDITOR.config.magicline_keystrokePrevious = CKEDITOR.CTRL + 188; - * - * @cfg {Number} [magicline_keystrokePrevious=CKEDITOR.CTRL + CKEDITOR.SHIFT + 219 (CTRL + SHIFT + [)] - * @member CKEDITOR.config - */ -CKEDITOR.config.magicline_keystrokePrevious = CKEDITOR.CTRL + CKEDITOR.SHIFT + 219; // CTRL + SHIFT + [ - -/** - * Defines default keystroke that access the closest unreachable focus space **after** - * the caret (start of the selection). If there's no any focus space, selection remains. - * - * // Changes keystroke to CTRL + . - * CKEDITOR.config.magicline_keystrokeNext = CKEDITOR.CTRL + 190; - * - * @cfg {Number} [magicline_keystrokeNext=CKEDITOR.CTRL + CKEDITOR.SHIFT + 221 (CTRL + SHIFT + ])] - * @member CKEDITOR.config - */ -CKEDITOR.config.magicline_keystrokeNext = CKEDITOR.CTRL + CKEDITOR.SHIFT + 221; // CTRL + SHIFT + ] - -/** - * Defines a list of attributes that, if assigned to some elements, prevent magicline from being - * used within these elements. - * - * // Adds "data-tabu" attribute to magicline tabu list. - * CKEDITOR.config.magicline_tabuList = [ 'data-tabu' ]; - * - * @cfg {Number} [magicline_tabuList=[ 'data-widget-wrapper' ]] - * @member CKEDITOR.config - */ - -/** - * Defines box color. The color may be adjusted to enhance readability. - * - * // Changes color to blue. - * CKEDITOR.config.magicline_color = '#0000FF'; - * - * @cfg {String} [magicline_color='#FF0000'] - * @member CKEDITOR.config - */ - -/** - * Activates plugin mode that considers all focus spaces between - * {@link CKEDITOR.dtd#$block} elements as accessible by the box. - * - * // Enables "put everywhere" mode. - * CKEDITOR.config.magicline_putEverywhere = true; - * - * @cfg {Boolean} [magicline_putEverywhere=false] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/maximize/icons/hidpi/maximize.png b/addons/website/static/lib/ckeditor/plugins/maximize/icons/hidpi/maximize.png Binary files differdeleted file mode 100644 index 1d1ed4559d1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/maximize/icons/hidpi/maximize.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/maximize/icons/maximize.png b/addons/website/static/lib/ckeditor/plugins/maximize/icons/maximize.png Binary files differdeleted file mode 100644 index db01908b8a8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/maximize/icons/maximize.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/maximize/lang/en.js b/addons/website/static/lib/ckeditor/plugins/maximize/lang/en.js deleted file mode 100644 index da43c27affd..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/maximize/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'maximize', 'en', { - maximize: 'Maximize', - minimize: 'Minimize' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/maximize/plugin.js b/addons/website/static/lib/ckeditor/plugins/maximize/plugin.js deleted file mode 100644 index 9d9b0749027..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/maximize/plugin.js +++ /dev/null @@ -1,305 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - function protectFormStyles( formElement ) { - if ( !formElement || formElement.type != CKEDITOR.NODE_ELEMENT || formElement.getName() != 'form' ) - return []; - - var hijackRecord = [], - hijackNames = [ 'style', 'className' ]; - for ( var i = 0; i < hijackNames.length; i++ ) { - var name = hijackNames[ i ]; - var $node = formElement.$.elements.namedItem( name ); - if ( $node ) { - var hijackNode = new CKEDITOR.dom.element( $node ); - hijackRecord.push( [ hijackNode, hijackNode.nextSibling ] ); - hijackNode.remove(); - } - } - - return hijackRecord; - } - - function restoreFormStyles( formElement, hijackRecord ) { - if ( !formElement || formElement.type != CKEDITOR.NODE_ELEMENT || formElement.getName() != 'form' ) - return; - - if ( hijackRecord.length > 0 ) { - for ( var i = hijackRecord.length - 1; i >= 0; i-- ) { - var node = hijackRecord[ i ][ 0 ]; - var sibling = hijackRecord[ i ][ 1 ]; - if ( sibling ) - node.insertBefore( sibling ); - else - node.appendTo( formElement ); - } - } - } - - function saveStyles( element, isInsideEditor ) { - var data = protectFormStyles( element ); - var retval = {}; - - var $element = element.$; - - if ( !isInsideEditor ) { - retval[ 'class' ] = $element.className || ''; - $element.className = ''; - } - - retval.inline = $element.style.cssText || ''; - if ( !isInsideEditor ) // Reset any external styles that might interfere. (#2474) - $element.style.cssText = 'position: static; overflow: visible'; - - restoreFormStyles( data ); - return retval; - } - - function restoreStyles( element, savedStyles ) { - var data = protectFormStyles( element ); - var $element = element.$; - if ( 'class' in savedStyles ) - $element.className = savedStyles[ 'class' ]; - if ( 'inline' in savedStyles ) - $element.style.cssText = savedStyles.inline; - restoreFormStyles( data ); - } - - function refreshCursor( editor ) { - if ( editor.editable().isInline() ) - return; - - // Refresh all editor instances on the page (#5724). - var all = CKEDITOR.instances; - for ( var i in all ) { - var one = all[ i ]; - if ( one.mode == 'wysiwyg' && !one.readOnly ) { - var body = one.document.getBody(); - // Refresh 'contentEditable' otherwise - // DOM lifting breaks design mode. (#5560) - body.setAttribute( 'contentEditable', false ); - body.setAttribute( 'contentEditable', true ); - } - } - - if ( editor.editable().hasFocus ) { - editor.toolbox.focus(); - editor.focus(); - } - } - - CKEDITOR.plugins.add( 'maximize', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'maximize', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - // Maximize plugin isn't available in inline mode yet. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - return; - - var lang = editor.lang; - var mainDocument = CKEDITOR.document, - mainWindow = mainDocument.getWindow(); - - // Saved selection and scroll position for the editing area. - var savedSelection, savedScroll; - - // Saved scroll position for the outer window. - var outerScroll; - - // Saved resize handler function. - function resizeHandler() { - var viewPaneSize = mainWindow.getViewPaneSize(); - editor.resize( viewPaneSize.width, viewPaneSize.height, null, true ); - } - - // Retain state after mode switches. - var savedState = CKEDITOR.TRISTATE_OFF; - - editor.addCommand( 'maximize', { - // Disabled on iOS (#8307). - modes: { wysiwyg: !CKEDITOR.env.iOS, source: !CKEDITOR.env.iOS }, - readOnly: 1, - editorFocus: false, - exec: function() { - var container = editor.container.getChild( 1 ); - var contents = editor.ui.space( 'contents' ); - - // Save current selection and scroll position in editing area. - if ( editor.mode == 'wysiwyg' ) { - var selection = editor.getSelection(); - savedSelection = selection && selection.getRanges(); - savedScroll = mainWindow.getScrollPosition(); - } else { - var $textarea = editor.editable().$; - savedSelection = !CKEDITOR.env.ie && [ $textarea.selectionStart, $textarea.selectionEnd ]; - savedScroll = [ $textarea.scrollLeft, $textarea.scrollTop ]; - } - - if ( this.state == CKEDITOR.TRISTATE_OFF ) // Go fullscreen if the state is off. - { - // Add event handler for resizing. - mainWindow.on( 'resize', resizeHandler ); - - // Save the scroll bar position. - outerScroll = mainWindow.getScrollPosition(); - - // Save and reset the styles for the entire node tree. - var currentNode = editor.container; - while ( ( currentNode = currentNode.getParent() ) ) { - currentNode.setCustomData( 'maximize_saved_styles', saveStyles( currentNode ) ); - // Show under floatpanels (-1) and context menu (-2). - currentNode.setStyle( 'z-index', editor.config.baseFloatZIndex - 5 ); - } - contents.setCustomData( 'maximize_saved_styles', saveStyles( contents, true ) ); - container.setCustomData( 'maximize_saved_styles', saveStyles( container, true ) ); - - // Hide scroll bars. - var styles = { - overflow: CKEDITOR.env.webkit ? '' : 'hidden', // #6896 - width: 0, - height: 0 - }; - - mainDocument.getDocumentElement().setStyles( styles ); - !CKEDITOR.env.gecko && mainDocument.getDocumentElement().setStyle( 'position', 'fixed' ); - !( CKEDITOR.env.gecko && CKEDITOR.env.quirks ) && mainDocument.getBody().setStyles( styles ); - - // Scroll to the top left (IE needs some time for it - #4923). - CKEDITOR.env.ie ? setTimeout( function() { - mainWindow.$.scrollTo( 0, 0 ); - }, 0 ) : mainWindow.$.scrollTo( 0, 0 ); - - // Resize and move to top left. - // Special treatment for FF Quirks (#7284) - container.setStyle( 'position', CKEDITOR.env.gecko && CKEDITOR.env.quirks ? 'fixed' : 'absolute' ); - container.$.offsetLeft; // SAFARI BUG: See #2066. - container.setStyles({ - // Show under floatpanels (-1) and context menu (-2). - 'z-index': editor.config.baseFloatZIndex - 5, - left: '0px', - top: '0px' - }); - - // Add cke_maximized class before resize handle since that will change things sizes (#5580) - container.addClass( 'cke_maximized' ); - - resizeHandler(); - - // Still not top left? Fix it. (Bug #174) - var offset = container.getDocumentPosition(); - container.setStyles({ - left: ( -1 * offset.x ) + 'px', - top: ( -1 * offset.y ) + 'px' - }); - - // Fixing positioning editor chrome in Firefox break design mode. (#5149) - CKEDITOR.env.gecko && refreshCursor( editor ); - - } else if ( this.state == CKEDITOR.TRISTATE_ON ) // Restore from fullscreen if the state is on. - { - // Remove event handler for resizing. - mainWindow.removeListener( 'resize', resizeHandler ); - - // Restore CSS styles for the entire node tree. - var editorElements = [ contents, container ]; - for ( var i = 0; i < editorElements.length; i++ ) { - restoreStyles( editorElements[ i ], editorElements[ i ].getCustomData( 'maximize_saved_styles' ) ); - editorElements[ i ].removeCustomData( 'maximize_saved_styles' ); - } - - currentNode = editor.container; - while ( ( currentNode = currentNode.getParent() ) ) { - restoreStyles( currentNode, currentNode.getCustomData( 'maximize_saved_styles' ) ); - currentNode.removeCustomData( 'maximize_saved_styles' ); - } - - // Restore the window scroll position. - CKEDITOR.env.ie ? setTimeout( function() { - mainWindow.$.scrollTo( outerScroll.x, outerScroll.y ); - }, 0 ) : mainWindow.$.scrollTo( outerScroll.x, outerScroll.y ); - - // Remove cke_maximized class. - container.removeClass( 'cke_maximized' ); - - // Webkit requires a re-layout on editor chrome. (#6695) - if ( CKEDITOR.env.webkit ) { - container.setStyle( 'display', 'inline' ); - setTimeout( function() { - container.setStyle( 'display', 'block' ); - }, 0 ); - } - - // Emit a resize event, because this time the size is modified in - // restoreStyles. - editor.fire( 'resize' ); - } - - this.toggleState(); - - // Toggle button label. - var button = this.uiItems[ 0 ]; - // Only try to change the button if it exists (#6166) - if ( button ) { - var label = ( this.state == CKEDITOR.TRISTATE_OFF ) ? lang.maximize.maximize : lang.maximize.minimize; - var buttonNode = CKEDITOR.document.getById( button._.id ); - buttonNode.getChild( 1 ).setHtml( label ); - buttonNode.setAttribute( 'title', label ); - buttonNode.setAttribute( 'href', 'javascript:void("' + label + '");' ); - } - - // Restore selection and scroll position in editing area. - if ( editor.mode == 'wysiwyg' ) { - if ( savedSelection ) { - // Fixing positioning editor chrome in Firefox break design mode. (#5149) - CKEDITOR.env.gecko && refreshCursor( editor ); - - editor.getSelection().selectRanges( savedSelection ); - var element = editor.getSelection().getStartElement(); - element && element.scrollIntoView( true ); - } else - mainWindow.$.scrollTo( savedScroll.x, savedScroll.y ); - } else { - if ( savedSelection ) { - $textarea.selectionStart = savedSelection[ 0 ]; - $textarea.selectionEnd = savedSelection[ 1 ]; - } - $textarea.scrollLeft = savedScroll[ 0 ]; - $textarea.scrollTop = savedScroll[ 1 ]; - } - - savedSelection = savedScroll = null; - savedState = this.state; - - editor.fire( 'maximize', this.state ); - }, - canUndo: false - }); - - editor.ui.addButton && editor.ui.addButton( 'Maximize', { - label: lang.maximize.maximize, - command: 'maximize', - toolbar: 'tools,10' - }); - - // Restore the command state after mode change, unless it has been changed to disabled (#6467) - editor.on( 'mode', function() { - var command = editor.getCommand( 'maximize' ); - command.setState( command.state == CKEDITOR.TRISTATE_DISABLED ? CKEDITOR.TRISTATE_DISABLED : savedState ); - }, null, null, 100 ); - } - }); -})(); - -/** - * Event fired when the maximize command is called. - * It also indicates whether an editor is maximized or not. - * - * @event maximize - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {Number} data Current state of the command. See {@link CKEDITOR#TRISTATE_ON} and {@link CKEDITOR#TRISTATE_OFF}. - */
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/menu/plugin.js b/addons/website/static/lib/ckeditor/plugins/menu/plugin.js deleted file mode 100644 index 385ab9b3d4a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/menu/plugin.js +++ /dev/null @@ -1,504 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'menu', { - requires: 'floatpanel', - - beforeInit: function( editor ) { - var groups = editor.config.menu_groups.split( ',' ), - groupsOrder = editor._.menuGroups = {}, - menuItems = editor._.menuItems = {}; - - for ( var i = 0; i < groups.length; i++ ) - groupsOrder[ groups[ i ] ] = i + 1; - - /** - * Registers an item group to the editor context menu in order to make it - * possible to associate it with menu items later. - * - * @param {String} name Specify a group name. - * @param {Number} [order=100] Define the display sequence of this group - * inside the menu. A smaller value gets displayed first. - * @member CKEDITOR.editor - */ - editor.addMenuGroup = function( name, order ) { - groupsOrder[ name ] = order || 100; - }; - - /** - * Adds an item from the specified definition to the editor context menu. - * - * @method - * @param {String} name The menu item name. - * @param {Object} definition The menu item definition. - * @member CKEDITOR.editor - */ - editor.addMenuItem = function( name, definition ) { - if ( groupsOrder[ definition.group ] ) - menuItems[ name ] = new CKEDITOR.menuItem( this, name, definition ); - }; - - /** - * Adds one or more items from the specified definition array to the editor context menu. - * - * @method - * @param {Array} definitions List of definitions for each menu item as if {@link #addMenuItem} is called. - * @member CKEDITOR.editor - */ - editor.addMenuItems = function( definitions ) { - for ( var itemName in definitions ) { - this.addMenuItem( itemName, definitions[ itemName ] ); - } - }; - - /** - * Retrieves a particular menu item definition from the editor context menu. - * - * @method - * @param {String} name The name of the desired menu item. - * @returns {Object} - * @member CKEDITOR.editor - */ - editor.getMenuItem = function( name ) { - return menuItems[ name ]; - }; - - /** - * Removes a particular menu item added before from the editor context menu. - * - * @since 3.6.1 - * @method - * @param {String} name The name of the desired menu item. - * @member CKEDITOR.editor - */ - editor.removeMenuItem = function( name ) { - delete menuItems[ name ]; - }; - } -}); - -(function() { - var menuItemSource = '<span class="cke_menuitem">' + - '<a id="{id}"' + - ' class="cke_menubutton cke_menubutton__{name} cke_menubutton_{state} {cls}" href="{href}"' + - ' title="{title}"' + - ' tabindex="-1"' + - '_cke_focus=1' + - ' hidefocus="true"' + - ' role="menuitem"' + - ' aria-haspopup="{hasPopup}"' + - ' aria-disabled="{disabled}"'; - - // Some browsers don't cancel key events in the keydown but in the - // keypress. - // TODO: Check if really needed for Gecko+Mac. - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - menuItemSource += ' onkeypress="return false;"'; - - // With Firefox, we need to force the button to redraw, otherwise it - // will remain in the focus state. - if ( CKEDITOR.env.gecko ) - menuItemSource += ' onblur="this.style.cssText = this.style.cssText;"'; - - // #188 - menuItemSource += ' onmouseover="CKEDITOR.tools.callFunction({hoverFn},{index});"' + - ' onmouseout="CKEDITOR.tools.callFunction({moveOutFn},{index});" ' + - ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + - '="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' + - '>'; - - menuItemSource += - '<span class="cke_menubutton_inner">' + - '<span class="cke_menubutton_icon">' + - '<span class="cke_button_icon cke_button__{iconName}_icon" style="{iconStyle}"></span>' + - '</span>' + - '<span class="cke_menubutton_label">' + - '{label}' + - '</span>' + - '{arrowHtml}' + - '</span>' + - '</a></span>'; - - var menuArrowSource = '<span class="cke_menuarrow">' + - '<span>{label}</span>' + - '</span>'; - - var menuItemTpl = CKEDITOR.addTemplate( 'menuItem', menuItemSource ), - menuArrowTpl = CKEDITOR.addTemplate( 'menuArrow', menuArrowSource ); - - /** - * @class - * @todo - */ - CKEDITOR.menu = CKEDITOR.tools.createClass({ - $: function( editor, definition ) { - definition = this._.definition = definition || {}; - this.id = CKEDITOR.tools.getNextId(); - - this.editor = editor; - this.items = []; - this._.listeners = []; - - this._.level = definition.level || 1; - - var panelDefinition = CKEDITOR.tools.extend( {}, definition.panel, { - css: [ CKEDITOR.skin.getPath( 'editor' ) ], - level: this._.level - 1, - block: {} - }); - - var attrs = panelDefinition.block.attributes = ( panelDefinition.attributes || {} ); - // Provide default role of 'menu'. - !attrs.role && ( attrs.role = 'menu' ); - this._.panelDefinition = panelDefinition; - }, - - _: { - onShow: function() { - var selection = this.editor.getSelection(), - start = selection && selection.getStartElement(), - path = this.editor.elementPath(), - listeners = this._.listeners; - - this.removeAll(); - // Call all listeners, filling the list of items to be displayed. - for ( var i = 0; i < listeners.length; i++ ) { - var listenerItems = listeners[ i ]( start, selection, path ); - - if ( listenerItems ) { - for ( var itemName in listenerItems ) { - var item = this.editor.getMenuItem( itemName ); - - if ( item && ( !item.command || this.editor.getCommand( item.command ).state ) ) { - item.state = listenerItems[ itemName ]; - this.add( item ); - } - } - } - } - }, - - onClick: function( item ) { - this.hide(); - - if ( item.onClick ) - item.onClick(); - else if ( item.command ) - this.editor.execCommand( item.command ); - }, - - onEscape: function( keystroke ) { - var parent = this.parent; - // 1. If it's sub-menu, close it, with focus restored on this. - // 2. In case of a top-menu, close it, with focus returned to page. - if ( parent ) - parent._.panel.hideChild( 1 ); - else if ( keystroke == 27 ) - this.hide( 1 ); - - return false; - }, - - onHide: function() { - this.onHide && this.onHide(); - }, - - showSubMenu: function( index ) { - var menu = this._.subMenu, - item = this.items[ index ], - subItemDefs = item.getItems && item.getItems(); - - // If this item has no subitems, we just hide the submenu, if - // available, and return back. - if ( !subItemDefs ) { - // Hide sub menu with focus returned. - this._.panel.hideChild( 1 ); - return; - } - - // Create the submenu, if not available, or clean the existing - // one. - if ( menu ) - menu.removeAll(); - else { - menu = this._.subMenu = new CKEDITOR.menu( this.editor, CKEDITOR.tools.extend( {}, this._.definition, { level: this._.level + 1 }, true ) ); - menu.parent = this; - menu._.onClick = CKEDITOR.tools.bind( this._.onClick, this ); - } - - // Add all submenu items to the menu. - for ( var subItemName in subItemDefs ) { - var subItem = this.editor.getMenuItem( subItemName ); - if ( subItem ) { - subItem.state = subItemDefs[ subItemName ]; - menu.add( subItem ); - } - } - - // Get the element representing the current item. - var element = this._.panel.getBlock( this.id ).element.getDocument().getById( this.id + String( index ) ); - - // Show the submenu. - // This timeout is needed to give time for the sub-menu get - // focus when JAWS is running. (#9844) - setTimeout( function() { - menu.show( element, 2 ); - },0); - } - }, - - proto: { - add: function( item ) { - // Later we may sort the items, but Array#sort is not stable in - // some browsers, here we're forcing the original sequence with - // 'order' attribute if it hasn't been assigned. (#3868) - if ( !item.order ) - item.order = this.items.length; - - this.items.push( item ); - }, - - removeAll: function() { - this.items = []; - }, - - show: function( offsetParent, corner, offsetX, offsetY ) { - // Not for sub menu. - if ( !this.parent ) { - this._.onShow(); - // Don't menu with zero items. - if ( !this.items.length ) - return; - } - - corner = corner || ( this.editor.lang.dir == 'rtl' ? 2 : 1 ); - - var items = this.items, - editor = this.editor, - panel = this._.panel, - element = this._.element; - - // Create the floating panel for this menu. - if ( !panel ) { - panel = this._.panel = new CKEDITOR.ui.floatPanel( this.editor, CKEDITOR.document.getBody(), this._.panelDefinition, this._.level ); - - panel.onEscape = CKEDITOR.tools.bind( function( keystroke ) { - if ( this._.onEscape( keystroke ) === false ) - return false; - }, this ); - - panel.onShow = function() { - // Menu need CSS resets, compensate class name. - var holder = panel._.panel.getHolderElement(); - holder.getParent().addClass( 'cke cke_reset_all' ); - }; - - panel.onHide = CKEDITOR.tools.bind( function() { - this._.onHide && this._.onHide(); - }, this ); - - // Create an autosize block inside the panel. - var block = panel.addBlock( this.id, this._.panelDefinition.block ); - block.autoSize = true; - - var keys = block.keys; - keys[ 40 ] = 'next'; // ARROW-DOWN - keys[ 9 ] = 'next'; // TAB - keys[ 38 ] = 'prev'; // ARROW-UP - keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB - keys[ ( editor.lang.dir == 'rtl' ? 37 : 39 ) ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // ARROW-RIGHT/ARROW-LEFT(rtl) - keys[ 32 ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // SPACE - CKEDITOR.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (#8041). - - element = this._.element = block.element; - - var elementDoc = element.getDocument(); - elementDoc.getBody().setStyle( 'overflow', 'hidden' ); - elementDoc.getElementsByTag( 'html' ).getItem( 0 ).setStyle( 'overflow', 'hidden' ); - - this._.itemOverFn = CKEDITOR.tools.addFunction( function( index ) { - clearTimeout( this._.showSubTimeout ); - this._.showSubTimeout = CKEDITOR.tools.setTimeout( this._.showSubMenu, editor.config.menu_subMenuDelay || 400, this, [ index ] ); - }, this ); - - this._.itemOutFn = CKEDITOR.tools.addFunction( function( index ) { - clearTimeout( this._.showSubTimeout ); - }, this ); - - this._.itemClickFn = CKEDITOR.tools.addFunction( function( index ) { - var item = this.items[ index ]; - - if ( item.state == CKEDITOR.TRISTATE_DISABLED ) { - this.hide( 1 ); - return; - } - - if ( item.getItems ) - this._.showSubMenu( index ); - else - this._.onClick( item ); - }, this ); - } - - // Put the items in the right order. - sortItems( items ); - - // Apply the editor mixed direction status to menu. - var path = editor.elementPath(), - mixedDirCls = ( path && path.direction() != editor.lang.dir ) ? ' cke_mixed_dir_content' : ''; - - // Build the HTML that composes the menu and its items. - var output = [ '<div class="cke_menu' + mixedDirCls + '" role="presentation">' ]; - - var length = items.length, - lastGroup = length && items[ 0 ].group; - - for ( var i = 0; i < length; i++ ) { - var item = items[ i ]; - if ( lastGroup != item.group ) { - output.push( '<div class="cke_menuseparator" role="separator"></div>' ); - lastGroup = item.group; - } - - item.render( this, i, output ); - } - - output.push( '</div>' ); - - // Inject the HTML inside the panel. - element.setHtml( output.join( '' ) ); - - CKEDITOR.ui.fire( 'ready', this ); - - // Show the panel. - if ( this.parent ) - this.parent._.panel.showAsChild( panel, this.id, offsetParent, corner, offsetX, offsetY ); - else - panel.showBlock( this.id, offsetParent, corner, offsetX, offsetY ); - - editor.fire( 'menuShow', [ panel ] ); - }, - - addListener: function( listenerFn ) { - this._.listeners.push( listenerFn ); - }, - - hide: function( returnFocus ) { - this._.onHide && this._.onHide(); - this._.panel && this._.panel.hide( returnFocus ); - } - } - }); - - function sortItems( items ) { - items.sort( function( itemA, itemB ) { - if ( itemA.group < itemB.group ) - return -1; - else if ( itemA.group > itemB.group ) - return 1; - - return itemA.order < itemB.order ? -1 : itemA.order > itemB.order ? 1 : 0; - }); - } - - /** - * @class - * @todo - */ - CKEDITOR.menuItem = CKEDITOR.tools.createClass({ - $: function( editor, name, definition ) { - CKEDITOR.tools.extend( this, definition, - // Defaults - { - order: 0, - className: 'cke_menubutton__' + name - }); - - // Transform the group name into its order number. - this.group = editor._.menuGroups[ this.group ]; - - this.editor = editor; - this.name = name; - }, - - proto: { - render: function( menu, index, output ) { - var id = menu.id + String( index ), - state = ( typeof this.state == 'undefined' ) ? CKEDITOR.TRISTATE_OFF : this.state; - - var stateName = state == CKEDITOR.TRISTATE_ON ? 'on' : state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off'; - - var hasSubMenu = this.getItems; - // ltr: BLACK LEFT-POINTING POINTER - // rtl: BLACK RIGHT-POINTING POINTER - var arrowLabel = '&#' + ( this.editor.lang.dir == 'rtl' ? '9668' : '9658' ) + ';'; - - var iconName = this.name; - if ( this.icon && !( /\./ ).test( this.icon ) ) - iconName = this.icon; - - var params = { - id: id, - name: this.name, - iconName: iconName, - label: this.label, - cls: this.className || '', - state: stateName, - hasPopup: hasSubMenu ? 'true' : 'false', - disabled: state == CKEDITOR.TRISTATE_DISABLED, - title: this.label, - href: 'javascript:void(\'' + ( this.label || '' ).replace( "'" + '' ) + '\')', - hoverFn: menu._.itemOverFn, - moveOutFn: menu._.itemOutFn, - clickFn: menu._.itemClickFn, - index: index, - iconStyle: CKEDITOR.skin.getIconStyle( iconName, ( this.editor.lang.dir == 'rtl' ), iconName == this.icon ? null : this.icon, this.iconOffset ), - arrowHtml: hasSubMenu ? menuArrowTpl.output({ label: arrowLabel } ) : '' - }; - - menuItemTpl.output( params, output ); - } - } - }); - -})(); - - -/** - * The amount of time, in milliseconds, the editor waits before displaying submenu - * options when moving the mouse over options that contain submenus, like the - * "Cell Properties" entry for tables. - * - * // Remove the submenu delay. - * config.menu_subMenuDelay = 0; - * - * @cfg {Number} [menu_subMenuDelay=400] - * @member CKEDITOR.config - */ - -/** - * Fired when a menu is shown. - * - * @event menuShow - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {CKEDITOR.ui.panel[]} data - */ - -/** - * A comma separated list of items group names to be displayed in the context - * menu. The order of items will reflect the order specified in this list if - * no priority was defined in the groups. - * - * config.menu_groups = 'clipboard,table,anchor,link,image'; - * - * @cfg {String} [menu_groups=see source] - * @member CKEDITOR.config - */ -CKEDITOR.config.menu_groups = 'clipboard,' + - 'form,' + - 'tablecell,tablecellproperties,tablerow,tablecolumn,table,' + - 'anchor,link,image,flash,' + - 'checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div'; diff --git a/addons/website/static/lib/ckeditor/plugins/menubutton/plugin.js b/addons/website/static/lib/ckeditor/plugins/menubutton/plugin.js deleted file mode 100644 index affdf559722..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/menubutton/plugin.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'menubutton', { - requires: 'button,menu', - onLoad: function() { - var clickFn = function( editor ) { - var _ = this._; - - // Do nothing if this button is disabled. - if ( _.state === CKEDITOR.TRISTATE_DISABLED ) - return; - - _.previousState = _.state; - - // Check if we already have a menu for it, otherwise just create it. - var menu = _.menu; - if ( !menu ) { - menu = _.menu = new CKEDITOR.menu( editor, { - panel: { - className: 'cke_menu_panel', - attributes: { 'aria-label': editor.lang.common.options } - } - }); - - menu.onHide = CKEDITOR.tools.bind( function() { - this.setState( this.modes && this.modes[ editor.mode ] ? _.previousState : CKEDITOR.TRISTATE_DISABLED ); - }, this ); - - // Initialize the menu items at this point. - if ( this.onMenu ) - menu.addListener( this.onMenu ); - } - - if ( _.on ) { - menu.hide(); - return; - } - - this.setState( CKEDITOR.TRISTATE_ON ); - - // This timeout is needed to give time for the panel get focus - // when JAWS is running. (#9842) - setTimeout( function() { - menu.show( CKEDITOR.document.getById( _.id ), 4 ); - },0); - }; - - /** - * @class - * @extends CKEDITOR.ui.button - * @todo - */ - CKEDITOR.ui.menuButton = CKEDITOR.tools.createClass({ - base: CKEDITOR.ui.button, - - /** - * Creates a menuButton class instance. - * - * @constructor - * @param Object definition - * @todo - */ - $: function( definition ) { - // We don't want the panel definition in this object. - var panelDefinition = definition.panel; - delete definition.panel; - - this.base( definition ); - - this.hasArrow = true; - - this.click = clickFn; - }, - - statics: { - handler: { - create: function( definition ) { - return new CKEDITOR.ui.menuButton( definition ); - } - } - } - }); - }, - beforeInit: function( editor ) { - editor.ui.addHandler( CKEDITOR.UI_MENUBUTTON, CKEDITOR.ui.menuButton.handler ); - } -}); - -/** - * Button UI element. - * - * @readonly - * @property {String} [='menubutton'] - * @member CKEDITOR - */ -CKEDITOR.UI_MENUBUTTON = 'menubutton'; diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage-rtl.png b/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage-rtl.png Binary files differdeleted file mode 100644 index 1a7551c2a88..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage.png b/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage.png Binary files differdeleted file mode 100644 index 8cbe223059b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/icons/hidpi/newpage.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage-rtl.png b/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage-rtl.png Binary files differdeleted file mode 100644 index 2c8ef7fe6fc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage.png b/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage.png Binary files differdeleted file mode 100644 index 8e18c8a2dcc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/icons/newpage.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/lang/en.js b/addons/website/static/lib/ckeditor/plugins/newpage/lang/en.js deleted file mode 100644 index 28cd1633f83..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'newpage', 'en', { - toolbar: 'New Page' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/newpage/plugin.js b/addons/website/static/lib/ckeditor/plugins/newpage/plugin.js deleted file mode 100644 index dbbcc9c0b18..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/newpage/plugin.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Horizontal Page Break. - */ - -// Register a plugin named "newpage". -CKEDITOR.plugins.add( 'newpage', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'newpage,newpage-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.addCommand( 'newpage', { modes:{wysiwyg:1,source:1 }, - - exec: function( editor ) { - var command = this; - editor.setData( editor.config.newpage_html || '', function() { - editor.focus(); - // Save the undo snapshot after all document changes are affected. (#4889) - setTimeout( function() { - editor.fire( 'afterCommandExec', { - name: 'newpage', - command: command - }); - editor.selectionChange(); - - }, 200 ); - }); - }, - async: true - }); - - editor.ui.addButton && editor.ui.addButton( 'NewPage', { - label: editor.lang.newpage.toolbar, - command: 'newpage', - toolbar: 'document,20' - }); - } -}); - -/** - * The HTML to load in the editor when the "new page" command is executed. - * - * config.newpage_html = '<p>Type your text here.</p>'; - * - * @cfg {String} [newpage_html=''] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak-rtl.png b/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak-rtl.png Binary files differdeleted file mode 100644 index 4a5418cbfc8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak.png b/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak.png Binary files differdeleted file mode 100644 index 8d3930bbeb5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/hidpi/pagebreak.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak-rtl.png b/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak-rtl.png Binary files differdeleted file mode 100644 index b5b342b09ff..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak.png b/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak.png Binary files differdeleted file mode 100644 index 5280a6e97a8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/icons/pagebreak.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/lang/en.js b/addons/website/static/lib/ckeditor/plugins/pagebreak/lang/en.js deleted file mode 100644 index 5e1c0512f43..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'pagebreak', 'en', { - alt: 'Page Break', - toolbar: 'Insert Page Break for Printing' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/pagebreak/plugin.js b/addons/website/static/lib/ckeditor/plugins/pagebreak/plugin.js deleted file mode 100644 index 9339e34d77c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pagebreak/plugin.js +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Horizontal Page Break - */ - -// Register a plugin named "pagebreak". -CKEDITOR.plugins.add( 'pagebreak', { - requires: 'fakeobjects', - - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'pagebreak,pagebreak-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - var cssStyles = [ - '{', - 'background: url(' + CKEDITOR.getUrl( this.path + 'images/pagebreak.gif' ) + ') no-repeat center center;', - 'clear: both;', - 'width:100%; _width:99.9%;', - 'border-top: #999999 1px dotted;', - 'border-bottom: #999999 1px dotted;', - 'padding:0;', - 'height: 5px;', - 'cursor: default;', - '}' - ].join( '' ).replace( /;/g, ' !important;' ); // Increase specificity to override other styles, e.g. block outline. - - // Add the style that renders our placeholder. - CKEDITOR.addCss( 'div.cke_pagebreak' + cssStyles ); - }, - init: function( editor ) { - if ( editor.blockless ) - return; - - // Register the command. - editor.addCommand( 'pagebreak', CKEDITOR.plugins.pagebreakCmd ); - - // Register the toolbar button. - editor.ui.addButton && editor.ui.addButton( 'PageBreak', { - label: editor.lang.pagebreak.toolbar, - command: 'pagebreak', - toolbar: 'insert,70' - }); - - // Opera needs help to select the page-break. - CKEDITOR.env.opera && editor.on( 'contentDom', function() { - editor.document.on( 'click', function( evt ) { - var target = evt.data.getTarget(); - if ( target.is( 'div' ) && target.hasClass( 'cke_pagebreak' ) ) - editor.getSelection().selectElement( target ); - }); - }); - }, - - afterInit: function( editor ) { - var label = editor.lang.pagebreak.alt; - - // Register a filter to displaying placeholders after mode change. - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter, - htmlFilter = dataProcessor && dataProcessor.htmlFilter; - - if ( htmlFilter ) { - htmlFilter.addRules({ - attributes: { - 'class': function( value, element ) { - var className = value.replace( 'cke_pagebreak', '' ); - if ( className != value ) { - var span = CKEDITOR.htmlParser.fragment.fromHtml( '<span style="display: none;"> </span>' ).children[ 0 ]; - element.children.length = 0; - element.add( span ); - var attrs = element.attributes; - delete attrs[ 'aria-label' ]; - delete attrs.contenteditable; - delete attrs.title; - } - return className; - } - } - }, 5 ); - } - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - div: function( element ) { - var attributes = element.attributes, - style = attributes && attributes.style, - child = style && element.children.length == 1 && element.children[ 0 ], - childStyle = child && ( child.name == 'span' ) && child.attributes.style; - - if ( childStyle && ( /page-break-after\s*:\s*always/i ).test( style ) && ( /display\s*:\s*none/i ).test( childStyle ) ) { - attributes.contenteditable = "false"; - attributes[ 'class' ] = "cke_pagebreak"; - attributes[ 'data-cke-display-name' ] = "pagebreak"; - attributes[ 'aria-label' ] = label; - attributes[ 'title' ] = label; - - element.children.length = 0; - } - } - } - }); - } - } -}); - -// TODO Much probably there's no need to expose this object as public object. - -CKEDITOR.plugins.pagebreakCmd = { - exec: function( editor ) { - var label = editor.lang.pagebreak.alt; - - // Create read-only element that represents a print break. - var pagebreak = CKEDITOR.dom.element.createFromHtml( '<div style="' + - 'page-break-after: always;"' + - 'contenteditable="false" ' + - 'title="' + label + '" ' + - 'aria-label="' + label + '" ' + - 'data-cke-display-name="pagebreak" ' + - 'class="cke_pagebreak">' + - '</div>', editor.document ); - - editor.insertElement( pagebreak ); - }, - context: 'div', - allowedContent: { - div: { - styles: '!page-break-after' - }, - span: { - match: function( element ) { - var parent = element.parent; - return parent && parent.name == 'div' && parent.styles[ 'page-break-after' ]; - }, - styles: 'display' - } - }, - requiredContent: 'div{page-break-after}' -}; diff --git a/addons/website/static/lib/ckeditor/plugins/panel/plugin.js b/addons/website/static/lib/ckeditor/plugins/panel/plugin.js deleted file mode 100644 index 633ca4a69b7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/panel/plugin.js +++ /dev/null @@ -1,394 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.add( 'panel', { - beforeInit: function( editor ) { - editor.ui.addHandler( CKEDITOR.UI_PANEL, CKEDITOR.ui.panel.handler ); - } - }); - - /** - * Panel UI element. - * - * @readonly - * @property {String} [='panel'] - * @member CKEDITOR - */ - CKEDITOR.UI_PANEL = 'panel'; - - /** - * @class - * @constructor Creates a panel class instance. - * @param {CKEDITOR.dom.document} document - * @param {Object} definition - */ - CKEDITOR.ui.panel = function( document, definition ) { - // Copy all definition properties to this object. - if ( definition ) - CKEDITOR.tools.extend( this, definition ); - - // Set defaults. - CKEDITOR.tools.extend( this, { - className: '', - css: [] - }); - - this.id = CKEDITOR.tools.getNextId(); - this.document = document; - this.isFramed = this.forceIFrame || this.css.length; - - this._ = { - blocks: {} - }; - }; - - /** - * Represents panel handler object. - * - * @class - * @singleton - * @extends CKEDITOR.ui.handlerDefinition - */ - CKEDITOR.ui.panel.handler = { - /** - * Transforms a panel definition in a {@link CKEDITOR.ui.panel} instance. - * - * @param {Object} definition - * @returns {CKEDITOR.ui.panel} - */ - create: function( definition ) { - return new CKEDITOR.ui.panel( definition ); - } - }; - - var panelTpl = CKEDITOR.addTemplate( 'panel', '<div lang="{langCode}" id="{id}" dir={dir}' + - ' class="cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}"' + - ' style="z-index:{z-index}" role="presentation">' + - '{frame}' + - '</div>' ); - - var frameTpl = CKEDITOR.addTemplate( 'panel-frame', '<iframe id="{id}" class="cke_panel_frame" role="presentation" frameborder="0" src="{src}"></iframe>' ); - - var frameDocTpl = CKEDITOR.addTemplate( 'panel-frame-inner', '<!DOCTYPE html>' + - '<html class="cke_panel_container {env}" dir="{dir}" lang="{langCode}">' + - '<head>{css}</head>' + - '<body class="cke_{dir}"' + - ' style="margin:0;padding:0" onload="{onload}"></body>' + - '<\/html>' ); - - /** @class CKEDITOR.ui.panel */ - CKEDITOR.ui.panel.prototype = { - /** - * Renders the combo. - * - * @param {CKEDITOR.editor} editor The editor instance which this button is - * to be used by. - * @param {Array} [output] The output array to which append the HTML relative - * to this button. - */ - render: function( editor, output ) { - this.getHolderElement = function() { - var holder = this._.holder; - - if ( !holder ) { - if ( this.isFramed ) { - var iframe = this.document.getById( this.id + '_frame' ), - parentDiv = iframe.getParent(), - doc = iframe.getFrameDocument(); - - // Make it scrollable on iOS. (#8308) - CKEDITOR.env.iOS && parentDiv.setStyles({ - 'overflow': 'scroll', - '-webkit-overflow-scrolling': 'touch' - }); - - var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev ) { - this.isLoaded = true; - if ( this.onLoad ) - this.onLoad(); - }, this ) ); - - doc.write( frameDocTpl.output( CKEDITOR.tools.extend({ - css: CKEDITOR.tools.buildStyleHtml( this.css ), - onload: 'window.parent.CKEDITOR.tools.callFunction(' + onLoad + ');' - }, data ) ) ); - - var win = doc.getWindow(); - - // Register the CKEDITOR global. - win.$.CKEDITOR = CKEDITOR; - - // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534). - doc.on( 'key' + ( CKEDITOR.env.opera ? 'press' : 'down' ), function( evt ) { - var keystroke = evt.data.getKeystroke(), - dir = this.document.getById( this.id ).getAttribute( 'dir' ); - - // Delegate key processing to block. - if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) { - evt.data.preventDefault(); - return; - } - - // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl) - if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) ) { - if ( this.onEscape && this.onEscape( keystroke ) === false ) - evt.data.preventDefault(); - } - }, this ); - - holder = doc.getBody(); - holder.unselectable(); - CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad ); - } else - holder = this.document.getById( this.id ); - - this._.holder = holder; - } - - return holder; - }; - - var data = { - editorId: editor.id, - id: this.id, - langCode: editor.langCode, - dir: editor.lang.dir, - cls: this.className, - frame: '', - env: CKEDITOR.env.cssClass, - 'z-index': editor.config.baseFloatZIndex + 1 - }; - - if ( this.isFramed ) { - // With IE, the custom domain has to be taken care at first, - // for other browers, the 'src' attribute should be left empty to - // trigger iframe's 'load' event. - var src = - CKEDITOR.env.air ? 'javascript:void(0)' : - CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent( - 'document.open();' + - // In IE, the document domain must be set any time we call document.open(). - '(' + CKEDITOR.tools.fixDomain + ')();' + - 'document.close();' - ) + '}())' : - ''; - - data.frame = frameTpl.output({ - id: this.id + '_frame', - src: src - }); - } - - var html = panelTpl.output( data ); - - if ( output ) - output.push( html ); - - return html; - }, - - /** - * @todo - */ - addBlock: function( name, block ) { - block = this._.blocks[ name ] = block instanceof CKEDITOR.ui.panel.block ? block : new CKEDITOR.ui.panel.block( this.getHolderElement(), block ); - - if ( !this._.currentBlock ) - this.showBlock( name ); - - return block; - }, - - /** - * @todo - */ - getBlock: function( name ) { - return this._.blocks[ name ]; - }, - - /** - * @todo - */ - showBlock: function( name ) { - var blocks = this._.blocks, - block = blocks[ name ], - current = this._.currentBlock; - - // ARIA role works better in IE on the body element, while on the iframe - // for FF. (#8864) - var holder = !this.forceIFrame || CKEDITOR.env.ie ? this._.holder : this.document.getById( this.id + '_frame' ); - - if ( current ) { - // Clean up the current block's effects on holder. - holder.removeAttributes( current.attributes ); - current.hide(); - } - - this._.currentBlock = block; - - holder.setAttributes( block.attributes ); - CKEDITOR.fire( 'ariaWidget', holder ); - - // Reset the focus index, so it will always go into the first one. - block._.focusIndex = -1; - - this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block ); - - block.show(); - - return block; - }, - - /** - * @todo - */ - destroy: function() { - this.element && this.element.remove(); - } - }; - - /** - * @class - * - * @todo class and all methods - */ - CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass({ - /** - * Creates a block class instances. - * - * @constructor - * @todo - */ - $: function( blockHolder, blockDefinition ) { - this.element = blockHolder.append( blockHolder.getDocument().createElement( 'div', { - attributes: { - 'tabIndex': -1, - 'class': 'cke_panel_block', - 'role': 'presentation', - 'tabindex': 0 - }, - styles: { - display: 'none' - } - } ) ); - - // Copy all definition properties to this object. - if ( blockDefinition ) - CKEDITOR.tools.extend( this, blockDefinition ); - - - // Set the a11y attributes of this element ... - this.element.setAttributes( { - 'aria-label': this.attributes[ 'aria-label' ], - 'title': this.attributes.title || this.attributes[ 'aria-label' ] - } ); - - // ... and remove them from being set in the panel main element. - delete this.attributes[ 'aria-label' ]; - delete this.attributes.title; - - this.keys = {}; - - this._.focusIndex = -1; - - // Disable context menu for panels. - this.element.disableContextMenu(); - }, - - _: { - - /** - * Mark the item specified by the index as current activated. - */ - markItem: function( index ) { - if ( index == -1 ) - return; - var links = this.element.getElementsByTag( 'a' ); - var item = links.getItem( this._.focusIndex = index ); - - // Safari need focus on the iframe window first(#3389), but we need - // lock the blur to avoid hiding the panel. - if ( CKEDITOR.env.webkit || CKEDITOR.env.opera ) - item.getDocument().getWindow().focus(); - item.focus(); - - this.onMark && this.onMark( item ); - } - }, - - proto: { - show: function() { - this.element.setStyle( 'display', '' ); - }, - - hide: function() { - if ( !this.onHide || this.onHide.call( this ) !== true ) - this.element.setStyle( 'display', 'none' ); - }, - - onKeyDown: function( keystroke ) { - var keyAction = this.keys[ keystroke ]; - switch ( keyAction ) { - // Move forward. - case 'next': - var index = this._.focusIndex, - links = this.element.getElementsByTag( 'a' ), - link; - - while ( ( link = links.getItem( ++index ) ) ) { - // Move the focus only if the element is marked with - // the _cke_focus and it it's visible (check if it has - // width). - if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) { - this._.focusIndex = index; - link.focus(); - break; - } - } - return false; - - // Move backward. - case 'prev': - index = this._.focusIndex; - links = this.element.getElementsByTag( 'a' ); - - while ( index > 0 && ( link = links.getItem( --index ) ) ) { - // Move the focus only if the element is marked with - // the _cke_focus and it it's visible (check if it has - // width). - if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) { - this._.focusIndex = index; - link.focus(); - break; - } - } - return false; - - case 'click': - case 'mouseup': - index = this._.focusIndex; - link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index ); - - if ( link ) - link.$[ keyAction ] ? link.$[ keyAction ]() : link.$[ 'on' + keyAction ](); - - return false; - } - - return true; - } - } - }); - -})(); - -/** - * Fired when a panel is added to the document. - * - * @event ariaWidget - * @member CKEDITOR - * @param {Object} data The element wrapping the panel. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/panelbutton/plugin.js b/addons/website/static/lib/ckeditor/plugins/panelbutton/plugin.js deleted file mode 100644 index 709edfb85a0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/panelbutton/plugin.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'panelbutton', { - requires: 'button', - onLoad: function() { - function clickFn( editor ) { - var _ = this._; - - if ( _.state == CKEDITOR.TRISTATE_DISABLED ) - return; - - this.createPanel( editor ); - - if ( _.on ) { - _.panel.hide(); - return; - } - - _.panel.showBlock( this._.id, this.document.getById( this._.id ), 4 ); - } - - /** - * @class - * @extends CKEDITOR.ui.button - * @todo class and methods - */ - CKEDITOR.ui.panelButton = CKEDITOR.tools.createClass({ - base: CKEDITOR.ui.button, - - /** - * Creates a panelButton class instance. - * - * @constructor - */ - $: function( definition ) { - // We don't want the panel definition in this object. - var panelDefinition = definition.panel || {}; - delete definition.panel; - - this.base( definition ); - - this.document = ( panelDefinition.parent && panelDefinition.parent.getDocument() ) || CKEDITOR.document; - - panelDefinition.block = { - attributes: panelDefinition.attributes - }; - panelDefinition.toolbarRelated = true; - - this.hasArrow = true; - - this.click = clickFn; - - this._ = { - panelDefinition: panelDefinition - }; - }, - - statics: { - handler: { - create: function( definition ) { - return new CKEDITOR.ui.panelButton( definition ); - } - } - }, - - proto: { - createPanel: function( editor ) { - var _ = this._; - - if ( _.panel ) - return; - - var panelDefinition = this._.panelDefinition, - panelBlockDefinition = this._.panelDefinition.block, - panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(), - panel = this._.panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ), - block = panel.addBlock( _.id, panelBlockDefinition ), - me = this; - - panel.onShow = function() { - if ( me.className ) - this.element.addClass( me.className + '_panel' ); - - me.setState( CKEDITOR.TRISTATE_ON ); - - _.on = 1; - - me.editorFocus && editor.focus(); - - if ( me.onOpen ) - me.onOpen(); - }; - - panel.onHide = function( preventOnClose ) { - if ( me.className ) - this.element.getFirst().removeClass( me.className + '_panel' ); - - me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - - _.on = 0; - - if ( !preventOnClose && me.onClose ) - me.onClose(); - }; - - panel.onEscape = function() { - panel.hide( 1 ); - me.document.getById( _.id ).focus(); - }; - - if ( this.onBlock ) - this.onBlock( panel, block ); - - block.onHide = function() { - _.on = 0; - me.setState( CKEDITOR.TRISTATE_OFF ); - }; - } - } - }); - - }, - beforeInit: function( editor ) { - editor.ui.addHandler( CKEDITOR.UI_PANELBUTTON, CKEDITOR.ui.panelButton.handler ); - } -}); - -/** - * Button UI element. - * - * @readonly - * @property {String} [='panelbutton'] - * @member CKEDITOR - */ -CKEDITOR.UI_PANELBUTTON = 'panelbutton'; diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/filter/default.js b/addons/website/static/lib/ckeditor/plugins/pastefromword/filter/default.js deleted file mode 100644 index 643815e48b9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/filter/default.js +++ /dev/null @@ -1,1212 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var fragmentPrototype = CKEDITOR.htmlParser.fragment.prototype, - elementPrototype = CKEDITOR.htmlParser.element.prototype; - - fragmentPrototype.onlyChild = elementPrototype.onlyChild = function() { - var children = this.children, - count = children.length, - firstChild = ( count == 1 ) && children[ 0 ]; - return firstChild || null; - }; - - elementPrototype.removeAnyChildWithName = function( tagName ) { - var children = this.children, - childs = [], - child; - - for ( var i = 0; i < children.length; i++ ) { - child = children[ i ]; - if ( !child.name ) - continue; - - if ( child.name == tagName ) { - childs.push( child ); - children.splice( i--, 1 ); - } - childs = childs.concat( child.removeAnyChildWithName( tagName ) ); - } - return childs; - }; - - elementPrototype.getAncestor = function( tagNameRegex ) { - var parent = this.parent; - while ( parent && !( parent.name && parent.name.match( tagNameRegex ) ) ) - parent = parent.parent; - return parent; - }; - - fragmentPrototype.firstChild = elementPrototype.firstChild = function( evaluator ) { - var child; - - for ( var i = 0; i < this.children.length; i++ ) { - child = this.children[ i ]; - if ( evaluator( child ) ) - return child; - else if ( child.name ) { - child = child.firstChild( evaluator ); - if ( child ) - return child; - } - } - - return null; - }; - - // Adding a (set) of styles to the element's 'style' attributes. - elementPrototype.addStyle = function( name, value, isPrepend ) { - var styleText, - addingStyleText = ''; - // name/value pair. - if ( typeof value == 'string' ) - addingStyleText += name + ':' + value + ';'; - else { - // style literal. - if ( typeof name == 'object' ) { - for ( var style in name ) { - if ( name.hasOwnProperty( style ) ) - addingStyleText += style + ':' + name[ style ] + ';'; - } - } - // raw style text form. - else - addingStyleText += name; - - isPrepend = value; - } - - if ( !this.attributes ) - this.attributes = {}; - - styleText = this.attributes.style || ''; - - styleText = ( isPrepend ? [ addingStyleText, styleText ] : [ styleText, addingStyleText ] ).join( ';' ); - - this.attributes.style = styleText.replace( /^;|;(?=;)/, '' ); - }; - - // Retrieve a style property value of the element. - elementPrototype.getStyle = function( name ) { - var styles = this.attributes.style; - if ( styles ) { - styles = CKEDITOR.tools.parseCssText( styles, 1 ); - return styles[ name ]; - } - }; - - /** - * Return the DTD-valid parent tag names of the specified one. - * - * @member CKEDITOR.dtd - * @param {String} tagName - * @returns {Object} - */ - CKEDITOR.dtd.parentOf = function( tagName ) { - var result = {}; - for ( var tag in this ) { - if ( tag.indexOf( '$' ) == -1 && this[ tag ][ tagName ] ) - result[ tag ] = 1; - } - return result; - }; - - // 1. move consistent list item styles up to list root. - // 2. clear out unnecessary list item numbering. - function postProcessList( list ) { - var children = list.children, - child, attrs, - count = list.children.length, - match, mergeStyle, - styleTypeRegexp = /list-style-type:(.*?)(?:;|$)/, - stylesFilter = CKEDITOR.plugins.pastefromword.filters.stylesFilter; - - attrs = list.attributes; - if ( styleTypeRegexp.exec( attrs.style ) ) - return; - - for ( var i = 0; i < count; i++ ) { - child = children[ i ]; - - if ( child.attributes.value && Number( child.attributes.value ) == i + 1 ) - delete child.attributes.value; - - match = styleTypeRegexp.exec( child.attributes.style ); - - if ( match ) { - if ( match[ 1 ] == mergeStyle || !mergeStyle ) - mergeStyle = match[ 1 ]; - else { - mergeStyle = null; - break; - } - } - } - - if ( mergeStyle ) { - for ( i = 0; i < count; i++ ) { - attrs = children[ i ].attributes; - attrs.style && ( attrs.style = stylesFilter( [ [ 'list-style-type' ] ] )( attrs.style ) || '' ); - } - - list.addStyle( 'list-style-type', mergeStyle ); - } - } - - var cssLengthRelativeUnit = /^([.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz){1}?/i; - var emptyMarginRegex = /^(?:\b0[^\s]*\s*){1,4}$/; // e.g. 0px 0pt 0px - var romanLiternalPattern = '^m{0,4}(cm|cd|d?c{0,3})(xc|xl|l?x{0,3})(ix|iv|v?i{0,3})$', - lowerRomanLiteralRegex = new RegExp( romanLiternalPattern ), - upperRomanLiteralRegex = new RegExp( romanLiternalPattern.toUpperCase() ); - - var orderedPatterns = { 'decimal': /\d+/, 'lower-roman': lowerRomanLiteralRegex, 'upper-roman': upperRomanLiteralRegex, 'lower-alpha': /^[a-z]+$/, 'upper-alpha': /^[A-Z]+$/ }, - unorderedPatterns = { 'disc': /[l\u00B7\u2002]/, 'circle': /[\u006F\u00D8]/, 'square': /[\u006E\u25C6]/ }, - listMarkerPatterns = { 'ol': orderedPatterns, 'ul': unorderedPatterns }, - romans = [ [ 1000, 'M' ], [ 900, 'CM' ], [ 500, 'D' ], [ 400, 'CD' ], [ 100, 'C' ], [ 90, 'XC' ], [ 50, 'L' ], [ 40, 'XL' ], [ 10, 'X' ], [ 9, 'IX' ], [ 5, 'V' ], [ 4, 'IV' ], [ 1, 'I' ] ], - alpahbets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - // Convert roman numbering back to decimal. - function fromRoman( str ) { - str = str.toUpperCase(); - var l = romans.length, - retVal = 0; - for ( var i = 0; i < l; ++i ) { - for ( var j = romans[ i ], k = j[ 1 ].length; str.substr( 0, k ) == j[ 1 ]; str = str.substr( k ) ) - retVal += j[ 0 ]; - } - return retVal; - } - - // Convert alphabet numbering back to decimal. - function fromAlphabet( str ) { - str = str.toUpperCase(); - var l = alpahbets.length, - retVal = 1; - for ( var x = 1; str.length > 0; x *= l ) { - retVal += alpahbets.indexOf( str.charAt( str.length - 1 ) ) * x; - str = str.substr( 0, str.length - 1 ); - } - return retVal; - } - - var listBaseIndent = 0, - previousListItemMargin = null, - previousListId; - - var plugin = ( CKEDITOR.plugins.pastefromword = { - utils: { - // Create a <cke:listbullet> which indicate an list item type. - createListBulletMarker: function( bullet, bulletText ) { - var marker = new CKEDITOR.htmlParser.element( 'cke:listbullet' ); - marker.attributes = { 'cke:listsymbol': bullet[ 0 ] }; - marker.add( new CKEDITOR.htmlParser.text( bulletText ) ); - return marker; - }, - - isListBulletIndicator: function( element ) { - var styleText = element.attributes && element.attributes.style; - if ( /mso-list\s*:\s*Ignore/i.test( styleText ) ) - return true; - }, - - isContainingOnlySpaces: function( element ) { - var text; - return ( ( text = element.onlyChild() ) && ( /^(:?\s| )+$/ ).test( text.value ) ); - }, - - resolveList: function( element ) { - // <cke:listbullet> indicate a list item. - var attrs = element.attributes, - listMarker; - - if ( ( listMarker = element.removeAnyChildWithName( 'cke:listbullet' ) ) && listMarker.length && ( listMarker = listMarker[ 0 ] ) ) { - element.name = 'cke:li'; - - if ( attrs.style ) { - attrs.style = plugin.filters.stylesFilter( [ - // Text-indent is not representing list item level any more. - [ 'text-indent' ], - [ 'line-height' ], - // First attempt is to resolve indent level from on a constant margin increment. - [ ( /^margin(:?-left)?$/ ), null, function( margin ) { - // Deal with component/short-hand form. - var values = margin.split( ' ' ); - margin = CKEDITOR.tools.convertToPx( values[ 3 ] || values[ 1 ] || values[ 0 ] ); - - // Figure out the indent unit by checking the first time of incrementation. - if ( !listBaseIndent && previousListItemMargin !== null && margin > previousListItemMargin ) - listBaseIndent = margin - previousListItemMargin; - - previousListItemMargin = margin; - - attrs[ 'cke:indent' ] = listBaseIndent && ( Math.ceil( margin / listBaseIndent ) + 1 ) || 1; - }], - // The best situation: "mso-list:l0 level1 lfo2" tells the belonged list root, list item indentation, etc. - [ ( /^mso-list$/ ), null, function( val ) { - val = val.split( ' ' ); - var listId = Number( val[ 0 ].match( /\d+/ ) ), - indent = Number( val[ 1 ].match( /\d+/ ) ); - - if ( indent == 1 ) { - listId !== previousListId && ( attrs[ 'cke:reset' ] = 1 ); - previousListId = listId; - } - attrs[ 'cke:indent' ] = indent; - }] - ] )( attrs.style, element ) || ''; - } - - // First level list item might be presented without a margin. - - - // In case all above doesn't apply. - if ( !attrs[ 'cke:indent' ] ) { - previousListItemMargin = 0; - attrs[ 'cke:indent' ] = 1; - } - - // Inherit attributes from bullet. - CKEDITOR.tools.extend( attrs, listMarker.attributes ); - return true; - } - // Current list disconnected. - else - previousListId = previousListItemMargin = listBaseIndent = null; - - return false; - }, - - // Providing a shorthand style then retrieve one or more style component values. - getStyleComponents: (function() { - var calculator = CKEDITOR.dom.element.createFromHtml( '<div style="position:absolute;left:-9999px;top:-9999px;"></div>', CKEDITOR.document ); - CKEDITOR.document.getBody().append( calculator ); - - return function( name, styleValue, fetchList ) { - calculator.setStyle( name, styleValue ); - var styles = {}, - count = fetchList.length; - for ( var i = 0; i < count; i++ ) - styles[ fetchList[ i ] ] = calculator.getStyle( fetchList[ i ] ); - - return styles; - }; - })(), - - listDtdParents: CKEDITOR.dtd.parentOf( 'ol' ) - }, - - filters: { - // Transform a normal list into flat list items only presentation. - // E.g. <ul><li>level1<ol><li>level2</li></ol></li> => - // <cke:li cke:listtype="ul" cke:indent="1">level1</cke:li> - // <cke:li cke:listtype="ol" cke:indent="2">level2</cke:li> - flattenList: function( element, level ) { - level = typeof level == 'number' ? level : 1; - - var attrs = element.attributes, - listStyleType; - - // All list items are of the same type. - switch ( attrs.type ) { - case 'a': - listStyleType = 'lower-alpha'; - break; - case '1': - listStyleType = 'decimal'; - break; - // TODO: Support more list style type from MS-Word. - } - - var children = element.children, - child; - - for ( var i = 0; i < children.length; i++ ) { - child = children[ i ]; - - if ( child.name in CKEDITOR.dtd.$listItem ) { - var attributes = child.attributes, - listItemChildren = child.children, - count = listItemChildren.length, - last = listItemChildren[ count - 1 ]; - - // Move out nested list. - if ( last.name in CKEDITOR.dtd.$list ) { - element.add( last, i + 1 ); - - // Remove the parent list item if it's just a holder. - if ( !--listItemChildren.length ) - children.splice( i--, 1 ); - } - - child.name = 'cke:li'; - - // Inherit numbering from list root on the first list item. - attrs.start && !i && ( attributes.value = attrs.start ); - - plugin.filters.stylesFilter( [ - [ 'tab-stops', null, function( val ) { - var margin = val.split( ' ' )[ 1 ].match( cssLengthRelativeUnit ); - margin && ( previousListItemMargin = CKEDITOR.tools.convertToPx( margin[ 0 ] ) ); - }], - ( level == 1 ? [ 'mso-list', null, function( val ) { - val = val.split( ' ' ); - var listId = Number( val[ 0 ].match( /\d+/ ) ); - listId !== previousListId && ( attributes[ 'cke:reset' ] = 1 ); - previousListId = listId; - }] : null ) - ] )( attributes.style ); - - attributes[ 'cke:indent' ] = level; - attributes[ 'cke:listtype' ] = element.name; - attributes[ 'cke:list-style-type' ] = listStyleType; - } - // Flatten sub list. - else if ( child.name in CKEDITOR.dtd.$list ) { - // Absorb sub list children. - arguments.callee.apply( this, [ child, level + 1 ] ); - children = children.slice( 0, i ).concat( child.children ).concat( children.slice( i + 1 ) ); - element.children = []; - for ( var j = 0, num = children.length; j < num; j++ ) - element.add( children[ j ] ); - - children = element.children; - } - } - - delete element.name; - - // We're loosing tag name here, signalize this element as a list. - attrs[ 'cke:list' ] = 1; - }, - - // Try to collect all list items among the children and establish one - // or more HTML list structures for them. - // @param element - assembleList: function( element ) { - var children = element.children, - child, listItem, // The current processing cke:li element. - listItemAttrs, listItemIndent, // Indent level of current list item. - lastIndent, lastListItem, // The previous one just been added to the list. - list, // Current staging list and it's parent list if any. - openedLists = [], - previousListStyleType, previousListType; - - // Properties of the list item are to be resolved from the list bullet. - var bullet, listType, listStyleType, itemNumeric; - - for ( var i = 0; i < children.length; i++ ) { - child = children[ i ]; - - if ( 'cke:li' == child.name ) { - child.name = 'li'; - listItem = child; - listItemAttrs = listItem.attributes; - bullet = listItemAttrs[ 'cke:listsymbol' ]; - bullet = bullet && bullet.match( /^(?:[(]?)([^\s]+?)([.)]?)$/ ); - listType = listStyleType = itemNumeric = null; - - if ( listItemAttrs[ 'cke:ignored' ] ) { - children.splice( i--, 1 ); - continue; - } - - - // This's from a new list root. - listItemAttrs[ 'cke:reset' ] && ( list = lastIndent = lastListItem = null ); - - // List item indent level might come from a real list indentation or - // been resolved from a pseudo list item's margin value, even get - // no indentation at all. - listItemIndent = Number( listItemAttrs[ 'cke:indent' ] ); - - // We're moving out of the current list, cleaning up. - if ( listItemIndent != lastIndent ) - previousListType = previousListStyleType = null; - - // List type and item style are already resolved. - if ( !bullet ) { - listType = listItemAttrs[ 'cke:listtype' ] || 'ol'; - listStyleType = listItemAttrs[ 'cke:list-style-type' ]; - } else { - // Probably share the same list style type with previous list item, - // give it priority to avoid ambiguous between C(Alpha) and C.(Roman). - if ( previousListType && listMarkerPatterns[ previousListType ][ previousListStyleType ].test( bullet[ 1 ] ) ) { - listType = previousListType; - listStyleType = previousListStyleType; - } else { - for ( var type in listMarkerPatterns ) { - for ( var style in listMarkerPatterns[ type ] ) { - if ( listMarkerPatterns[ type ][ style ].test( bullet[ 1 ] ) ) { - // Small numbering has higher priority, when dealing with ambiguous - // between C(Alpha) and C.(Roman). - if ( type == 'ol' && ( /alpha|roman/ ).test( style ) ) { - var num = /roman/.test( style ) ? fromRoman( bullet[ 1 ] ) : fromAlphabet( bullet[ 1 ] ); - if ( !itemNumeric || num < itemNumeric ) { - itemNumeric = num; - listType = type; - listStyleType = style; - } - } else { - listType = type; - listStyleType = style; - break; - } - } - } - } - } - - // Simply use decimal/disc for the rest forms of unrepresentable - // numerals, e.g. Chinese..., but as long as there a second part - // included, it has a bigger chance of being a order list ;) - !listType && ( listType = bullet[ 2 ] ? 'ol' : 'ul' ); - } - - previousListType = listType; - previousListStyleType = listStyleType || ( listType == 'ol' ? 'decimal' : 'disc' ); - if ( listStyleType && listStyleType != ( listType == 'ol' ? 'decimal' : 'disc' ) ) - listItem.addStyle( 'list-style-type', listStyleType ); - - // Figure out start numbering. - if ( listType == 'ol' && bullet ) { - switch ( listStyleType ) { - case 'decimal': - itemNumeric = Number( bullet[ 1 ] ); - break; - case 'lower-roman': - case 'upper-roman': - itemNumeric = fromRoman( bullet[ 1 ] ); - break; - case 'lower-alpha': - case 'upper-alpha': - itemNumeric = fromAlphabet( bullet[ 1 ] ); - break; - } - - // Always create the numbering, swipe out unnecessary ones later. - listItem.attributes.value = itemNumeric; - } - - // Start the list construction. - if ( !list ) { - openedLists.push( list = new CKEDITOR.htmlParser.element( listType ) ); - list.add( listItem ); - children[ i ] = list; - } else { - if ( listItemIndent > lastIndent ) { - openedLists.push( list = new CKEDITOR.htmlParser.element( listType ) ); - list.add( listItem ); - lastListItem.add( list ); - } else if ( listItemIndent < lastIndent ) { - // There might be a negative gap between two list levels. (#4944) - var diff = lastIndent - listItemIndent, - parent; - while ( diff-- && ( parent = list.parent ) ) - list = parent.parent; - - list.add( listItem ); - } else - list.add( listItem ); - - children.splice( i--, 1 ); - } - - lastListItem = listItem; - lastIndent = listItemIndent; - } else if ( list ) - list = lastIndent = lastListItem = null; - } - - for ( i = 0; i < openedLists.length; i++ ) - postProcessList( openedLists[ i ] ); - - list = lastIndent = lastListItem = previousListId = previousListItemMargin = listBaseIndent = null; - }, - - // A simple filter which always rejecting. - falsyFilter: function( value ) { - return false; - }, - - // A filter dedicated on the 'style' attribute filtering, e.g. dropping/replacing style properties. - // @param styles {Array} in form of [ styleNameRegexp, styleValueRegexp, - // newStyleValue/newStyleGenerator, newStyleName ] where only the first - // parameter is mandatory. - // @param whitelist {Boolean} Whether the {@param styles} will be considered as a white-list. - stylesFilter: function( styles, whitelist ) { - return function( styleText, element ) { - var rules = []; - // html-encoded quote might be introduced by 'font-family' - // from MS-Word which confused the following regexp. e.g. - //'font-family: "Lucida, Console"' - ( styleText || '' ).replace( /"/g, '"' ).replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) { - name = name.toLowerCase(); - name == 'font-family' && ( value = value.replace( /["']/g, '' ) ); - - var namePattern, valuePattern, newValue, newName; - for ( var i = 0; i < styles.length; i++ ) { - if ( styles[ i ] ) { - namePattern = styles[ i ][ 0 ]; - valuePattern = styles[ i ][ 1 ]; - newValue = styles[ i ][ 2 ]; - newName = styles[ i ][ 3 ]; - - if ( name.match( namePattern ) && ( !valuePattern || value.match( valuePattern ) ) ) { - name = newName || name; - whitelist && ( newValue = newValue || value ); - - if ( typeof newValue == 'function' ) - newValue = newValue( value, element, name ); - - // Return an couple indicate both name and value - // changed. - if ( newValue && newValue.push ) - name = newValue[ 0 ], newValue = newValue[ 1 ]; - - if ( typeof newValue == 'string' ) - rules.push( [ name, newValue ] ); - return; - } - } - } - - !whitelist && rules.push( [ name, value ] ); - - }); - - for ( var i = 0; i < rules.length; i++ ) - rules[ i ] = rules[ i ].join( ':' ); - return rules.length ? ( rules.join( ';' ) + ';' ) : false; - }; - }, - - // Migrate the element by decorate styles on it. - // @param styleDefinition - // @param variables - elementMigrateFilter: function( styleDefinition, variables ) { - return styleDefinition ? function( element ) { - var styleDef = variables ? new CKEDITOR.style( styleDefinition, variables )._.definition : styleDefinition; - element.name = styleDef.element; - CKEDITOR.tools.extend( element.attributes, CKEDITOR.tools.clone( styleDef.attributes ) ); - element.addStyle( CKEDITOR.style.getStyleText( styleDef ) ); - } : function(){}; - }, - - // Migrate styles by creating a new nested stylish element. - // @param styleDefinition - styleMigrateFilter: function( styleDefinition, variableName ) { - - var elementMigrateFilter = this.elementMigrateFilter; - return styleDefinition ? function( value, element ) { - // Build an stylish element first. - var styleElement = new CKEDITOR.htmlParser.element( null ), - variables = {}; - - variables[ variableName ] = value; - elementMigrateFilter( styleDefinition, variables )( styleElement ); - // Place the new element inside the existing span. - styleElement.children = element.children; - element.children = [ styleElement ]; - - // #10285 - later on styleElement will replace element if element won't have any attributes. - // However, in some cases styleElement is identical to element and therefore should not be filtered - // to avoid inf loop. Unfortunately calling element.filterChildren() does not prevent from that (#10327). - // However, we can assume that we don't need to filter styleElement at all, so it is safe to replace - // its filter method. - styleElement.filter = function() {}; - styleElement.parent = element; - } : function(){}; - }, - - // A filter which remove cke-namespaced-attribute on - // all none-cke-namespaced elements. - // @param value - // @param element - bogusAttrFilter: function( value, element ) { - if ( element.name.indexOf( 'cke:' ) == -1 ) - return false; - }, - - // A filter which will be used to apply inline css style according the stylesheet - // definition rules, is generated lazily when filtering. - applyStyleFilter: null - - }, - - getRules: function( editor, filter ) { - var dtd = CKEDITOR.dtd, - blockLike = CKEDITOR.tools.extend( {}, dtd.$block, dtd.$listItem, dtd.$tableContent ), - config = editor.config, - filters = this.filters, - falsyFilter = filters.falsyFilter, - stylesFilter = filters.stylesFilter, - elementMigrateFilter = filters.elementMigrateFilter, - styleMigrateFilter = CKEDITOR.tools.bind( this.filters.styleMigrateFilter, this.filters ), - createListBulletMarker = this.utils.createListBulletMarker, - flattenList = filters.flattenList, - assembleList = filters.assembleList, - isListBulletIndicator = this.utils.isListBulletIndicator, - containsNothingButSpaces = this.utils.isContainingOnlySpaces, - resolveListItem = this.utils.resolveList, - convertToPx = function( value ) { - value = CKEDITOR.tools.convertToPx( value ); - return isNaN( value ) ? value : value + 'px'; - }, - getStyleComponents = this.utils.getStyleComponents, - listDtdParents = this.utils.listDtdParents, - removeFontStyles = config.pasteFromWordRemoveFontStyles !== false, - removeStyles = config.pasteFromWordRemoveStyles !== false; - - return { - - elementNames: [ - // Remove script, meta and link elements. - [ ( /meta|link|script/ ), '' ] - ], - - root: function( element ) { - element.filterChildren( filter ); - assembleList( element ); - }, - - elements: { - '^': function( element ) { - // Transform CSS style declaration to inline style. - var applyStyleFilter; - if ( CKEDITOR.env.gecko && ( applyStyleFilter = filters.applyStyleFilter ) ) - applyStyleFilter( element ); - }, - - $: function( element ) { - var tagName = element.name || '', - attrs = element.attributes; - - // Convert length unit of width/height on blocks to - // a more editor-friendly way (px). - if ( tagName in blockLike && attrs.style ) { - attrs.style = stylesFilter( [ [ ( /^(:?width|height)$/ ), null, convertToPx ] ] )( attrs.style ) || ''; - } - - // Processing headings. - if ( tagName.match( /h\d/ ) ) { - element.filterChildren( filter ); - // Is the heading actually a list item? - if ( resolveListItem( element ) ) - return; - - // Adapt heading styles to editor's convention. - elementMigrateFilter( config[ 'format_' + tagName ] )( element ); - } - // Remove inline elements which contain only empty spaces. - else if ( tagName in dtd.$inline ) { - element.filterChildren( filter ); - if ( containsNothingButSpaces( element ) ) - delete element.name; - } - // Remove element with ms-office namespace, - // with it's content preserved, e.g. 'o:p'. - else if ( tagName.indexOf( ':' ) != -1 && tagName.indexOf( 'cke' ) == -1 ) { - element.filterChildren( filter ); - - // Restore image real link from vml. - if ( tagName == 'v:imagedata' ) { - var href = element.attributes[ 'o:href' ]; - if ( href ) - element.attributes.src = href; - element.name = 'img'; - return; - } - delete element.name; - } - - // Assembling list items into a whole list. - if ( tagName in listDtdParents ) { - element.filterChildren( filter ); - assembleList( element ); - } - }, - - // We'll drop any style sheet, but Firefox conclude - // certain styles in a single style element, which are - // required to be changed into inline ones. - 'style': function( element ) { - if ( CKEDITOR.env.gecko ) { - // Grab only the style definition section. - var styleDefSection = element.onlyChild().value.match( /\/\* Style Definitions \*\/([\s\S]*?)\/\*/ ), - styleDefText = styleDefSection && styleDefSection[ 1 ], - rules = {}; // Storing the parsed result. - - if ( styleDefText ) { - styleDefText - // Remove line-breaks. - .replace( /[\n\r]/g, '' ) - // Extract selectors and style properties. - .replace( /(.+?)\{(.+?)\}/g, function( rule, selectors, styleBlock ) { - selectors = selectors.split( ',' ); - var length = selectors.length, - selector; - for ( var i = 0; i < length; i++ ) { - // Assume MS-Word mostly generate only simple - // selector( [Type selector][Class selector]). - CKEDITOR.tools.trim( selectors[ i ] ).replace( /^(\w+)(\.[\w-]+)?$/g, function( match, tagName, className ) { - tagName = tagName || '*'; - className = className.substring( 1, className.length ); - - // Reject MS-Word Normal styles. - if ( className.match( /MsoNormal/ ) ) - return; - - if ( !rules[ tagName ] ) - rules[ tagName ] = {}; - if ( className ) - rules[ tagName ][ className ] = styleBlock; - else - rules[ tagName ] = styleBlock; - }); - } - }); - - filters.applyStyleFilter = function( element ) { - var name = rules[ '*' ] ? '*' : element.name, - className = element.attributes && element.attributes[ 'class' ], - style; - if ( name in rules ) { - style = rules[ name ]; - if ( typeof style == 'object' ) - style = style[ className ]; - // Maintain style rules priorities. - style && element.addStyle( style, true ); - } - }; - } - } - return false; - }, - - 'p': function( element ) { - // A a fall-back approach to resolve list item in browsers - // that doesn't include "mso-list:Ignore" on list bullets, - // note it's not perfect as not all list style (e.g. "heading list") is shipped - // with this pattern. (#6662) - if ( ( /MsoListParagraph/i ).exec( element.attributes[ 'class' ] ) || element.getStyle( 'mso-list' ) ) { - var bulletText = element.firstChild( function( node ) { - return node.type == CKEDITOR.NODE_TEXT && !containsNothingButSpaces( node.parent ); - }); - - var bullet = bulletText && bulletText.parent; - if ( bullet ) { - bullet.addStyle( 'mso-list', 'Ignore' ); - } - } - - element.filterChildren( filter ); - - // Is the paragraph actually a list item? - if ( resolveListItem( element ) ) - return; - - // Adapt paragraph formatting to editor's convention - // according to enter-mode. - if ( config.enterMode == CKEDITOR.ENTER_BR ) { - // We suffer from attribute/style lost in this situation. - delete element.name; - element.add( new CKEDITOR.htmlParser.element( 'br' ) ); - } else - elementMigrateFilter( config[ 'format_' + ( config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ] )( element ); - }, - - 'div': function( element ) { - // Aligned table with no text surrounded is represented by a wrapper div, from which - // table cells inherit as text-align styles, which is wrong. - // Instead we use a clear-float div after the table to properly achieve the same layout. - var singleChild = element.onlyChild(); - if ( singleChild && singleChild.name == 'table' ) { - var attrs = element.attributes; - singleChild.attributes = CKEDITOR.tools.extend( singleChild.attributes, attrs ); - attrs.style && singleChild.addStyle( attrs.style ); - - var clearFloatDiv = new CKEDITOR.htmlParser.element( 'div' ); - clearFloatDiv.addStyle( 'clear', 'both' ); - element.add( clearFloatDiv ); - delete element.name; - } - }, - - 'td': function( element ) { - // 'td' in 'thead' is actually <th>. - if ( element.getAncestor( 'thead' ) ) - element.name = 'th'; - }, - - // MS-Word sometimes present list as a mixing of normal list - // and pseudo-list, normalize the previous ones into pseudo form. - 'ol': flattenList, - 'ul': flattenList, - 'dl': flattenList, - - 'font': function( element ) { - // Drop the font tag if it comes from list bullet text. - if ( isListBulletIndicator( element.parent ) ) { - delete element.name; - return; - } - - element.filterChildren( filter ); - - var attrs = element.attributes, - styleText = attrs.style, - parent = element.parent; - - if ( 'font' == parent.name ) // Merge nested <font> tags. - { - CKEDITOR.tools.extend( parent.attributes, element.attributes ); - styleText && parent.addStyle( styleText ); - delete element.name; - } - // Convert the merged into a span with all attributes preserved. - else { - styleText = styleText || ''; - // IE's having those deprecated attributes, normalize them. - if ( attrs.color ) { - attrs.color != '#000000' && ( styleText += 'color:' + attrs.color + ';' ); - delete attrs.color; - } - if ( attrs.face ) { - styleText += 'font-family:' + attrs.face + ';'; - delete attrs.face; - } - // TODO: Mapping size in ranges of xx-small, - // x-small, small, medium, large, x-large, xx-large. - if ( attrs.size ) { - styleText += 'font-size:' + - ( attrs.size > 3 ? 'large' : ( attrs.size < 3 ? 'small' : 'medium' ) ) + ';'; - delete attrs.size; - } - - element.name = 'span'; - element.addStyle( styleText ); - } - }, - - 'span': function( element ) { - // Remove the span if it comes from list bullet text. - if ( isListBulletIndicator( element.parent ) ) - return false; - - element.filterChildren( filter ); - if ( containsNothingButSpaces( element ) ) { - delete element.name; - return null; - } - - // List item bullet type is supposed to be indicated by - // the text of a span with style 'mso-list : Ignore' or an image. - if ( isListBulletIndicator( element ) ) { - var listSymbolNode = element.firstChild( function( node ) { - return node.value || node.name == 'img'; - }); - - var listSymbol = listSymbolNode && ( listSymbolNode.value || 'l.' ), - listType = listSymbol && listSymbol.match( /^(?:[(]?)([^\s]+?)([.)]?)$/ ); - - if ( listType ) { - var marker = createListBulletMarker( listType, listSymbol ); - // Some non-existed list items might be carried by an inconsequential list, indicate by "mso-hide:all/display:none", - // those are to be removed later, now mark it with "cke:ignored". - var ancestor = element.getAncestor( 'span' ); - if ( ancestor && ( / mso-hide:\s*all|display:\s*none / ).test( ancestor.attributes.style ) ) - marker.attributes[ 'cke:ignored' ] = 1; - return marker; - } - } - - // Update the src attribute of image element with href. - var children = element.children, - attrs = element.attributes, - styleText = attrs && attrs.style, - firstChild = children && children[ 0 ]; - - // Assume MS-Word mostly carry font related styles on <span>, - // adapting them to editor's convention. - if ( styleText ) { - attrs.style = stylesFilter( [ - // Drop 'inline-height' style which make lines overlapping. - [ 'line-height' ], - [ ( /^font-family$/ ), null, !removeFontStyles ? styleMigrateFilter( config[ 'font_style' ], 'family' ) : null ], - [ ( /^font-size$/ ), null, !removeFontStyles ? styleMigrateFilter( config[ 'fontSize_style' ], 'size' ) : null ], - [ ( /^color$/ ), null, !removeFontStyles ? styleMigrateFilter( config[ 'colorButton_foreStyle' ], 'color' ) : null ], - [ ( /^background-color$/ ), null, !removeFontStyles ? styleMigrateFilter( config[ 'colorButton_backStyle' ], 'color' ) : null ] - ] )( styleText, element ) || ''; - } - - if ( !attrs.style ) - delete attrs.style; - - if ( CKEDITOR.tools.isEmpty( attrs ) ) - delete element.name; - - return null; - }, - - // Migrate basic style formats to editor configured ones. - b: elementMigrateFilter( config[ 'coreStyles_bold' ] ), - i: elementMigrateFilter( config[ 'coreStyles_italic' ] ), - u: elementMigrateFilter( config[ 'coreStyles_underline' ] ), - s: elementMigrateFilter( config[ 'coreStyles_strike' ] ), - sup: elementMigrateFilter( config[ 'coreStyles_superscript' ] ), - sub: elementMigrateFilter( config[ 'coreStyles_subscript' ] ), - - // Remove full paths from links to anchors. - a: function( element ) { - var attrs = element.attributes; - if ( attrs.href && attrs.href.match( /^file:\/\/\/[\S]+#/i ) ) - attrs.href = attrs.href.replace( /^file:\/\/\/[^#]+/i, '' ); - }, - - 'cke:listbullet': function( element ) { - if ( element.getAncestor( /h\d/ ) && !config.pasteFromWordNumberedHeadingToList ) - delete element.name; - } - }, - - attributeNames: [ - // Remove onmouseover and onmouseout events (from MS Word comments effect) - [ ( /^onmouse(:?out|over)/ ), '' ], - // Onload on image element. - [ ( /^onload$/ ), '' ], - // Remove office and vml attribute from elements. - [ ( /(?:v|o):\w+/ ), '' ], - // Remove lang/language attributes. - [ ( /^lang/ ), '' ] - ], - - attributes: { - 'style': stylesFilter( removeStyles ? - // Provide a white-list of styles that we preserve, those should - // be the ones that could later be altered with editor tools. - [ - // Leave list-style-type - [ ( /^list-style-type$/ ), null ], - - // Preserve margin-left/right which used as default indent style in the editor. - [ ( /^margin$|^margin-(?!bottom|top)/ ), null, function( value, element, name ) { - if ( element.name in { p:1,div:1 } ) { - var indentStyleName = config.contentsLangDirection == 'ltr' ? 'margin-left' : 'margin-right'; - - // Extract component value from 'margin' shorthand. - if ( name == 'margin' ) { - value = getStyleComponents( name, value, [ indentStyleName ] )[ indentStyleName ]; - } else if ( name != indentStyleName ) - return null; - - if ( value && !emptyMarginRegex.test( value ) ) - return [ indentStyleName, value ]; - } - - return null; - }], - - // Preserve clear float style. - [ ( /^clear$/ ) ], - - [ ( /^border.*|margin.*|vertical-align|float$/ ), null, function( value, element ) { - if ( element.name == 'img' ) - return value; - }], - - [ ( /^width|height$/ ), null, function( value, element ) { - if ( element.name in { table:1,td:1,th:1,img:1 } ) - return value; - }] - ] : - // Otherwise provide a black-list of styles that we remove. - [ - [ ( /^mso-/ ) ], - // Fixing color values. - [ ( /-color$/ ), null, function( value ) { - if ( value == 'transparent' ) - return false; - if ( CKEDITOR.env.gecko ) - return value.replace( /-moz-use-text-color/g, 'transparent' ); - }], - // Remove empty margin values, e.g. 0.00001pt 0em 0pt - [ ( /^margin$/ ), emptyMarginRegex ], - [ 'text-indent', '0cm' ], - [ 'page-break-before' ], - [ 'tab-stops' ], - [ 'display', 'none' ], - removeFontStyles ? [ ( /font-?/ ) ] : null - ], removeStyles ), - - // Prefer width styles over 'width' attributes. - 'width': function( value, element ) { - if ( element.name in dtd.$tableContent ) - return false; - }, - // Prefer border styles over table 'border' attributes. - 'border': function( value, element ) { - if ( element.name in dtd.$tableContent ) - return false; - }, - - // Only Firefox carry style sheet from MS-Word, which - // will be applied by us manually. For other browsers - // the css className is useless. - 'class': falsyFilter, - - // MS-Word always generate 'background-color' along with 'bgcolor', - // simply drop the deprecated attributes. - 'bgcolor': falsyFilter, - - // Deprecate 'valign' attribute in favor of 'vertical-align'. - 'valign': removeStyles ? falsyFilter : function( value, element ) { - element.addStyle( 'vertical-align', value ); - return false; - } - }, - - // Fore none-IE, some useful data might be buried under these IE-conditional - // comments where RegExp were the right approach to dig them out where usual approach - // is transform it into a fake element node which hold the desired data. - comment: !CKEDITOR.env.ie ? function( value, node ) { - var imageInfo = value.match( /<img.*?>/ ), - listInfo = value.match( /^\[if !supportLists\]([\s\S]*?)\[endif\]$/ ); - - // Seek for list bullet indicator. - if ( listInfo ) { - // Bullet symbol could be either text or an image. - var listSymbol = listInfo[ 1 ] || ( imageInfo && 'l.' ), - listType = listSymbol && listSymbol.match( />(?:[(]?)([^\s]+?)([.)]?)</ ); - return createListBulletMarker( listType, listSymbol ); - } - - // Reveal the <img> element in conditional comments for Firefox. - if ( CKEDITOR.env.gecko && imageInfo ) { - var img = CKEDITOR.htmlParser.fragment.fromHtml( imageInfo[ 0 ] ).children[ 0 ], - previousComment = node.previous, - // Try to dig the real image link from vml markup from previous comment text. - imgSrcInfo = previousComment && previousComment.value.match( /<v:imagedata[^>]*o:href=['"](.*?)['"]/ ), - imgSrc = imgSrcInfo && imgSrcInfo[ 1 ]; - - // Is there a real 'src' url to be used? - imgSrc && ( img.attributes.src = imgSrc ); - return img; - } - - return false; - } : falsyFilter - }; - } - }); - - // The paste processor here is just a reduced copy of html data processor. - var pasteProcessor = function() { - this.dataFilter = new CKEDITOR.htmlParser.filter(); - }; - - pasteProcessor.prototype = { - toHtml: function( data ) { - var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data ), - writer = new CKEDITOR.htmlParser.basicWriter(); - - fragment.writeHtml( writer, this.dataFilter ); - return writer.getHtml( true ); - } - }; - - CKEDITOR.cleanWord = function( data, editor ) { - // Firefox will be confused by those downlevel-revealed IE conditional - // comments, fixing them first( convert it to upperlevel-revealed one ). - // e.g. <![if !vml]>...<![endif]> - if ( CKEDITOR.env.gecko ) - data = data.replace( /(<!--\[if[^<]*?\])-->([\S\s]*?)<!--(\[endif\]-->)/gi, '$1$2$3' ); - - // #9456 - Webkit doesn't wrap list number with span, which is crucial for filter to recognize list. - // - // <p class="MsoListParagraphCxSpLast" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"> - // <!--[if !supportLists]--> - // 3.<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';"> </span> - // <!--[endif]-->Test3<o:p></o:p> - // </p> - // - // Transform to: - // - // <p class="MsoListParagraphCxSpLast" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"> - // <!--[if !supportLists]--> - // <span> - // 3.<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';"> </span> - // </span> - // <!--[endif]-->Test3<o:p></o:p> - // </p> - if ( CKEDITOR.env.webkit ) { - data = data.replace( /(class="MsoListParagraph[^>]+><!--\[if !supportLists\]-->)([^<]+<span[^<]+<\/span>)(<!--\[endif\]-->)/gi, '$1<span>$2</span>$3' ); - } - - var dataProcessor = new pasteProcessor(), - dataFilter = dataProcessor.dataFilter; - - // These rules will have higher priorities than default ones. - dataFilter.addRules( CKEDITOR.plugins.pastefromword.getRules( editor, dataFilter ) ); - - // Allow extending data filter rules. - editor.fire( 'beforeCleanWord', { filter: dataFilter } ); - - try { - data = dataProcessor.toHtml( data ); - } catch ( e ) { - alert( editor.lang.pastefromword.error ); - } - - // Below post processing those things that are unable to delivered by filter rules. - - // Remove 'cke' namespaced attribute used in filter rules as marker. - data = data.replace( /cke:.*?".*?"/g, '' ); - - // Remove empty style attribute. - data = data.replace( /style=""/g, '' ); - - // Remove the dummy spans ( having no inline style ). - data = data.replace( /<span>/g, '' ); - - return data; - }; -})(); - -/** - * Whether to ignore all font related formatting styles, including: - * - * * font size; - * * font family; - * * font foreground/background color. - * - * config.pasteFromWordRemoveFontStyles = false; - * - * @since 3.1 - * @cfg {Boolean} [pasteFromWordRemoveFontStyles=true] - * @member CKEDITOR.config - */ - -/** - * Whether to transform MS Word outline numbered headings into lists. - * - * config.pasteFromWordNumberedHeadingToList = true; - * - * @since 3.1 - * @cfg {Boolean} [pasteFromWordNumberedHeadingToList=false] - * @member CKEDITOR.config - */ - -/** - * Whether to remove element styles that can't be managed with the editor. Note - * that this doesn't handle the font specific styles, which depends on the - * {@link #pasteFromWordRemoveFontStyles} setting instead. - * - * config.pasteFromWordRemoveStyles = false; - * - * @since 3.1 - * @cfg {Boolean} [pasteFromWordRemoveStyles=true] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword-rtl.png b/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword-rtl.png Binary files differdeleted file mode 100644 index 142bd569526..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword.png b/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword.png Binary files differdeleted file mode 100644 index ac043cddb89..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/hidpi/pastefromword.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword-rtl.png b/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword-rtl.png Binary files differdeleted file mode 100644 index 7b69c5550c3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword.png b/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword.png Binary files differdeleted file mode 100644 index 61a0ae43f58..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/icons/pastefromword.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/lang/en.js b/addons/website/static/lib/ckeditor/plugins/pastefromword/lang/en.js deleted file mode 100644 index c7bcc72f1de..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/lang/en.js +++ /dev/null @@ -1,10 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'pastefromword', 'en', { - confirmCleanup: 'The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?', - error: 'It was not possible to clean up the pasted data due to an internal error', - title: 'Paste from Word', - toolbar: 'Paste from Word' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/pastefromword/plugin.js b/addons/website/static/lib/ckeditor/plugins/pastefromword/plugin.js deleted file mode 100755 index fab69245b9b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastefromword/plugin.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.add( 'pastefromword', { - requires: 'clipboard', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'pastefromword,pastefromword-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var commandName = 'pastefromword', - // Flag indicate this command is actually been asked instead of a generic pasting. - forceFromWord = 0, - path = this.path; - - editor.addCommand( commandName, { - // Snapshots are done manually by editable.insertXXX methods. - canUndo: false, - async: true, - - exec: function( editor ) { - var cmd = this; - - forceFromWord = 1; - // Force html mode for incomming paste events sequence. - editor.once( 'beforePaste', forceHtmlMode ); - - editor.getClipboardData({ title: editor.lang.pastefromword.title }, function( data ) { - // Do not use editor#paste, because it would start from beforePaste event. - data && editor.fire( 'paste', { type: 'html', dataValue: data.dataValue } ); - - editor.fire( 'afterCommandExec', { - name: commandName, - command: cmd, - returnValue: !!data - }); - }); - } - }); - - // Register the toolbar button. - editor.ui.addButton && editor.ui.addButton( 'PasteFromWord', { - label: editor.lang.pastefromword.toolbar, - command: commandName, - toolbar: 'clipboard,50' - }); - - editor.on( 'pasteState', function( evt ) { - editor.getCommand( commandName ).setState( evt.data ); - }); - - // Features bring by this command beside the normal process: - // 1. No more bothering of user about the clean-up. - // 2. Perform the clean-up even if content is not from MS-Word. - // (e.g. from a MS-Word similar application.) - // 3. Listen with high priority (3), so clean up is done before content - // type sniffing (priority = 6). - editor.on( 'paste', function( evt ) { - var data = evt.data, - mswordHtml = data.dataValue; - - // MS-WORD format sniffing. - if ( mswordHtml && ( forceFromWord || ( /(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/ ).test( mswordHtml ) ) ) { - // If filter rules aren't loaded then cancel 'paste' event, - // load them and when they'll get loaded fire new paste event - // for which data will be filtered in second execution of - // this listener. - var isLazyLoad = loadFilterRules( editor, path, function() { - // Event continuation with the original data. - if ( isLazyLoad ) - editor.fire( 'paste', data ); - else if ( !editor.config.pasteFromWordPromptCleanup || ( forceFromWord || confirm( editor.lang.pastefromword.confirmCleanup ) ) ) { - data.dataValue = CKEDITOR.cleanWord( mswordHtml, editor ); - } - }); - - // The cleanup rules are to be loaded, we should just cancel - // this event. - isLazyLoad && evt.cancel(); - } - }, null, null, 3 ); - - function resetFromWord( evt ) { - evt && evt.removeListener(); - editor.removeListener( 'beforePaste', forceHtmlMode ); - forceFromWord && setTimeout( function() { - forceFromWord = 0; - }, 0 ); - } - } - - }); - - function loadFilterRules( editor, path, callback ) { - var isLoaded = CKEDITOR.cleanWord; - - if ( isLoaded ) - callback(); - else { - var filterFilePath = CKEDITOR.getUrl( editor.config.pasteFromWordCleanupFile || ( path + 'filter/default.js' ) ); - - // Load with busy indicator. - CKEDITOR.scriptLoader.load( filterFilePath, callback, null, true ); - } - - return !isLoaded; - } - - function forceHtmlMode( evt ) { - evt.data.type = 'html'; - } -})(); - - -/** - * Whether to prompt the user about the clean up of content being pasted from MS Word. - * - * config.pasteFromWordPromptCleanup = true; - * - * @since 3.1 - * @cfg {Boolean} [pasteFromWordPromptCleanup=false] - * @member CKEDITOR.config - */ - -/** - * The file that provides the MS Word cleanup function for pasting operations. - * - * **Note:** This is a global configuration shared by all editor instances present - * in the page. - * - * // Load from 'pastefromword' plugin 'filter' sub folder (custom.js file) using path relative to CKEditor installation folder. - * CKEDITOR.config.pasteFromWordCleanupFile = 'plugins/pastefromword/filter/custom.js'; - * - * // Load from 'pastefromword' plugin 'filter' sub folder (custom.js file) using full path (including CKEditor installation folder). - * CKEDITOR.config.pasteFromWordCleanupFile = '/ckeditor/plugins/pastefromword/filter/custom.js'; - * - * // Load custom.js file from 'customFilerts' folder (located in server's root) using full URL. - * CKEDITOR.config.pasteFromWordCleanupFile = 'http://my.example.com/customFilerts/custom.js'; - * - * @since 3.1 - * @cfg {String} [pasteFromWordCleanupFile=<plugin path> + 'filter/default.js'] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext-rtl.png b/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext-rtl.png Binary files differdeleted file mode 100644 index 35354a5f8d9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext.png b/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext.png Binary files differdeleted file mode 100644 index f82900fa997..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/hidpi/pastetext.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext-rtl.png b/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext-rtl.png Binary files differdeleted file mode 100644 index 9393b347f19..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext.png b/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext.png Binary files differdeleted file mode 100644 index 20816a4f460..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/icons/pastetext.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/lang/en.js b/addons/website/static/lib/ckeditor/plugins/pastetext/lang/en.js deleted file mode 100644 index 131594e5fa8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'pastetext', 'en', { - button: 'Paste as plain text', - title: 'Paste as Plain Text' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/pastetext/plugin.js b/addons/website/static/lib/ckeditor/plugins/pastetext/plugin.js deleted file mode 100644 index ce9c5587694..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/pastetext/plugin.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Paste as plain text plugin. - */ - -(function() { - // The pastetext command definition. - var pasteTextCmd = { - // Snapshots are done manually by editable.insertXXX methods. - canUndo: false, - async: true, - - exec: function( editor ) { - editor.getClipboardData({ title: editor.lang.pastetext.title }, function( data ) { - // Do not use editor#paste, because it would start from beforePaste event. - data && editor.fire( 'paste', { type: 'text', dataValue: data.dataValue } ); - - editor.fire( 'afterCommandExec', { - name: 'pastetext', - command: pasteTextCmd, - returnValue: !!data - }); - }); - } - }; - - // Register the plugin. - CKEDITOR.plugins.add( 'pastetext', { - requires: 'clipboard', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'pastetext,pastetext-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var commandName = 'pastetext'; - - editor.addCommand( commandName, pasteTextCmd ); - - editor.ui.addButton && editor.ui.addButton( 'PasteText', { - label: editor.lang.pastetext.button, - command: commandName, - toolbar: 'clipboard,40' - }); - - if ( editor.config.forcePasteAsPlainText ) { - editor.on( 'beforePaste', function( evt ) { - // Do NOT overwrite if HTML format is explicitly requested. - // This allows pastefromword dominates over pastetext. - if ( evt.data.type != 'html' ) - evt.data.type = 'text'; - }); - } - - editor.on( 'pasteState', function( evt ) { - editor.getCommand( commandName ).setState( evt.data ); - }); - } - }); -})(); - - -/** - * Whether to force all pasting operations to insert on plain text into the - * editor, loosing any formatting information possibly available in the source - * text. - * - * **Note:** paste from word (dialog) is not affected by this configuration. - * - * config.forcePasteAsPlainText = true; - * - * @cfg {Boolean} [forcePasteAsPlainText=false] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/placeholder/dialogs/placeholder.js b/addons/website/static/lib/ckeditor/plugins/placeholder/dialogs/placeholder.js deleted file mode 100644 index 2789246cee6..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/placeholder/dialogs/placeholder.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - function placeholderDialog( editor, isEdit ) { - - var lang = editor.lang.placeholder, - generalLabel = editor.lang.common.generalTab; - return { - title: lang.title, - minWidth: 300, - minHeight: 80, - contents: [ - { - id: 'info', - label: generalLabel, - title: generalLabel, - elements: [ - { - id: 'text', - type: 'text', - style: 'width: 100%;', - label: lang.text, - 'default': '', - required: true, - validate: CKEDITOR.dialog.validate.notEmpty( lang.textMissing ), - setup: function( element ) { - if ( isEdit ) - this.setValue( element.getText().slice( 2, -2 ) ); - }, - commit: function( element ) { - var text = '[[' + this.getValue() + ']]'; - // The placeholder must be recreated. - CKEDITOR.plugins.placeholder.createPlaceholder( editor, element, text ); - } - } - ] - } - ], - onShow: function() { - if ( isEdit ) - this._element = CKEDITOR.plugins.placeholder.getSelectedPlaceHolder( editor ); - - this.setupContent( this._element ); - }, - onOk: function() { - this.commitContent( this._element ); - delete this._element; - } - }; - } - - CKEDITOR.dialog.add( 'createplaceholder', function( editor ) { - return placeholderDialog( editor ); - }); - CKEDITOR.dialog.add( 'editplaceholder', function( editor ) { - return placeholderDialog( editor, 1 ); - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/placeholder/icons/hidpi/placeholder.png b/addons/website/static/lib/ckeditor/plugins/placeholder/icons/hidpi/placeholder.png Binary files differdeleted file mode 100644 index 0b7abcec8ae..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/placeholder/icons/hidpi/placeholder.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/placeholder/icons/placeholder.png b/addons/website/static/lib/ckeditor/plugins/placeholder/icons/placeholder.png Binary files differdeleted file mode 100644 index cb12b481452..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/placeholder/icons/placeholder.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/placeholder/lang/en.js b/addons/website/static/lib/ckeditor/plugins/placeholder/lang/en.js deleted file mode 100644 index 61b8185c304..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/placeholder/lang/en.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'placeholder', 'en', { - title: 'Placeholder Properties', - toolbar: 'Create Placeholder', - text: 'Placeholder Text', - edit: 'Edit Placeholder', - textMissing: 'The placeholder must contain text.' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/placeholder/plugin.js b/addons/website/static/lib/ckeditor/plugins/placeholder/plugin.js deleted file mode 100644 index f49ccb02171..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/placeholder/plugin.js +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "placeholder" plugin. - * - */ - -(function() { - var placeholderReplaceRegex = /\[\[[^\]]+\]\]/g; - CKEDITOR.plugins.add( 'placeholder', { - requires: 'dialog', - lang: 'en,bg,cs,cy,da,de,el,eo,et,fa,fi,fr,he,hr,it,ku,nb,nl,no,pl,tr,ug,uk,vi,zh-cn', // %REMOVE_LINE_CORE% - icons: 'placeholder', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - CKEDITOR.addCss( '.cke_placeholder' + - '{' + - 'background-color: #ffff00;' + - ( CKEDITOR.env.gecko ? 'cursor: default;' : '' ) + - '}' - ); - }, - init: function( editor ) { - var lang = editor.lang.placeholder; - - editor.addCommand( 'createplaceholder', new CKEDITOR.dialogCommand( 'createplaceholder' ) ); - editor.addCommand( 'editplaceholder', new CKEDITOR.dialogCommand( 'editplaceholder' ) ); - - editor.ui.addButton && editor.ui.addButton( 'CreatePlaceholder', { - label: lang.toolbar, - command: 'createplaceholder', - toolbar: 'insert,5', - icon: 'placeholder' - }); - - if ( editor.addMenuItems ) { - editor.addMenuGroup( 'placeholder', 20 ); - editor.addMenuItems({ - editplaceholder: { - label: lang.edit, - command: 'editplaceholder', - group: 'placeholder', - order: 1, - icon: 'placeholder' - } - }); - - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection ) { - if ( !element || !element.data( 'cke-placeholder' ) ) - return null; - - return { editplaceholder: CKEDITOR.TRISTATE_OFF }; - }); - } - } - - editor.on( 'doubleclick', function( evt ) { - if ( CKEDITOR.plugins.placeholder.getSelectedPlaceHolder( editor ) ) - evt.data.dialog = 'editplaceholder'; - }); - - editor.on( 'contentDom', function() { - editor.editable().on( 'resizestart', function( evt ) { - if ( editor.getSelection().getSelectedElement().data( 'cke-placeholder' ) ) - evt.data.preventDefault(); - }); - }); - - CKEDITOR.dialog.add( 'createplaceholder', this.path + 'dialogs/placeholder.js' ); - CKEDITOR.dialog.add( 'editplaceholder', this.path + 'dialogs/placeholder.js' ); - }, - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter, - htmlFilter = dataProcessor && dataProcessor.htmlFilter; - - if ( dataFilter ) { - dataFilter.addRules({ - text: function( text ) { - return text.replace( placeholderReplaceRegex, function( match ) { - return CKEDITOR.plugins.placeholder.createPlaceholder( editor, null, match, 1 ); - }); - } - }); - } - - if ( htmlFilter ) { - htmlFilter.addRules({ - elements: { - 'span': function( element ) { - if ( element.attributes && element.attributes[ 'data-cke-placeholder' ] ) - delete element.name; - } - } - }); - } - } - }); -})(); - -CKEDITOR.plugins.placeholder = { - createPlaceholder: function( editor, oldElement, text, isGet ) { - var element = new CKEDITOR.dom.element( 'span', editor.document ); - element.setAttributes({ - contentEditable: 'false', - 'data-cke-placeholder': 1, - 'class': 'cke_placeholder' - }); - - text && element.setText( text ); - - if ( isGet ) - return element.getOuterHtml(); - - if ( oldElement ) { - if ( CKEDITOR.env.ie ) { - element.insertAfter( oldElement ); - // Some time is required for IE before the element is removed. - setTimeout( function() { - oldElement.remove(); - element.focus(); - }, 10 ); - } else - element.replace( oldElement ); - } else - editor.insertElement( element ); - - return null; - }, - - getSelectedPlaceHolder: function( editor ) { - var range = editor.getSelection().getRanges()[ 0 ]; - range.shrink( CKEDITOR.SHRINK_TEXT ); - var node = range.startContainer; - while ( node && !( node.type == CKEDITOR.NODE_ELEMENT && node.data( 'cke-placeholder' ) ) ) - node = node.getParent(); - return node; - } -}; diff --git a/addons/website/static/lib/ckeditor/plugins/popup/plugin.js b/addons/website/static/lib/ckeditor/plugins/popup/plugin.js deleted file mode 100644 index a8b5b72af20..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/popup/plugin.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'popup' ); - -CKEDITOR.tools.extend( CKEDITOR.editor.prototype, { - /** - * Opens Browser in a popup. The `width` and `height` parameters accept - * numbers (pixels) or percent (of screen size) values. - * - * @member CKEDITOR.editor - * @param {String} url The url of the external file browser. - * @param {Number/String} [width='80%'] Popup window width. - * @param {Number/String} [height='70%'] Popup window height. - * @param {String} [options='location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes'] - * Popup window features. - */ - popup: function( url, width, height, options ) { - width = width || '80%'; - height = height || '70%'; - - if ( typeof width == 'string' && width.length > 1 && width.substr( width.length - 1, 1 ) == '%' ) - width = parseInt( window.screen.width * parseInt( width, 10 ) / 100, 10 ); - - if ( typeof height == 'string' && height.length > 1 && height.substr( height.length - 1, 1 ) == '%' ) - height = parseInt( window.screen.height * parseInt( height, 10 ) / 100, 10 ); - - if ( width < 640 ) - width = 640; - - if ( height < 420 ) - height = 420; - - var top = parseInt( ( window.screen.height - height ) / 2, 10 ), - left = parseInt( ( window.screen.width - width ) / 2, 10 ); - - options = ( options || 'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes' ) + ',width=' + width + - ',height=' + height + - ',top=' + top + - ',left=' + left; - - var popupWindow = window.open( '', null, options, true ); - - // Blocked by a popup blocker. - if ( !popupWindow ) - return false; - - try { - // Chrome is problematic with moveTo/resizeTo, but it's not really needed here (#8855). - var ua = navigator.userAgent.toLowerCase(); - if ( ua.indexOf( ' chrome/' ) == -1 ) { - popupWindow.moveTo( left, top ); - popupWindow.resizeTo( width, height ); - } - popupWindow.focus(); - popupWindow.location.href = url; - } catch ( e ) { - popupWindow = window.open( url, null, options, true ); - } - - return true; - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview-rtl.png b/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview-rtl.png Binary files differdeleted file mode 100644 index cd64e19a87a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview.png b/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview.png Binary files differdeleted file mode 100644 index 402db20e277..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/icons/hidpi/preview.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/preview/icons/preview-rtl.png b/addons/website/static/lib/ckeditor/plugins/preview/icons/preview-rtl.png Binary files differdeleted file mode 100644 index 1c9d97874ca..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/icons/preview-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/preview/icons/preview.png b/addons/website/static/lib/ckeditor/plugins/preview/icons/preview.png Binary files differdeleted file mode 100644 index 162b44b845a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/icons/preview.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/preview/lang/en.js b/addons/website/static/lib/ckeditor/plugins/preview/lang/en.js deleted file mode 100644 index f06bb819cbc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'preview', 'en', { - preview: 'Preview' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/preview/plugin.js b/addons/website/static/lib/ckeditor/plugins/preview/plugin.js deleted file mode 100644 index acbe2453bcb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/plugin.js +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Preview plugin. - */ - -(function() { - var pluginPath; - - var previewCmd = { modes:{wysiwyg:1,source:1 }, - canUndo: false, - readOnly: 1, - exec: function( editor ) { - var sHTML, - config = editor.config, - baseTag = config.baseHref ? '<base href="' + config.baseHref + '"/>' : '', - eventData; - - if ( config.fullPage ) { - sHTML = editor.getData().replace( /<head>/, '$&' + baseTag ).replace( /[^>]*(?=<\/title>)/, '$& — ' + editor.lang.preview.preview ); - } else { - var bodyHtml = '<body ', - body = editor.document && editor.document.getBody(); - - if ( body ) { - if ( body.getAttribute( 'id' ) ) - bodyHtml += 'id="' + body.getAttribute( 'id' ) + '" '; - if ( body.getAttribute( 'class' ) ) - bodyHtml += 'class="' + body.getAttribute( 'class' ) + '" '; - } - - bodyHtml += '>'; - - sHTML = editor.config.docType + '<html dir="' + editor.config.contentsLangDirection + '">' + - '<head>' + - baseTag + - '<title>' + editor.lang.preview.preview + '</title>' + - CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss ) + - '</head>' + bodyHtml + - editor.getData() + - '</body></html>'; - } - - var iWidth = 640, - // 800 * 0.8, - iHeight = 420, - // 600 * 0.7, - iLeft = 80; // (800 - 0.8 * 800) /2 = 800 * 0.1. - try { - var screen = window.screen; - iWidth = Math.round( screen.width * 0.8 ); - iHeight = Math.round( screen.height * 0.7 ); - iLeft = Math.round( screen.width * 0.1 ); - } catch ( e ) {} - - // (#9907) Allow data manipulation before preview is displayed. - // Also don't open the preview window when event cancelled. - if ( !editor.fire( 'contentPreview', eventData = { dataValue: sHTML } ) ) - return false; - - var sOpenUrl = ''; - if ( CKEDITOR.env.ie ) { - window._cke_htmlToLoad = eventData.dataValue; - sOpenUrl = 'javascript:void( (function(){' + - 'document.open();' + - // Support for custom document.domain. - // Strip comments and replace parent with window.opener in the function body. - ( '(' + CKEDITOR.tools.fixDomain + ')();' ).replace( /\/\/.*?\n/g, '' ).replace( /parent\./g, 'window.opener.' ) + - 'document.write( window.opener._cke_htmlToLoad );' + - 'document.close();' + - 'window.opener._cke_htmlToLoad = null;' + - '})() )'; - } - - // With Firefox only, we need to open a special preview page, so - // anchors will work properly on it. (#9047) - if ( CKEDITOR.env.gecko ) { - window._cke_htmlToLoad = eventData.dataValue; - sOpenUrl = pluginPath + 'preview.html'; - } - - var oWindow = window.open( sOpenUrl, null, 'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width=' + - iWidth + ',height=' + iHeight + ',left=' + iLeft ); - - if ( !CKEDITOR.env.ie && !CKEDITOR.env.gecko ) { - var doc = oWindow.document; - doc.open(); - doc.write( eventData.dataValue ); - doc.close(); - - // Chrome will need this to show the embedded. (#8016) - CKEDITOR.env.webkit && setTimeout( function() { - doc.body.innerHTML += ''; - }, 0 ); - } - - return true; - } - }; - - var pluginName = 'preview'; - - // Register a plugin named "preview". - CKEDITOR.plugins.add( pluginName, { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'preview,preview-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - - // Preview is not used for the inline creator. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - return; - - pluginPath = this.path; - - editor.addCommand( pluginName, previewCmd ); - editor.ui.addButton && editor.ui.addButton( 'Preview', { - label: editor.lang.preview.preview, - command: pluginName, - toolbar: 'document,40' - }); - } - }); -})(); - -/** - * Event fired when executing `preview` command, which allows additional data manipulation. - * With this event, the raw HTML content of the preview window to be displayed can be altered - * or modified. - * - * @event contentPreview - * @member CKEDITOR - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {String} data.dataValue The data that will go to the preview. - */
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/preview/preview.html b/addons/website/static/lib/ckeditor/plugins/preview/preview.html deleted file mode 100644 index f515ac42422..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/preview/preview.html +++ /dev/null @@ -1,10 +0,0 @@ -<script> - -var doc = document; -doc.open(); -doc.write( window.opener._cke_htmlToLoad ); -doc.close(); - -delete window.opener._cke_htmlToLoad; - -</script> diff --git a/addons/website/static/lib/ckeditor/plugins/print/icons/hidpi/print.png b/addons/website/static/lib/ckeditor/plugins/print/icons/hidpi/print.png Binary files differdeleted file mode 100644 index 4b72460dd4f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/print/icons/hidpi/print.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/print/icons/print.png b/addons/website/static/lib/ckeditor/plugins/print/icons/print.png Binary files differdeleted file mode 100644 index 06f797dc728..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/print/icons/print.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/print/lang/en.js b/addons/website/static/lib/ckeditor/plugins/print/lang/en.js deleted file mode 100644 index dee9b3d7025..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/print/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'print', 'en', { - toolbar: 'Print' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/print/plugin.js b/addons/website/static/lib/ckeditor/plugins/print/plugin.js deleted file mode 100644 index 345f86013f7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/print/plugin.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Print Plugin - */ - -CKEDITOR.plugins.add( 'print', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'print,', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - // Print plugin isn't available in inline mode yet. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - return; - - var pluginName = 'print'; - - // Register the command. - var command = editor.addCommand( pluginName, CKEDITOR.plugins.print ); - - // Register the toolbar button. - editor.ui.addButton && editor.ui.addButton( 'Print', { - label: editor.lang.print.toolbar, - command: pluginName, - toolbar: 'document,50' - }); - } -}); - -CKEDITOR.plugins.print = { - exec: function( editor ) { - if ( CKEDITOR.env.opera ) - return; - else if ( CKEDITOR.env.gecko ) - editor.window.$.print(); - else - editor.document.$.execCommand( "Print" ); - }, - canUndo: false, - readOnly: 1, - modes: { wysiwyg: !( CKEDITOR.env.opera ) } // It is imposible to print the inner document in Opera. -}; diff --git a/addons/website/static/lib/ckeditor/plugins/removeformat/icons/hidpi/removeformat.png b/addons/website/static/lib/ckeditor/plugins/removeformat/icons/hidpi/removeformat.png Binary files differdeleted file mode 100644 index 910b0a3c8f5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/removeformat/icons/hidpi/removeformat.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/removeformat/icons/removeformat.png b/addons/website/static/lib/ckeditor/plugins/removeformat/icons/removeformat.png Binary files differdeleted file mode 100644 index 1bc9b38601a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/removeformat/icons/removeformat.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/removeformat/lang/en.js b/addons/website/static/lib/ckeditor/plugins/removeformat/lang/en.js deleted file mode 100644 index 29fa4dfd921..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/removeformat/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'removeformat', 'en', { - toolbar: 'Remove Format' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/removeformat/plugin.js b/addons/website/static/lib/ckeditor/plugins/removeformat/plugin.js deleted file mode 100644 index cf44666b394..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/removeformat/plugin.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'removeformat', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'removeformat', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.addCommand( 'removeFormat', CKEDITOR.plugins.removeformat.commands.removeformat ); - editor.ui.addButton && editor.ui.addButton( 'RemoveFormat', { - label: editor.lang.removeformat.toolbar, - command: 'removeFormat', - toolbar: 'cleanup,10' - }); - } -}); - -CKEDITOR.plugins.removeformat = { - commands: { - removeformat: { - exec: function( editor ) { - var tagsRegex = editor._.removeFormatRegex || ( editor._.removeFormatRegex = new RegExp( '^(?:' + editor.config.removeFormatTags.replace( /,/g, '|' ) + ')$', 'i' ) ); - - var removeAttributes = editor._.removeAttributes || ( editor._.removeAttributes = editor.config.removeFormatAttributes.split( ',' ) ); - - var filter = CKEDITOR.plugins.removeformat.filter; - var ranges = editor.getSelection().getRanges( 1 ), - iterator = ranges.createIterator(), - range; - - while ( ( range = iterator.getNextRange() ) ) { - if ( !range.collapsed ) - range.enlarge( CKEDITOR.ENLARGE_ELEMENT ); - - // Bookmark the range so we can re-select it after processing. - var bookmark = range.createBookmark(), - // The style will be applied within the bookmark boundaries. - startNode = bookmark.startNode, - endNode = bookmark.endNode, - currentNode; - - // We need to check the selection boundaries (bookmark spans) to break - // the code in a way that we can properly remove partially selected nodes. - // For example, removing a <b> style from - // <b>This is [some text</b> to show <b>the] problem</b> - // ... where [ and ] represent the selection, must result: - // <b>This is </b>[some text to show the]<b> problem</b> - // The strategy is simple, we just break the partial nodes before the - // removal logic, having something that could be represented this way: - // <b>This is </b>[<b>some text</b> to show <b>the</b>]<b> problem</b> - - var breakParent = function( node ) { - // Let's start checking the start boundary. - var path = editor.elementPath( node ), - pathElements = path.elements; - - for ( var i = 1, pathElement; pathElement = pathElements[ i ]; i++ ) { - if ( pathElement.equals( path.block ) || pathElement.equals( path.blockLimit ) ) - break; - - // If this element can be removed (even partially). - if ( tagsRegex.test( pathElement.getName() ) && filter( editor, pathElement ) ) - node.breakParent( pathElement ); - } - }; - - breakParent( startNode ); - if ( endNode ) { - breakParent( endNode ); - - // Navigate through all nodes between the bookmarks. - currentNode = startNode.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT ); - - while ( currentNode ) { - // If we have reached the end of the selection, stop looping. - if ( currentNode.equals( endNode ) ) - break; - - // Cache the next node to be processed. Do it now, because - // currentNode may be removed. - var nextNode = currentNode.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ); - - // This node must not be a fake element. - if ( !( currentNode.getName() == 'img' && currentNode.data( 'cke-realelement' ) ) && filter( editor, currentNode ) ) { - // Remove elements nodes that match with this style rules. - if ( tagsRegex.test( currentNode.getName() ) ) - currentNode.remove( 1 ); - else { - currentNode.removeAttributes( removeAttributes ); - editor.fire( 'removeFormatCleanup', currentNode ); - } - } - - currentNode = nextNode; - } - } - - range.moveToBookmark( bookmark ); - } - - // The selection path may not changed, but we should force a selection - // change event to refresh command states, due to the above attribution change. (#9238) - editor.forceNextSelectionCheck(); - editor.getSelection().selectRanges( ranges ); - } - } - }, - - // Perform the remove format filters on the passed element. - // @param {CKEDITOR.editor} editor - // @param {CKEDITOR.dom.element} element - filter: function( editor, element ) { - // If editor#addRemoveFotmatFilter hasn't been executed yet value is not initialized. - var filters = editor._.removeFormatFilters || []; - for ( var i = 0; i < filters.length; i++ ) { - if ( filters[ i ]( element ) === false ) - return false; - } - return true; - } -}; - -/** - * Add to a collection of functions to decide whether a specific - * element should be considered as formatting element and thus - * could be removed during `removeFormat` command. - * - * **Note:** Only available with the existence of `removeformat` plugin. - * - * // Don't remove empty span. - * editor.addRemoveFormatFilter( function( element ) { - * return !( element.is( 'span' ) && CKEDITOR.tools.isEmpty( element.getAttributes() ) ); - * } ); - * - * @since 3.3 - * @member CKEDITOR.editor - * @param {Function} func The function to be called, which will be passed a {CKEDITOR.dom.element} element to test. - */ -CKEDITOR.editor.prototype.addRemoveFormatFilter = function( func ) { - if ( !this._.removeFormatFilters ) - this._.removeFormatFilters = []; - - this._.removeFormatFilters.push( func ); -}; - -/** - * A comma separated list of elements to be removed when executing the `remove - * format` command. Note that only inline elements are allowed. - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var'; - -/** - * A comma separated list of elements attributes to be removed when executing - * the `remove format` command. - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.removeFormatAttributes = 'class,style,lang,width,height,align,hspace,valign'; - -/** - * Fired after an element was cleaned by the removeFormat plugin. - * - * @event removeFormatCleanup - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param data - * @param {CKEDITOR.dom.element} data.element The element that was cleaned up. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/resize/plugin.js b/addons/website/static/lib/ckeditor/plugins/resize/plugin.js deleted file mode 100644 index 7c7750a8594..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/resize/plugin.js +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'resize', { - init: function( editor ) { - var config = editor.config; - var spaceId = editor.ui.spaceId( 'resizer' ); - - // Resize in the same direction of chrome, - // which is identical to dir of editor element. (#6614) - var resizeDir = editor.element ? editor.element.getDirection( 1 ) : 'ltr'; - - !config.resize_dir && ( config.resize_dir = 'vertical' ); - ( config.resize_maxWidth == undefined ) && ( config.resize_maxWidth = 3000 ); - ( config.resize_maxHeight == undefined ) && ( config.resize_maxHeight = 3000 ); - ( config.resize_minWidth == undefined ) && ( config.resize_minWidth = 750 ); - ( config.resize_minHeight == undefined ) && ( config.resize_minHeight = 250 ); - - if ( config.resize_enabled !== false ) { - var container = null, - origin, startSize, - resizeHorizontal = ( config.resize_dir == 'both' || config.resize_dir == 'horizontal' ) && ( config.resize_minWidth != config.resize_maxWidth ), - resizeVertical = ( config.resize_dir == 'both' || config.resize_dir == 'vertical' ) && ( config.resize_minHeight != config.resize_maxHeight ); - - function dragHandler( evt ) { - var dx = evt.data.$.screenX - origin.x, - dy = evt.data.$.screenY - origin.y, - width = startSize.width, - height = startSize.height, - internalWidth = width + dx * ( resizeDir == 'rtl' ? -1 : 1 ), - internalHeight = height + dy; - - if ( resizeHorizontal ) - width = Math.max( config.resize_minWidth, Math.min( internalWidth, config.resize_maxWidth ) ); - - if ( resizeVertical ) - height = Math.max( config.resize_minHeight, Math.min( internalHeight, config.resize_maxHeight ) ); - - // DO NOT impose fixed size with single direction resize. (#6308) - editor.resize( resizeHorizontal ? width : null, height ); - } - - function dragEndHandler( evt ) { - CKEDITOR.document.removeListener( 'mousemove', dragHandler ); - CKEDITOR.document.removeListener( 'mouseup', dragEndHandler ); - - if ( editor.document ) { - editor.document.removeListener( 'mousemove', dragHandler ); - editor.document.removeListener( 'mouseup', dragEndHandler ); - } - } - - var mouseDownFn = CKEDITOR.tools.addFunction( function( $event ) { - if ( !container ) - container = editor.getResizable(); - - startSize = { width: container.$.offsetWidth || 0, height: container.$.offsetHeight || 0 }; - origin = { x: $event.screenX, y: $event.screenY }; - - config.resize_minWidth > startSize.width && ( config.resize_minWidth = startSize.width ); - config.resize_minHeight > startSize.height && ( config.resize_minHeight = startSize.height ); - - CKEDITOR.document.on( 'mousemove', dragHandler ); - CKEDITOR.document.on( 'mouseup', dragEndHandler ); - - if ( editor.document ) { - editor.document.on( 'mousemove', dragHandler ); - editor.document.on( 'mouseup', dragEndHandler ); - } - - $event.preventDefault && $event.preventDefault(); - }); - - editor.on( 'destroy', function() { - CKEDITOR.tools.removeFunction( mouseDownFn ); - }); - - editor.on( 'uiSpace', function( event ) { - if ( event.data.space == 'bottom' ) { - var direction = ''; - if ( resizeHorizontal && !resizeVertical ) - direction = ' cke_resizer_horizontal'; - if ( !resizeHorizontal && resizeVertical ) - direction = ' cke_resizer_vertical'; - - var resizerHtml = - '<span' + - ' id="' + spaceId + '"' + - ' class="cke_resizer' + direction + ' cke_resizer_' + resizeDir + '"' + - ' title="' + CKEDITOR.tools.htmlEncode( editor.lang.common.resize ) + '"' + - ' onmousedown="CKEDITOR.tools.callFunction(' + mouseDownFn + ', event)"' + - '>' + - // BLACK LOWER RIGHT TRIANGLE (ltr) - // BLACK LOWER LEFT TRIANGLE (rtl) - ( resizeDir == 'ltr' ? '\u25E2' : '\u25E3' ) + - '</span>'; - - // Always sticks the corner of botttom space. - resizeDir == 'ltr' && direction == 'ltr' ? event.data.html += resizerHtml : event.data.html = resizerHtml + event.data.html; - } - }, editor, null, 100 ); - - // Toggle the visibility of the resizer when an editor is being maximized or minimized. - editor.on( 'maximize', function( event ) { - editor.ui.space( 'resizer' )[ event.data == CKEDITOR.TRISTATE_ON ? 'hide' : 'show' ](); - }); - } - } -}); - -/** - * The minimum editor width, in pixels, when resizing the editor interface by using the resize handle. - * Note: It falls back to editor's actual width if it is smaller than the default value. - * - * config.resize_minWidth = 500; - * - * @cfg {Number} [resize_minWidth=750] - * @member CKEDITOR.config - */ - -/** - * The minimum editor height, in pixels, when resizing the editor interface by using the resize handle. - * Note: It falls back to editor's actual height if it is smaller than the default value. - * - * config.resize_minHeight = 600; - * - * @cfg {Number} [resize_minHeight=250] - * @member CKEDITOR.config - */ - -/** - * The maximum editor width, in pixels, when resizing the editor interface by using the resize handle. - * - * config.resize_maxWidth = 750; - * - * @cfg {Number} [resize_maxWidth=3000] - * @member CKEDITOR.config - */ - -/** - * The maximum editor height, in pixels, when resizing the editor interface by using the resize handle. - * - * config.resize_maxHeight = 600; - * - * @cfg {Number} [resize_maxHeight=3000] - * @member CKEDITOR.config - */ - -/** - * Whether to enable the resizing feature. If this feature is disabled, the resize handle will not be visible. - * - * config.resize_enabled = false; - * - * @cfg {Boolean} [resize_enabled=true] - * @member CKEDITOR.config - */ - -/** - * The dimensions for which the editor resizing is enabled. Possible values - * are `both`, `vertical`, and `horizontal`. - * - * config.resize_dir = 'both'; - * - * @since 3.3 - * @cfg {String} [resize_dir='vertical'] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/richcombo/plugin.js b/addons/website/static/lib/ckeditor/plugins/richcombo/plugin.js deleted file mode 100644 index 0aa5c1586d7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/richcombo/plugin.js +++ /dev/null @@ -1,414 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'richcombo', { - requires: 'floatpanel,listblock,button', - - beforeInit: function( editor ) { - editor.ui.addHandler( CKEDITOR.UI_RICHCOMBO, CKEDITOR.ui.richCombo.handler ); - } -}); - -(function() { - var template = '<span id="{id}"' + - ' class="cke_combo cke_combo__{name} {cls}"' + - ' role="presentation">' + - '<span id="{id}_label" class="cke_combo_label">{label}</span>' + - '<a class="cke_combo_button" hidefocus=true title="{title}" tabindex="-1"' + - ( CKEDITOR.env.gecko && CKEDITOR.env.version >= 10900 && !CKEDITOR.env.hc ? '' : '" href="javascript:void(\'{titleJs}\')"' ) + - ' hidefocus="true"' + - ' role="button"' + - ' aria-labelledby="{id}_label"' + - ' aria-haspopup="true"'; - - // Some browsers don't cancel key events in the keydown but in the - // keypress. - // TODO: Check if really needed for Gecko+Mac. - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - template += ' onkeypress="return false;"'; - - // With Firefox, we need to force the button to redraw, otherwise it - // will remain in the focus state. - if ( CKEDITOR.env.gecko ) - template += ' onblur="this.style.cssText = this.style.cssText;"'; - - template += - ' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event,this);"' + - ' onmousedown="return CKEDITOR.tools.callFunction({mousedownFn},event);" ' + - ' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' + - ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // #188 - '="CKEDITOR.tools.callFunction({clickFn},this);return false;">' + - '<span id="{id}_text" class="cke_combo_text cke_combo_inlinelabel">{label}</span>' + - '<span class="cke_combo_open">' + - '<span class="cke_combo_arrow">' + - // BLACK DOWN-POINTING TRIANGLE - ( CKEDITOR.env.hc ? '▼' : CKEDITOR.env.air ? ' ' : '' ) + - '</span>' + - '</span>' + - '</a>' + - '</span>'; - - var rcomboTpl = CKEDITOR.addTemplate( 'combo', template ); - - /** - * Button UI element. - * - * @readonly - * @property {String} [='richcombo'] - * @member CKEDITOR - */ - CKEDITOR.UI_RICHCOMBO = 'richcombo'; - - /** - * @class - * @todo - */ - CKEDITOR.ui.richCombo = CKEDITOR.tools.createClass({ - $: function( definition ) { - // Copy all definition properties to this object. - CKEDITOR.tools.extend( this, definition, - // Set defaults. - { - // The combo won't participate in toolbar grouping. - canGroup: false, - title: definition.label, - modes: { wysiwyg:1 }, - editorFocus: 1 - }); - - // We don't want the panel definition in this object. - var panelDefinition = this.panel || {}; - delete this.panel; - - this.id = CKEDITOR.tools.getNextNumber(); - - this.document = ( panelDefinition.parent && panelDefinition.parent.getDocument() ) || CKEDITOR.document; - - panelDefinition.className = 'cke_combopanel'; - panelDefinition.block = { - multiSelect: panelDefinition.multiSelect, - attributes: panelDefinition.attributes - }; - panelDefinition.toolbarRelated = true; - - this._ = { - panelDefinition: panelDefinition, - items: {} - }; - }, - - proto: { - renderHtml: function( editor ) { - var output = []; - this.render( editor, output ); - return output.join( '' ); - }, - - /** - * Renders the combo. - * - * @param {CKEDITOR.editor} editor The editor instance which this button is - * to be used by. - * @param {Array} output The output array to which append the HTML relative - * to this button. - */ - render: function( editor, output ) { - var env = CKEDITOR.env; - - var id = 'cke_' + this.id; - var clickFn = CKEDITOR.tools.addFunction( function( el ) { - - // Restore locked selection in Opera. - if ( selLocked ) { - editor.unlockSelection( 1 ); - selLocked = 0; - } - - instance.execute( el ); - }, this ); - - var combo = this; - var instance = { - id: id, - combo: this, - focus: function() { - var element = CKEDITOR.document.getById( id ).getChild( 1 ); - element.focus(); - }, - execute: function( el ) { - var _ = combo._; - - if ( _.state == CKEDITOR.TRISTATE_DISABLED ) - return; - - combo.createPanel( editor ); - - if ( _.on ) { - _.panel.hide(); - return; - } - - combo.commit(); - var value = combo.getValue(); - if ( value ) - _.list.mark( value ); - else - _.list.unmarkAll(); - - _.panel.showBlock( combo.id, new CKEDITOR.dom.element( el ), 4 ); - }, - clickFn: clickFn - }; - - function updateState() { - var state = this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; - this.setState( editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state ); - this.setValue( '' ); - } - - editor.on( 'mode', updateState, this ); - // If this combo is sensitive to readOnly state, update it accordingly. - !this.readOnly && editor.on( 'readOnly', updateState, this ); - - var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ) { - ev = new CKEDITOR.dom.event( ev ); - - var keystroke = ev.getKeystroke(); - switch ( keystroke ) { - case 13: // ENTER - case 32: // SPACE - case 40: // ARROW-DOWN - // Show panel - CKEDITOR.tools.callFunction( clickFn, element ); - break; - default: - // Delegate the default behavior to toolbar button key handling. - instance.onkey( instance, keystroke ); - } - - // Avoid subsequent focus grab on editor document. - ev.preventDefault(); - }); - - var focusFn = CKEDITOR.tools.addFunction( function() { - instance.onfocus && instance.onfocus(); - }); - - var selLocked = 0; - var mouseDownFn = CKEDITOR.tools.addFunction( function() { - // Opera: lock to prevent loosing editable text selection when clicking on button. - if ( CKEDITOR.env.opera ) { - var edt = editor.editable(); - if ( edt.isInline() && edt.hasFocus ) { - editor.lockSelection(); - selLocked = 1; - } - } - }); - - // For clean up - instance.keyDownFn = keyDownFn; - - var params = { - id: id, - name: this.name || this.command, - label: this.label, - title: this.title, - cls: this.className || '', - titleJs: env.gecko && env.version >= 10900 && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ), - keydownFn: keyDownFn, - mousedownFn: mouseDownFn, - focusFn: focusFn, - clickFn: clickFn - }; - - rcomboTpl.output( params, output ); - - if ( this.onRender ) - this.onRender(); - - return instance; - }, - - createPanel: function( editor ) { - if ( this._.panel ) - return; - - var panelDefinition = this._.panelDefinition, - panelBlockDefinition = this._.panelDefinition.block, - panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(), - namedPanelCls = 'cke_combopanel__' + this.name, - panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ), - list = panel.addListBlock( this.id, panelBlockDefinition ), - me = this; - - panel.onShow = function() { - this.element.addClass( namedPanelCls ); - - me.setState( CKEDITOR.TRISTATE_ON ); - - me._.on = 1; - - me.editorFocus && editor.focus(); - - if ( me.onOpen ) - me.onOpen(); - - list.focus( !list.multiSelect && me.getValue() ); - }; - - panel.onHide = function( preventOnClose ) { - this.element.removeClass( namedPanelCls ); - - me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - - me._.on = 0; - - if ( !preventOnClose && me.onClose ) - me.onClose(); - }; - - panel.onEscape = function() { - // Hide drop-down with focus returned. - panel.hide( 1 ); - }; - - list.onClick = function( value, marked ) { - - if ( me.onClick ) - me.onClick.call( me, value, marked ); - - panel.hide(); - }; - - this._.panel = panel; - this._.list = list; - - panel.getBlock( this.id ).onHide = function() { - me._.on = 0; - me.setState( CKEDITOR.TRISTATE_OFF ); - }; - - if ( this.init ) - this.init(); - }, - - setValue: function( value, text ) { - this._.value = value; - - var textElement = this.document.getById( 'cke_' + this.id + '_text' ); - if ( textElement ) { - if ( !( value || text ) ) { - text = this.label; - textElement.addClass( 'cke_combo_inlinelabel' ); - } else - textElement.removeClass( 'cke_combo_inlinelabel' ); - - textElement.setText( typeof text != 'undefined' ? text : value ); - } - }, - - getValue: function() { - return this._.value || ''; - }, - - unmarkAll: function() { - this._.list.unmarkAll(); - }, - - mark: function( value ) { - this._.list.mark( value ); - }, - - hideItem: function( value ) { - this._.list.hideItem( value ); - }, - - hideGroup: function( groupTitle ) { - this._.list.hideGroup( groupTitle ); - }, - - showAll: function() { - this._.list.showAll(); - }, - - add: function( value, html, text ) { - this._.items[ value ] = text || value; - this._.list.add( value, html, text ); - }, - - startGroup: function( title ) { - this._.list.startGroup( title ); - }, - - commit: function() { - if ( !this._.committed ) { - this._.list.commit(); - this._.committed = 1; - CKEDITOR.ui.fire( 'ready', this ); - } - this._.committed = 1; - }, - - setState: function( state ) { - if ( this._.state == state ) - return; - - var el = this.document.getById( 'cke_' + this.id ); - el.setState( state, 'cke_combo' ); - - state == CKEDITOR.TRISTATE_DISABLED ? - el.setAttribute( 'aria-disabled', true ) : - el.removeAttribute( 'aria-disabled' ); - - this._.state = state; - }, - - enable: function() { - if ( this._.state == CKEDITOR.TRISTATE_DISABLED ) - this.setState( this._.lastState ); - }, - - disable: function() { - if ( this._.state != CKEDITOR.TRISTATE_DISABLED ) { - this._.lastState = this._.state; - this.setState( CKEDITOR.TRISTATE_DISABLED ); - } - } - }, - - /** - * Represents richCombo handler object. - * - * @class CKEDITOR.ui.richCombo.handler - * @singleton - * @extends CKEDITOR.ui.handlerDefinition - */ - statics: { - handler: { - /** - * Transforms a richCombo definition in a {@link CKEDITOR.ui.richCombo} instance. - * - * @param {Object} definition - * @returns {CKEDITOR.ui.richCombo} - */ - create: function( definition ) { - return new CKEDITOR.ui.richCombo( definition ); - } - } - } - }); - - /** - * @member CKEDITOR.ui - * @param {String} - * @param {Object} definition - * @todo - */ - CKEDITOR.ui.prototype.addRichCombo = function( name, definition ) { - this.add( name, CKEDITOR.UI_RICHCOMBO, definition ); - }; - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/save/icons/hidpi/save.png b/addons/website/static/lib/ckeditor/plugins/save/icons/hidpi/save.png Binary files differdeleted file mode 100644 index fc59f677aa3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/save/icons/hidpi/save.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/save/icons/save.png b/addons/website/static/lib/ckeditor/plugins/save/icons/save.png Binary files differdeleted file mode 100644 index 51b8f6ee11e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/save/icons/save.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/save/lang/en.js b/addons/website/static/lib/ckeditor/plugins/save/lang/en.js deleted file mode 100644 index 8eb35206c1c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/save/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'save', 'en', { - toolbar: 'Save' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/save/plugin.js b/addons/website/static/lib/ckeditor/plugins/save/plugin.js deleted file mode 100644 index 96348b623b0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/save/plugin.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The Save plugin. - */ - -(function() { - var saveCmd = { - readOnly: 1, - - exec: function( editor ) { - if ( editor.fire( 'save' ) ) { - var $form = editor.element.$.form; - - if ( $form ) { - try { - $form.submit(); - } catch ( e ) { - // If there's a button named "submit" then the form.submit - // function is masked and can't be called in IE/FF, so we - // call the click() method of that button. - if ( $form.submit.click ) - $form.submit.click(); - } - } - } - } - }; - - var pluginName = 'save'; - - // Register a plugin named "save". - CKEDITOR.plugins.add( pluginName, { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'save', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - // Save plugin is for replace mode only. - if ( editor.elementMode != CKEDITOR.ELEMENT_MODE_REPLACE ) - return; - - var command = editor.addCommand( pluginName, saveCmd ); - command.modes = { wysiwyg: !!( editor.element.$.form ) }; - - editor.ui.addButton && editor.ui.addButton( 'Save', { - label: editor.lang.save.toolbar, - command: pluginName, - toolbar: 'document,10' - }); - } - }); -})(); - -/** - * Fired when the user clicks the Save button on the editor toolbar. - * This event allows to overwrite the default Save button behavior. - * - * @since 4.2 - * @event save - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/selectall/icons/hidpi/selectall.png b/addons/website/static/lib/ckeditor/plugins/selectall/icons/hidpi/selectall.png Binary files differdeleted file mode 100644 index c67f64ddebb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/selectall/icons/hidpi/selectall.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/selectall/icons/selectall.png b/addons/website/static/lib/ckeditor/plugins/selectall/icons/selectall.png Binary files differdeleted file mode 100644 index 0d1e8160e42..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/selectall/icons/selectall.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/selectall/lang/en.js b/addons/website/static/lib/ckeditor/plugins/selectall/lang/en.js deleted file mode 100644 index 804ef843c5a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/selectall/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'selectall', 'en', { - toolbar: 'Select All' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/selectall/plugin.js b/addons/website/static/lib/ckeditor/plugins/selectall/plugin.js deleted file mode 100644 index b0cdc24df42..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/selectall/plugin.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "selectall" plugin provides an editor command that - * allows selecting the entire content of editable area. - * This plugin also enables a toolbar button for the feature. - */ - -(function() { - CKEDITOR.plugins.add( 'selectall', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'selectall', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.addCommand( 'selectAll', { modes:{wysiwyg:1,source:1 }, - exec: function( editor ) { - var editable = editor.editable(); - - if ( editable.is( 'textarea' ) ) { - var textarea = editable.$; - - if ( CKEDITOR.env.ie ) - textarea.createTextRange().execCommand( 'SelectAll' ); - else { - textarea.selectionStart = 0; - textarea.selectionEnd = textarea.value.length; - } - - textarea.focus(); - } else { - if ( editable.is( 'body' ) ) - editor.document.$.execCommand( 'SelectAll', false, null ); - else { - var range = editor.createRange(); - range.selectNodeContents( editable ); - range.select(); - } - - // Force triggering selectionChange (#7008) - editor.forceNextSelectionCheck(); - editor.selectionChange(); - } - - }, - canUndo: false - }); - - editor.ui.addButton && editor.ui.addButton( 'SelectAll', { - label: editor.lang.selectall.toolbar, - command: 'selectAll', - toolbar: 'selection,10' - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/sharedspace/plugin.js b/addons/website/static/lib/ckeditor/plugins/sharedspace/plugin.js deleted file mode 100644 index ce2e0729e7e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sharedspace/plugin.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @license Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - - 'use strict'; - - var containerTpl = CKEDITOR.addTemplate( 'sharedcontainer', '<div' + - ' id="cke_{name}"' + - ' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_shared cke_detached cke_{langDir} ' + CKEDITOR.env.cssClass + '"' + - ' dir="{langDir}"' + - ' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' + - ' lang="{langCode}"' + - ' role="presentation"' + - '>' + - '<div class="cke_inner">' + - '<div id="{spaceId}" class="cke_{space}" role="presentation">{content}</div>' + - '</div>' + - '</div>' ); - - CKEDITOR.plugins.add( 'sharedspace', { - init: function( editor ) { - // Create toolbars on #loaded (like themed creator), but do that - // with higher priority to block the default scenario. - editor.on( 'loaded', function() { - var spaces = editor.config.sharedSpaces; - - if ( spaces ) { - for ( var spaceName in spaces ) - create( editor, spaceName, spaces[ spaceName ] ); - } - }, null, null, 9 ); - } - }); - - function create( editor, spaceName, targetId ) { - var target = CKEDITOR.document.getById( targetId ), - innerHtml, space; - - if ( target ) { - // Have other plugins filling the space. - innerHtml = editor.fire( 'uiSpace', { space: spaceName, html: '' } ).html; - - if ( innerHtml ) { - // Block the uiSpace handling by others (e.g. themed-ui). - editor.on( 'uiSpace', function( ev ) { - if ( ev.data.space == spaceName ) - ev.cancel(); - }, null, null, 1 ); // Hi-priority - - // Inject the space into the target. - space = target.append( CKEDITOR.dom.element.createFromHtml( containerTpl.output({ - id: editor.id, - name: editor.name, - langDir: editor.lang.dir, - langCode: editor.langCode, - space: spaceName, - spaceId: editor.ui.spaceId( spaceName ), - content: innerHtml - }))); - - // Only the first container starts visible. Others get hidden. - if ( target.getCustomData( 'cke_hasshared' ) ) - space.hide(); - else - target.setCustomData( 'cke_hasshared', 1 ); - - // There's no need for the space to be selectable. - space.unselectable(); - - // Prevent clicking on non-buttons area of the space from blurring editor. - space.on( 'mousedown', function( evt ) { - evt = evt.data; - if ( !evt.getTarget().hasAscendant( 'a', 1 ) ) - evt.preventDefault(); - }); - - // Register this UI space to the focus manager. - editor.focusManager.add( space, 1 ); - - // When the editor gets focus, show the space container, hiding others. - editor.on( 'focus', function() { - for ( var i = 0, sibling, children = target.getChildren(); ( sibling = children.getItem( i ) ); i++ ) { - if ( sibling.type == CKEDITOR.NODE_ELEMENT && - !sibling.equals( space ) && - sibling.hasClass( 'cke_shared' ) ) { - sibling.hide(); - } - } - - space.show(); - }); - - editor.on( 'destroy', function() { - space.remove(); - }); - } - } - } -})(); - -/** - * Makes it possible to place some of the editor UI blocks, like the toolbar - * and the elements path, into any element in the page. - * - * The elements used to hold the UI blocks can be shared among several editor - * instances. In that case, only the blocks of the active editor instance will - * display. - * - * // Place the toolbar inside the element with ID "someElementId" and the - * // elements path into the element with ID "anotherId". - * config.sharedSpaces = { - * top: 'someElementId', - * bottom: 'anotherId' - * }; - * - * // Place the toolbar inside the element with ID "someElementId". The - * // elements path will remain attached to the editor UI. - * config.sharedSpaces = { - * top: 'someElementId' - * }; - * - * @cfg {Object} [sharedSpaces] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks-rtl.png b/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks-rtl.png Binary files differdeleted file mode 100644 index c88abcb6dbe..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks.png b/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks.png Binary files differdeleted file mode 100644 index a776fcc139f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/hidpi/showblocks.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks-rtl.png b/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks-rtl.png Binary files differdeleted file mode 100644 index cd87d3e258e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks.png b/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks.png Binary files differdeleted file mode 100644 index 41b5f3466d2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/icons/showblocks.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/lang/en.js b/addons/website/static/lib/ckeditor/plugins/showblocks/lang/en.js deleted file mode 100644 index 45d3f8988de..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'showblocks', 'en', { - toolbar: 'Show Blocks' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/showblocks/plugin.js b/addons/website/static/lib/ckeditor/plugins/showblocks/plugin.js deleted file mode 100755 index e3021cbf181..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showblocks/plugin.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "showblocks" plugin. Enable it will make all block level - * elements being decorated with a border and the element name - * displayed on the left-right corner. - */ - -(function() { - var commandDefinition = { - readOnly: 1, - preserveState: true, - editorFocus: false, - - exec: function( editor ) { - this.toggleState(); - this.refresh( editor ); - }, - - refresh: function( editor ) { - if ( editor.document ) { - // Show blocks turns inactive after editor loses focus when in inline. - var showBlocks = this.state == CKEDITOR.TRISTATE_ON && - ( editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE || - editor.focusManager.hasFocus ); - - var funcName = showBlocks ? 'attachClass' : 'removeClass'; - editor.editable()[ funcName ]( 'cke_show_blocks' ); - } - } - }; - - CKEDITOR.plugins.add( 'showblocks', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'showblocks,showblocks-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - onLoad: function() { - var cssTemplate = '.%2 p,' + - '.%2 div,' + - '.%2 pre,' + - '.%2 address,' + - '.%2 blockquote,' + - '.%2 h1,' + - '.%2 h2,' + - '.%2 h3,' + - '.%2 h4,' + - '.%2 h5,' + - '.%2 h6' + - '{' + - 'background-repeat: no-repeat;' + - 'border: 1px dotted gray;' + - 'padding-top: 8px;' + - '}' + - - '.%2 p' + - '{' + - '%1p.png);' + - '}' + - - '.%2 div' + - '{' + - '%1div.png);' + - '}' + - - '.%2 pre' + - '{' + - '%1pre.png);' + - '}' + - - '.%2 address' + - '{' + - '%1address.png);' + - '}' + - - '.%2 blockquote' + - '{' + - '%1blockquote.png);' + - '}' + - - '.%2 h1' + - '{' + - '%1h1.png);' + - '}' + - - '.%2 h2' + - '{' + - '%1h2.png);' + - '}' + - - '.%2 h3' + - '{' + - '%1h3.png);' + - '}' + - - '.%2 h4' + - '{' + - '%1h4.png);' + - '}' + - - '.%2 h5' + - '{' + - '%1h5.png);' + - '}' + - - '.%2 h6' + - '{' + - '%1h6.png);' + - '}'; - - // Styles with contents direction awareness. - function cssWithDir( dir ) { - var template = '.%1.%2 p,' + - '.%1.%2 div,' + - '.%1.%2 pre,' + - '.%1.%2 address,' + - '.%1.%2 blockquote,' + - '.%1.%2 h1,' + - '.%1.%2 h2,' + - '.%1.%2 h3,' + - '.%1.%2 h4,' + - '.%1.%2 h5,' + - '.%1.%2 h6' + - '{' + - 'background-position: top %3;' + - 'padding-%3: 8px;' + - '}'; - - return template.replace( /%1/g, 'cke_show_blocks' ).replace( /%2/g, 'cke_contents_' + dir ).replace( /%3/g, dir == 'rtl' ? 'right' : 'left' ); - } - - CKEDITOR.addCss( cssTemplate.replace( /%1/g, 'background-image: url(' + CKEDITOR.getUrl( this.path ) + 'images/block_' ).replace( /%2/g, 'cke_show_blocks ' ) + cssWithDir( 'ltr' ) + cssWithDir( 'rtl' ) ); - }, - init: function( editor ) { - if ( editor.blockless ) - return; - - var command = editor.addCommand( 'showblocks', commandDefinition ); - command.canUndo = false; - - if ( editor.config.startupOutlineBlocks ) - command.setState( CKEDITOR.TRISTATE_ON ); - - editor.ui.addButton && editor.ui.addButton( 'ShowBlocks', { - label: editor.lang.showblocks.toolbar, - command: 'showblocks', - toolbar: 'tools,20' - }); - - // Refresh the command on setData. - editor.on( 'mode', function() { - if ( command.state != CKEDITOR.TRISTATE_DISABLED ) - command.refresh( editor ); - }); - - // Refresh the command on focus/blur in inline. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) { - function onFocusBlur() { - command.refresh( editor ); - } - editor.on( 'focus', onFocusBlur ); - editor.on( 'blur', onFocusBlur ); - } - - // Refresh the command on setData. - editor.on( 'contentDom', function() { - if ( command.state != CKEDITOR.TRISTATE_DISABLED ) - command.refresh( editor ); - }); - } - }); -})(); - -/** - * Whether to automaticaly enable the show block" command when the editor loads. - * - * config.startupOutlineBlocks = true; - * - * @cfg {Boolean} [startupOutlineBlocks=false] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/showborders/plugin.js b/addons/website/static/lib/ckeditor/plugins/showborders/plugin.js deleted file mode 100644 index 5b2d2095932..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/showborders/plugin.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "show border" plugin. The command display visible outline - * border line around all table elements if table doesn't have a none-zero 'border' attribute specified. - */ - -(function() { - var commandDefinition = { - preserveState: true, - editorFocus: false, - readOnly: 1, - - exec: function( editor ) { - this.toggleState(); - this.refresh( editor ); - }, - - refresh: function( editor ) { - if ( editor.document ) { - var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'attachClass' : 'removeClass'; - editor.editable()[ funcName ]( 'cke_show_borders' ); - } - } - }; - - var showBorderClassName = 'cke_show_border'; - - CKEDITOR.plugins.add( 'showborders', { - modes: { 'wysiwyg':1 }, - - onLoad: function() { - var cssStyleText, - cssTemplate = - // TODO: For IE6, we don't have child selector support, - // where nested table cells could be incorrect. - ( CKEDITOR.env.ie6Compat ? [ - '.%1 table.%2,', - '.%1 table.%2 td, .%1 table.%2 th', - '{', - 'border : #d3d3d3 1px dotted', - '}' - ] : [ - '.%1 table.%2,', - '.%1 table.%2 > tr > td, .%1 table.%2 > tr > th,', - '.%1 table.%2 > tbody > tr > td, .%1 table.%2 > tbody > tr > th,', - '.%1 table.%2 > thead > tr > td, .%1 table.%2 > thead > tr > th,', - '.%1 table.%2 > tfoot > tr > td, .%1 table.%2 > tfoot > tr > th', - '{', - 'border : #d3d3d3 1px dotted', - '}' - ] ).join( '' ); - - cssStyleText = cssTemplate.replace( /%2/g, showBorderClassName ).replace( /%1/g, 'cke_show_borders ' ); - - CKEDITOR.addCss( cssStyleText ); - }, - - init: function( editor ) { - - var command = editor.addCommand( 'showborders', commandDefinition ); - command.canUndo = false; - - if ( editor.config.startupShowBorders !== false ) - command.setState( CKEDITOR.TRISTATE_ON ); - - // Refresh the command on setData. - editor.on( 'mode', function() { - if ( command.state != CKEDITOR.TRISTATE_DISABLED ) - command.refresh( editor ); - }, null, null, 100 ); - - // Refresh the command on wysiwyg frame reloads. - editor.on( 'contentDom', function() { - if ( command.state != CKEDITOR.TRISTATE_DISABLED ) - command.refresh( editor ); - }); - - editor.on( 'removeFormatCleanup', function( evt ) { - var element = evt.data; - if ( editor.getCommand( 'showborders' ).state == CKEDITOR.TRISTATE_ON && element.is( 'table' ) && ( !element.hasAttribute( 'border' ) || parseInt( element.getAttribute( 'border' ), 10 ) <= 0 ) ) - element.addClass( showBorderClassName ); - }); - }, - - afterInit: function( editor ) { - var dataProcessor = editor.dataProcessor, - dataFilter = dataProcessor && dataProcessor.dataFilter, - htmlFilter = dataProcessor && dataProcessor.htmlFilter; - - if ( dataFilter ) { - dataFilter.addRules({ - elements: { - 'table': function( element ) { - var attributes = element.attributes, - cssClass = attributes[ 'class' ], - border = parseInt( attributes.border, 10 ); - - if ( ( !border || border <= 0 ) && ( !cssClass || cssClass.indexOf( showBorderClassName ) == -1 ) ) - attributes[ 'class' ] = ( cssClass || '' ) + ' ' + showBorderClassName; - } - } - }); - } - - if ( htmlFilter ) { - htmlFilter.addRules({ - elements: { - 'table': function( table ) { - var attributes = table.attributes, - cssClass = attributes[ 'class' ]; - - cssClass && ( attributes[ 'class' ] = cssClass.replace( showBorderClassName, '' ).replace( /\s{2}/, ' ' ).replace( /^\s+|\s+$/, '' ) ); - } - } - }); - } - } - }); - - // Table dialog must be aware of it. - CKEDITOR.on( 'dialogDefinition', function( ev ) { - var dialogName = ev.data.name; - - if ( dialogName == 'table' || dialogName == 'tableProperties' ) { - var dialogDefinition = ev.data.definition, - infoTab = dialogDefinition.getContents( 'info' ), - borderField = infoTab.get( 'txtBorder' ), - originalCommit = borderField.commit; - - borderField.commit = CKEDITOR.tools.override( originalCommit, function( org ) { - return function( data, selectedTable ) { - org.apply( this, arguments ); - var value = parseInt( this.getValue(), 10 ); - selectedTable[ ( !value || value <= 0 ) ? 'addClass' : 'removeClass' ]( showBorderClassName ); - }; - }); - - var advTab = dialogDefinition.getContents( 'advanced' ), - classField = advTab && advTab.get( 'advCSSClasses' ); - - if ( classField ) { - classField.setup = CKEDITOR.tools.override( classField.setup, function( originalSetup ) { - return function() { - originalSetup.apply( this, arguments ); - this.setValue( this.getValue().replace( /cke_show_border/, '' ) ); - }; - }); - - classField.commit = CKEDITOR.tools.override( classField.commit, function( originalCommit ) { - return function( data, element ) { - originalCommit.apply( this, arguments ); - - if ( !parseInt( element.getAttribute( 'border' ), 10 ) ) - element.addClass( 'cke_show_border' ); - }; - }); - } - } - }); - -})(); - -/** - * Whether to automatically enable the "show borders" command when the editor loads. - * - * config.startupShowBorders = false; - * - * @cfg {Boolean} [startupShowBorders=true] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/smiley/dialogs/smiley.js b/addons/website/static/lib/ckeditor/plugins/smiley/dialogs/smiley.js deleted file mode 100644 index 2a0b05ab927..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/smiley/dialogs/smiley.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'smiley', function( editor ) { - var config = editor.config, - lang = editor.lang.smiley, - images = config.smiley_images, - columns = config.smiley_columns || 8, - i; - - // Simulate "this" of a dialog for non-dialog events. - // @type {CKEDITOR.dialog} - var dialog; - var onClick = function( evt ) { - var target = evt.data.getTarget(), - targetName = target.getName(); - - if ( targetName == 'a' ) - target = target.getChild( 0 ); - else if ( targetName != 'img' ) - return; - - var src = target.getAttribute( 'cke_src' ), - title = target.getAttribute( 'title' ); - - var img = editor.document.createElement( 'img', { - attributes: { - src: src, - 'data-cke-saved-src': src, - title: title, - alt: title, - width: target.$.width, - height: target.$.height - } - }); - - editor.insertElement( img ); - - dialog.hide(); - evt.data.preventDefault(); - }; - - var onKeydown = CKEDITOR.tools.addFunction( function( ev, element ) { - ev = new CKEDITOR.dom.event( ev ); - element = new CKEDITOR.dom.element( element ); - var relative, nodeToMove; - - var keystroke = ev.getKeystroke(), - rtl = editor.lang.dir == 'rtl'; - switch ( keystroke ) { - // UP-ARROW - case 38: - // relative is TR - if ( ( relative = element.getParent().getParent().getPrevious() ) ) { - nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); - nodeToMove.focus(); - } - ev.preventDefault(); - break; - // DOWN-ARROW - case 40: - // relative is TR - if ( ( relative = element.getParent().getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); - if ( nodeToMove ) - nodeToMove.focus(); - } - ev.preventDefault(); - break; - // ENTER - // SPACE - case 32: - onClick({ data: ev } ); - ev.preventDefault(); - break; - - // RIGHT-ARROW - case rtl ? 37: - 39 : - // relative is TD - if ( ( relative = element.getParent().getNext() ) ) { - nodeToMove = relative.getChild( 0 ); - nodeToMove.focus(); - ev.preventDefault( true ); - } - // relative is TR - else if ( ( relative = element.getParent().getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ 0, 0 ] ); - if ( nodeToMove ) - nodeToMove.focus(); - ev.preventDefault( true ); - } - break; - - // LEFT-ARROW - case rtl ? 39: - 37 : - // relative is TD - if ( ( relative = element.getParent().getPrevious() ) ) { - nodeToMove = relative.getChild( 0 ); - nodeToMove.focus(); - ev.preventDefault( true ); - } - // relative is TR - else if ( ( relative = element.getParent().getParent().getPrevious() ) ) { - nodeToMove = relative.getLast().getChild( 0 ); - nodeToMove.focus(); - ev.preventDefault( true ); - } - break; - default: - // Do not stop not handled events. - return; - } - }); - - // Build the HTML for the smiley images table. - var labelId = CKEDITOR.tools.getNextId() + '_smiley_emtions_label'; - var html = [ - '<div>' + - '<span id="' + labelId + '" class="cke_voice_label">' + lang.options + '</span>', - '<table role="listbox" aria-labelledby="' + labelId + '" style="width:100%;height:100%;border-collapse:separate;" cellspacing="2" cellpadding="2"', - CKEDITOR.env.ie && CKEDITOR.env.quirks ? ' style="position:absolute;"' : '', - '><tbody>' - ]; - - var size = images.length; - for ( i = 0; i < size; i++ ) { - if ( i % columns === 0 ) - html.push( '<tr role="presentation">' ); - - var smileyLabelId = 'cke_smile_label_' + i + '_' + CKEDITOR.tools.getNextNumber(); - html.push( '<td class="cke_dark_background cke_centered" style="vertical-align: middle;" role="presentation">' + - '<a href="javascript:void(0)" role="option"', ' aria-posinset="' + ( i + 1 ) + '"', ' aria-setsize="' + size + '"', ' aria-labelledby="' + smileyLabelId + '"', ' class="cke_smile cke_hand" tabindex="-1" onkeydown="CKEDITOR.tools.callFunction( ', onKeydown, ', event, this );">', '<img class="cke_hand" title="', config.smiley_descriptions[ i ], '"' + - ' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '" alt="', config.smiley_descriptions[ i ], '"', ' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"', - // IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct. - ( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ), '>' + - '<span id="' + smileyLabelId + '" class="cke_voice_label">' + config.smiley_descriptions[ i ] + '</span>' + - '</a>', '</td>' ); - - if ( i % columns == columns - 1 ) - html.push( '</tr>' ); - } - - if ( i < columns - 1 ) { - for ( ; i < columns - 1; i++ ) - html.push( '<td></td>' ); - html.push( '</tr>' ); - } - - html.push( '</tbody></table></div>' ); - - var smileySelector = { - type: 'html', - id: 'smileySelector', - html: html.join( '' ), - onLoad: function( event ) { - dialog = event.sender; - }, - focus: function() { - var self = this; - // IE need a while to move the focus (#6539). - setTimeout( function() { - var firstSmile = self.getElement().getElementsByTag( 'a' ).getItem( 0 ); - firstSmile.focus(); - }, 0 ); - }, - onClick: onClick, - style: 'width: 100%; border-collapse: separate;' - }; - - return { - title: editor.lang.smiley.title, - minWidth: 270, - minHeight: 120, - contents: [ - { - id: 'tab1', - label: '', - title: '', - expand: true, - padding: 0, - elements: [ - smileySelector - ] - } - ], - buttons: [ CKEDITOR.dialog.cancelButton ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/smiley/icons/hidpi/smiley.png b/addons/website/static/lib/ckeditor/plugins/smiley/icons/hidpi/smiley.png Binary files differdeleted file mode 100644 index bad62eed468..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/smiley/icons/hidpi/smiley.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/smiley/icons/smiley.png b/addons/website/static/lib/ckeditor/plugins/smiley/icons/smiley.png Binary files differdeleted file mode 100644 index 9fafa28a81a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/smiley/icons/smiley.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/smiley/lang/en.js b/addons/website/static/lib/ckeditor/plugins/smiley/lang/en.js deleted file mode 100644 index 1f4b6489c20..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/smiley/lang/en.js +++ /dev/null @@ -1,9 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'smiley', 'en', { - options: 'Smiley Options', - title: 'Insert a Smiley', - toolbar: 'Smiley' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/smiley/plugin.js b/addons/website/static/lib/ckeditor/plugins/smiley/plugin.js deleted file mode 100644 index 198523c0b40..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/smiley/plugin.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'smiley', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'smiley', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - editor.config.smiley_path = editor.config.smiley_path || ( this.path + 'images/' ); - editor.addCommand( 'smiley', new CKEDITOR.dialogCommand( 'smiley', { - allowedContent: 'img[alt,height,!src,title,width]', - requiredContent: 'img' - } ) ); - editor.ui.addButton && editor.ui.addButton( 'Smiley', { - label: editor.lang.smiley.toolbar, - command: 'smiley', - toolbar: 'insert,50' - }); - CKEDITOR.dialog.add( 'smiley', this.path + 'dialogs/smiley.js' ); - } -}); - -/** - * The base path used to build the URL for the smiley images. It must end with a slash. - * - * config.smiley_path = 'http://www.example.com/images/smileys/'; - * - * config.smiley_path = '/images/smileys/'; - * - * @cfg {String} [smiley_path=CKEDITOR.basePath + 'plugins/smiley/images/'] - * @member CKEDITOR.config - */ - -/** - * The file names for the smileys to be displayed. These files must be - * contained inside the URL path defined with the {@link #smiley_path} setting. - * - * // This is actually the default value. - * config.smiley_images = [ - * 'regular_smile.png','sad_smile.png','wink_smile.png','teeth_smile.png','confused_smile.png','tongue_smile.png', - * 'embarrassed_smile.png','omg_smile.png','whatchutalkingabout_smile.png','angry_smile.png','angel_smile.png','shades_smile.png', - * 'devil_smile.png','cry_smile.png','lightbulb.png','thumbs_down.png','thumbs_up.png','heart.png', - * 'broken_heart.png','kiss.png','envelope.png' - * ]; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.smiley_images = [ - 'regular_smile.png', 'sad_smile.png', 'wink_smile.png', 'teeth_smile.png', 'confused_smile.png', 'tongue_smile.png', - 'embarrassed_smile.png', 'omg_smile.png', 'whatchutalkingabout_smile.png', 'angry_smile.png', 'angel_smile.png', 'shades_smile.png', - 'devil_smile.png', 'cry_smile.png', 'lightbulb.png', 'thumbs_down.png', 'thumbs_up.png', 'heart.png', - 'broken_heart.png', 'kiss.png', 'envelope.png' ]; - -/** - * The description to be used for each of the smileys defined in the - * {@link CKEDITOR.config#smiley_images} setting. Each entry in this array list - * must match its relative pair in the {@link CKEDITOR.config#smiley_images} - * setting. - * - * // Default settings. - * config.smiley_descriptions = [ - * 'smiley', 'sad', 'wink', 'laugh', 'frown', 'cheeky', 'blush', 'surprise', - * 'indecision', 'angry', 'angel', 'cool', 'devil', 'crying', 'enlightened', 'no', - * 'yes', 'heart', 'broken heart', 'kiss', 'mail' - * ]; - * - * // Use textual emoticons as description. - * config.smiley_descriptions = [ - * ':)', ':(', ';)', ':D', ':/', ':P', ':*)', ':-o', - * ':|', '>:(', 'o:)', '8-)', '>:-)', ';(', '', '', '', - * '', '', ':-*', '' - * ]; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.smiley_descriptions = [ - 'smiley', 'sad', 'wink', 'laugh', 'frown', 'cheeky', 'blush', 'surprise', - 'indecision', 'angry', 'angel', 'cool', 'devil', 'crying', 'enlightened', 'no', - 'yes', 'heart', 'broken heart', 'kiss', 'mail' -]; - -/** - * The number of columns to be generated by the smilies matrix. - * - * config.smiley_columns = 6; - * - * @since 3.3.2 - * @cfg {Number} [smiley_columns=8] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source-rtl.png b/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source-rtl.png Binary files differdeleted file mode 100644 index adf4af3c984..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source.png b/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source.png Binary files differdeleted file mode 100644 index b4d0a15a4d8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/hidpi/source.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source-rtl.png b/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source-rtl.png Binary files differdeleted file mode 100644 index 27d1ba88198..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source.png b/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source.png Binary files differdeleted file mode 100644 index e44db37985a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/icons/source.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/lang/en.js b/addons/website/static/lib/ckeditor/plugins/sourcearea/lang/en.js deleted file mode 100644 index 17bdd00641c..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/lang/en.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'sourcearea', 'en', { - toolbar: 'Source' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/sourcearea/plugin.js b/addons/website/static/lib/ckeditor/plugins/sourcearea/plugin.js deleted file mode 100644 index 06e2c0b2dcb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcearea/plugin.js +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "sourcearea" plugin. It registers the "source" editing - * mode, which displays the raw data being edited in the editor. - */ - -(function() { - CKEDITOR.plugins.add( 'sourcearea', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'source,source-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - // Source mode isn't available in inline mode yet. - if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) - return; - - var sourcearea = CKEDITOR.plugins.sourcearea; - - editor.addMode( 'source', function( callback ) { - var contentsSpace = editor.ui.space( 'contents' ), - textarea = contentsSpace.getDocument().createElement( 'textarea' ); - - textarea.setStyles( - CKEDITOR.tools.extend({ - // IE7 has overflow the <textarea> from wrapping table cell. - width: CKEDITOR.env.ie7Compat ? '99%' : '100%', - height: '100%', - resize: 'none', - outline: 'none', - 'text-align': 'left' - }, - CKEDITOR.tools.cssVendorPrefix( 'tab-size', editor.config.sourceAreaTabSize || 4 ) ) ); - - // Make sure that source code is always displayed LTR, - // regardless of editor language (#10105). - textarea.setAttribute( 'dir', 'ltr' ); - - textarea.addClass( 'cke_source cke_reset cke_enable_context_menu' ); - - editor.ui.space( 'contents' ).append( textarea ); - - var editable = editor.editable( new sourceEditable( editor, textarea ) ); - - // Fill the textarea with the current editor data. - editable.setData( editor.getData( 1 ) ); - - // Having to make <textarea> fixed sized to conquer the following bugs: - // 1. The textarea height/width='100%' doesn't constraint to the 'td' in IE6/7. - // 2. Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor - // if text content within it has overflowed. (#4762) - if ( CKEDITOR.env.ie ) { - editable.attachListener( editor, 'resize', onResize, editable ); - editable.attachListener( CKEDITOR.document.getWindow(), 'resize', onResize, editable ); - CKEDITOR.tools.setTimeout( onResize, 0, editable ); - } - - editor.fire( 'ariaWidget', this ); - - callback(); - }); - - editor.addCommand( 'source', sourcearea.commands.source ); - - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Source', { - label: editor.lang.sourcearea.toolbar, - command: 'source', - toolbar: 'mode,10' - }); - } - - editor.on( 'mode', function() { - editor.getCommand( 'source' ).setState( editor.mode == 'source' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF ); - }); - - function onResize() { - // Holder rectange size is stretched by textarea, - // so hide it just for a moment. - this.hide(); - this.setStyle( 'height', this.getParent().$.clientHeight + 'px' ); - this.setStyle( 'width', this.getParent().$.clientWidth + 'px' ); - // When we have proper holder size, show textarea again. - this.show(); - } - } - }); - - var sourceEditable = CKEDITOR.tools.createClass({ - base: CKEDITOR.editable, - proto: { - setData: function( data ) { - this.setValue( data ); - this.editor.fire( 'dataReady' ); - }, - - getData: function() { - return this.getValue(); - }, - - // Insertions are not supported in source editable. - insertHtml: function() {}, - insertElement: function() {}, - insertText: function() {}, - - // Read-only support for textarea. - setReadOnly: function( isReadOnly ) { - this[ ( isReadOnly ? 'set' : 'remove' ) + 'Attribute' ]( 'readOnly', 'readonly' ); - }, - - detach: function() { - sourceEditable.baseProto.detach.call( this ); - this.clearCustomData(); - this.remove(); - } - } - }); -})(); - -CKEDITOR.plugins.sourcearea = { - commands: { - source: { - modes: { wysiwyg:1,source:1 }, - editorFocus: false, - readOnly: 1, - exec: function( editor ) { - if ( editor.mode == 'wysiwyg' ) - editor.fire( 'saveSnapshot' ); - editor.getCommand( 'source' ).setState( CKEDITOR.TRISTATE_DISABLED ); - editor.setMode( editor.mode == 'source' ? 'wysiwyg' : 'source' ); - }, - - canUndo: false - } - } -}; - -/** - * Controls CSS tab-size property of the sourcearea view. - * - * **Note:** Works only with {@link #dataIndentationChars} - * set to `'\t'`. Please consider that not all browsers support CSS - * `tab-size` property yet. - * - * // Set tab-size to 20 characters. - * CKEDITOR.config.sourceAreaTabSize = 20; - * - * @cfg {Number} [sourceAreaTabSize=4] - * @member CKEDITOR.config - * @see CKEDITOR.config#dataIndentationChars - */ diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/dialogs/sourcedialog.js b/addons/website/static/lib/ckeditor/plugins/sourcedialog/dialogs/sourcedialog.js deleted file mode 100755 index cafba966af5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/dialogs/sourcedialog.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'sourcedialog', function( editor ) { - var size = CKEDITOR.document.getWindow().getViewPaneSize(); - - // Make it maximum 800px wide, but still fully visible in the viewport. - var width = Math.min( size.width - 70, 800); - - // Make it use 2/3 of the viewport height. - var height = size.height / 1.5; - - // Store old editor data to avoid unnecessary setData. - var oldData; - - return { - title: editor.lang.sourcedialog.title, - minWidth: 100, - minHeight: 100, - - onShow: function() { - this.setValueOf( 'main', 'data', oldData = editor.getData() ); - }, - - onOk: (function() { - function setData( newData ) { - var that = this; - - editor.setData( newData, function() { - that.hide(); - - // Ensure correct selection. - var range = editor.createRange(); - range.moveToElementEditStart( editor.editable() ); - range.select(); - } ); - } - - return function( event ) { - // Remove CR from input data for reliable comparison with editor data. - var newData = this.getValueOf( 'main', 'data' ).replace( /\r/g, '' ); - - // Avoid unnecessary setData. Also preserve selection - // when user changed his mind and goes back to wysiwyg editing. - if ( newData === oldData ) - return true; - - // Set data asynchronously to avoid errors in IE. - CKEDITOR.env.ie ? - CKEDITOR.tools.setTimeout( setData, 0, this, newData ) - : - setData.call( this, newData ); - - // Don't let the dialog close before setData is over. - return false; - }; - })(), - - contents: [{ - id: 'main', - label: editor.lang.sourcedialog.title, - elements: [{ - type: 'textarea', - type: 'textarea', - id: 'data', - dir: 'ltr', - inputStyle: 'cursor:auto;' + - 'width:' + width + 'px;' + - 'height:' + height + 'px;' + - 'tab-size:4;' + - 'text-align:left;', - 'class': 'cke_source' - }] - }] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog-rtl.png b/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog-rtl.png Binary files differdeleted file mode 100644 index adf4af3c984..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog.png b/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog.png Binary files differdeleted file mode 100644 index b4d0a15a4d8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog-rtl.png b/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog-rtl.png Binary files differdeleted file mode 100644 index 27d1ba88198..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog.png b/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog.png Binary files differdeleted file mode 100644 index e44db37985a..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/icons/sourcedialog.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/lang/en.js b/addons/website/static/lib/ckeditor/plugins/sourcedialog/lang/en.js deleted file mode 100644 index 80aff46d753..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/lang/en.js +++ /dev/null @@ -1,9 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ - -CKEDITOR.plugins.setLang( 'sourcedialog', 'en', { - toolbar: 'Source', - title: 'Source' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/sourcedialog/plugin.js b/addons/website/static/lib/ckeditor/plugins/sourcedialog/plugin.js deleted file mode 100644 index 932b79c81d9..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/sourcedialog/plugin.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'sourcedialog', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'sourcedialog,sourcedialog-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - - init: function( editor ) { - // Register the "source" command, which simply opens the "source" dialog. - editor.addCommand( 'sourcedialog', new CKEDITOR.dialogCommand( 'sourcedialog' ) ); - - // Register the "source" dialog. - CKEDITOR.dialog.add( 'sourcedialog', this.path + 'dialogs/sourcedialog.js' ); - - // If the toolbar is available, create the "Source" button. - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Sourcedialog', { - label: editor.lang.sourcedialog.toolbar, - command: 'sourcedialog', - toolbar: 'mode,10' - }); - } - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/lang/en.js b/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/lang/en.js deleted file mode 100644 index b3dca6c7643..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/lang/en.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'specialchar', 'en', { - euro: 'Euro sign', - lsquo: 'Left single quotation mark', - rsquo: 'Right single quotation mark', - ldquo: 'Left double quotation mark', - rdquo: 'Right double quotation mark', - ndash: 'En dash', - mdash: 'Em dash', - iexcl: 'Inverted exclamation mark', - cent: 'Cent sign', - pound: 'Pound sign', - curren: 'Currency sign', - yen: 'Yen sign', - brvbar: 'Broken bar', - sect: 'Section sign', - uml: 'Diaeresis', - copy: 'Copyright sign', - ordf: 'Feminine ordinal indicator', - laquo: 'Left-pointing double angle quotation mark', - not: 'Not sign', - reg: 'Registered sign', - macr: 'Macron', - deg: 'Degree sign', - sup2: 'Superscript two', - sup3: 'Superscript three', - acute: 'Acute accent', - micro: 'Micro sign', - para: 'Pilcrow sign', - middot: 'Middle dot', - cedil: 'Cedilla', - sup1: 'Superscript one', - ordm: 'Masculine ordinal indicator', - raquo: 'Right-pointing double angle quotation mark', - frac14: 'Vulgar fraction one quarter', - frac12: 'Vulgar fraction one half', - frac34: 'Vulgar fraction three quarters', - iquest: 'Inverted question mark', - Agrave: 'Latin capital letter A with grave accent', - Aacute: 'Latin capital letter A with acute accent', - Acirc: 'Latin capital letter A with circumflex', - Atilde: 'Latin capital letter A with tilde', - Auml: 'Latin capital letter A with diaeresis', - Aring: 'Latin capital letter A with ring above', - AElig: 'Latin Capital letter Æ', - Ccedil: 'Latin capital letter C with cedilla', - Egrave: 'Latin capital letter E with grave accent', - Eacute: 'Latin capital letter E with acute accent', - Ecirc: 'Latin capital letter E with circumflex', - Euml: 'Latin capital letter E with diaeresis', - Igrave: 'Latin capital letter I with grave accent', - Iacute: 'Latin capital letter I with acute accent', - Icirc: 'Latin capital letter I with circumflex', - Iuml: 'Latin capital letter I with diaeresis', - ETH: 'Latin capital letter Eth', - Ntilde: 'Latin capital letter N with tilde', - Ograve: 'Latin capital letter O with grave accent', - Oacute: 'Latin capital letter O with acute accent', - Ocirc: 'Latin capital letter O with circumflex', - Otilde: 'Latin capital letter O with tilde', - Ouml: 'Latin capital letter O with diaeresis', - times: 'Multiplication sign', - Oslash: 'Latin capital letter O with stroke', - Ugrave: 'Latin capital letter U with grave accent', - Uacute: 'Latin capital letter U with acute accent', - Ucirc: 'Latin capital letter U with circumflex', - Uuml: 'Latin capital letter U with diaeresis', - Yacute: 'Latin capital letter Y with acute accent', - THORN: 'Latin capital letter Thorn', - szlig: 'Latin small letter sharp s', - agrave: 'Latin small letter a with grave accent', - aacute: 'Latin small letter a with acute accent', - acirc: 'Latin small letter a with circumflex', - atilde: 'Latin small letter a with tilde', - auml: 'Latin small letter a with diaeresis', - aring: 'Latin small letter a with ring above', - aelig: 'Latin small letter æ', - ccedil: 'Latin small letter c with cedilla', - egrave: 'Latin small letter e with grave accent', - eacute: 'Latin small letter e with acute accent', - ecirc: 'Latin small letter e with circumflex', - euml: 'Latin small letter e with diaeresis', - igrave: 'Latin small letter i with grave accent', - iacute: 'Latin small letter i with acute accent', - icirc: 'Latin small letter i with circumflex', - iuml: 'Latin small letter i with diaeresis', - eth: 'Latin small letter eth', - ntilde: 'Latin small letter n with tilde', - ograve: 'Latin small letter o with grave accent', - oacute: 'Latin small letter o with acute accent', - ocirc: 'Latin small letter o with circumflex', - otilde: 'Latin small letter o with tilde', - ouml: 'Latin small letter o with diaeresis', - divide: 'Division sign', - oslash: 'Latin small letter o with stroke', - ugrave: 'Latin small letter u with grave accent', - uacute: 'Latin small letter u with acute accent', - ucirc: 'Latin small letter u with circumflex', - uuml: 'Latin small letter u with diaeresis', - yacute: 'Latin small letter y with acute accent', - thorn: 'Latin small letter thorn', - yuml: 'Latin small letter y with diaeresis', - OElig: 'Latin capital ligature OE', - oelig: 'Latin small ligature oe', - '372': 'Latin capital letter W with circumflex', - '374': 'Latin capital letter Y with circumflex', - '373': 'Latin small letter w with circumflex', - '375': 'Latin small letter y with circumflex', - sbquo: 'Single low-9 quotation mark', - '8219': 'Single high-reversed-9 quotation mark', - bdquo: 'Double low-9 quotation mark', - hellip: 'Horizontal ellipsis', - trade: 'Trade mark sign', - '9658': 'Black right-pointing pointer', - bull: 'Bullet', - rarr: 'Rightwards arrow', - rArr: 'Rightwards double arrow', - hArr: 'Left right double arrow', - diams: 'Black diamond suit', - asymp: 'Almost equal to' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/specialchar.js b/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/specialchar.js deleted file mode 100644 index 05aba64544b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/dialogs/specialchar.js +++ /dev/null @@ -1,304 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'specialchar', function( editor ) { - // Simulate "this" of a dialog for non-dialog events. - // @type {CKEDITOR.dialog} - var dialog, - lang = editor.lang.specialchar; - - var onChoice = function( evt ) { - var target, value; - if ( evt.data ) - target = evt.data.getTarget(); - else - target = new CKEDITOR.dom.element( evt ); - - if ( target.getName() == 'a' && ( value = target.getChild( 0 ).getHtml() ) ) { - target.removeClass( "cke_light_background" ); - dialog.hide(); - - // We must use "insertText" here to keep text styled. - var span = editor.document.createElement( 'span' ); - span.setHtml( value ); - editor.insertText( span.getText() ); - } - }; - - var onClick = CKEDITOR.tools.addFunction( onChoice ); - - var focusedNode; - - var onFocus = function( evt, target ) { - var value; - target = target || evt.data.getTarget(); - - if ( target.getName() == 'span' ) - target = target.getParent(); - - if ( target.getName() == 'a' && ( value = target.getChild( 0 ).getHtml() ) ) { - // Trigger blur manually if there is focused node. - if ( focusedNode ) - onBlur( null, focusedNode ); - - var htmlPreview = dialog.getContentElement( 'info', 'htmlPreview' ).getElement(); - - dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( value ); - htmlPreview.setHtml( CKEDITOR.tools.htmlEncode( value ) ); - target.getParent().addClass( "cke_light_background" ); - - // Memorize focused node. - focusedNode = target; - } - }; - - var onBlur = function( evt, target ) { - target = target || evt.data.getTarget(); - - if ( target.getName() == 'span' ) - target = target.getParent(); - - if ( target.getName() == 'a' ) { - dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( ' ' ); - dialog.getContentElement( 'info', 'htmlPreview' ).getElement().setHtml( ' ' ); - target.getParent().removeClass( "cke_light_background" ); - - focusedNode = undefined; - } - }; - - var onKeydown = CKEDITOR.tools.addFunction( function( ev ) { - ev = new CKEDITOR.dom.event( ev ); - - // Get an Anchor element. - var element = ev.getTarget(); - var relative, nodeToMove; - var keystroke = ev.getKeystroke(), - rtl = editor.lang.dir == 'rtl'; - - switch ( keystroke ) { - // UP-ARROW - case 38: - // relative is TR - if ( ( relative = element.getParent().getParent().getPrevious() ) ) { - nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - } - ev.preventDefault(); - break; - // DOWN-ARROW - case 40: - // relative is TR - if ( ( relative = element.getParent().getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); - if ( nodeToMove && nodeToMove.type == 1 ) { - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - } - } - ev.preventDefault(); - break; - // SPACE - // ENTER is already handled as onClick - case 32: - onChoice({ data: ev } ); - ev.preventDefault(); - break; - - // RIGHT-ARROW - case rtl ? 37: - 39 : - // relative is TD - if ( ( relative = element.getParent().getNext() ) ) { - nodeToMove = relative.getChild( 0 ); - if ( nodeToMove.type == 1 ) { - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - ev.preventDefault( true ); - } else - onBlur( null, element ); - } - // relative is TR - else if ( ( relative = element.getParent().getParent().getNext() ) ) { - nodeToMove = relative.getChild( [ 0, 0 ] ); - if ( nodeToMove && nodeToMove.type == 1 ) { - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - ev.preventDefault( true ); - } else - onBlur( null, element ); - } - break; - - // LEFT-ARROW - case rtl ? 39: - 37 : - // relative is TD - if ( ( relative = element.getParent().getPrevious() ) ) { - nodeToMove = relative.getChild( 0 ); - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - ev.preventDefault( true ); - } - // relative is TR - else if ( ( relative = element.getParent().getParent().getPrevious() ) ) { - nodeToMove = relative.getLast().getChild( 0 ); - nodeToMove.focus(); - onBlur( null, element ); - onFocus( null, nodeToMove ); - ev.preventDefault( true ); - } else - onBlur( null, element ); - break; - default: - // Do not stop not handled events. - return; - } - }); - - return { - title: lang.title, - minWidth: 430, - minHeight: 280, - buttons: [ CKEDITOR.dialog.cancelButton ], - charColumns: 17, - onLoad: function() { - var columns = this.definition.charColumns, - extraChars = editor.config.extraSpecialChars, - chars = editor.config.specialChars; - - var charsTableLabel = CKEDITOR.tools.getNextId() + '_specialchar_table_label'; - var html = [ '<table role="listbox" aria-labelledby="' + charsTableLabel + '"' + - ' style="width: 320px; height: 100%; border-collapse: separate;"' + - ' align="center" cellspacing="2" cellpadding="2" border="0">' ]; - - var i = 0, - size = chars.length, - character, charDesc; - - while ( i < size ) { - html.push( '<tr role="presentation">' ); - - for ( var j = 0; j < columns; j++, i++ ) { - if ( ( character = chars[ i ] ) ) { - charDesc = ''; - - if ( character instanceof Array ) { - charDesc = character[ 1 ]; - character = character[ 0 ]; - } else { - var _tmpName = character.replace( '&', '' ).replace( ';', '' ).replace( '#', '' ); - - // Use character in case description unavailable. - charDesc = lang[ _tmpName ] || character; - } - - var charLabelId = 'cke_specialchar_label_' + i + '_' + CKEDITOR.tools.getNextNumber(); - - html.push( '<td class="cke_dark_background" style="cursor: default" role="presentation">' + - '<a href="javascript: void(0);" role="option"' + - ' aria-posinset="' + ( i + 1 ) + '"', ' aria-setsize="' + size + '"', ' aria-labelledby="' + charLabelId + '"', ' class="cke_specialchar" title="', CKEDITOR.tools.htmlEncode( charDesc ), '"' + - ' onkeydown="CKEDITOR.tools.callFunction( ' + onKeydown + ', event, this )"' + - ' onclick="CKEDITOR.tools.callFunction(' + onClick + ', this); return false;"' + - ' tabindex="-1">' + - '<span style="margin: 0 auto;cursor: inherit">' + - character + - '</span>' + - '<span class="cke_voice_label" id="' + charLabelId + '">' + - charDesc + - '</span></a>' ); - } else - html.push( '<td class="cke_dark_background"> ' ); - - html.push( '</td>' ); - } - html.push( '</tr>' ); - } - - html.push( '</tbody></table>', '<span id="' + charsTableLabel + '" class="cke_voice_label">' + lang.options + '</span>' ); - - this.getContentElement( 'info', 'charContainer' ).getElement().setHtml( html.join( '' ) ); - }, - contents: [ - { - id: 'info', - label: editor.lang.common.generalTab, - title: editor.lang.common.generalTab, - padding: 0, - align: 'top', - elements: [ - { - type: 'hbox', - align: 'top', - widths: [ '320px', '90px' ], - children: [ - { - type: 'html', - id: 'charContainer', - html: '', - onMouseover: onFocus, - onMouseout: onBlur, - focus: function() { - var firstChar = this.getElement().getElementsByTag( 'a' ).getItem( 0 ); - setTimeout( function() { - firstChar.focus(); - onFocus( null, firstChar ); - }, 0 ); - }, - onShow: function() { - var firstChar = this.getElement().getChild( [ 0, 0, 0, 0, 0 ] ); - setTimeout( function() { - firstChar.focus(); - onFocus( null, firstChar ); - }, 0 ); - }, - onLoad: function( event ) { - dialog = event.sender; - } - }, - { - type: 'hbox', - align: 'top', - widths: [ '100%' ], - children: [ - { - type: 'vbox', - align: 'top', - children: [ - { - type: 'html', - html: '<div></div>' - }, - { - type: 'html', - id: 'charPreview', - className: 'cke_dark_background', - style: 'border:1px solid #eeeeee;font-size:28px;height:40px;width:70px;padding-top:9px;font-family:\'Microsoft Sans Serif\',Arial,Helvetica,Verdana;text-align:center;', - html: '<div> </div>' - }, - { - type: 'html', - id: 'htmlPreview', - className: 'cke_dark_background', - style: 'border:1px solid #eeeeee;font-size:14px;height:20px;width:70px;padding-top:2px;font-family:\'Microsoft Sans Serif\',Arial,Helvetica,Verdana;text-align:center;', - html: '<div> </div>' - } - ] - } - ] - } - ] - } - ] - } - ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/icons/hidpi/specialchar.png b/addons/website/static/lib/ckeditor/plugins/specialchar/icons/hidpi/specialchar.png Binary files differdeleted file mode 100644 index d47f8453b39..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/icons/hidpi/specialchar.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/icons/specialchar.png b/addons/website/static/lib/ckeditor/plugins/specialchar/icons/specialchar.png Binary files differdeleted file mode 100644 index 6cd278f17fe..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/icons/specialchar.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/lang/en.js b/addons/website/static/lib/ckeditor/plugins/specialchar/lang/en.js deleted file mode 100644 index 263ccbedfb8..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/lang/en.js +++ /dev/null @@ -1,9 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'specialchar', 'en', { - options: 'Special Character Options', - title: 'Select Special Character', - toolbar: 'Insert Special Character' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/specialchar/plugin.js b/addons/website/static/lib/ckeditor/plugins/specialchar/plugin.js deleted file mode 100644 index 812b63407b7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/specialchar/plugin.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Special Character plugin - */ - -CKEDITOR.plugins.add( 'specialchar', { - // List of available localizations. - availableLangs: { ar:1,bg:1,ca:1,cs:1,cy:1,de:1,el:1,en:1,eo:1,es:1,et:1,fa:1,fi:1,fr:1,'fr-ca':1,gl:1,he:1,hr:1,hu:1,id:1,it:1,ja:1,ku:1,lv:1,nb:1,nl:1,no:1,pl:1,pt:1,'pt-br':1,ru:1,si:1,sk:1,sl:1,sq:1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,'zh-cn':1 }, - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - requires: 'dialog', - icons: 'specialchar', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var pluginName = 'specialchar', - plugin = this; - - // Register the dialog. - CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/specialchar.js' ); - - editor.addCommand( pluginName, { - exec: function() { - var langCode = editor.langCode; - langCode = - plugin.availableLangs[ langCode ] ? langCode : - plugin.availableLangs[ langCode.replace( /-.*/, '' ) ] ? langCode.replace( /-.*/, '' ) : - 'en'; - - CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( plugin.path + 'dialogs/lang/' + langCode + '.js' ), function() { - CKEDITOR.tools.extend( editor.lang.specialchar, plugin.langEntries[ langCode ] ); - editor.openDialog( pluginName ); - }); - }, - modes: { wysiwyg:1 }, - canUndo: false - }); - - // Register the toolbar button. - editor.ui.addButton && editor.ui.addButton( 'SpecialChar', { - label: editor.lang.specialchar.toolbar, - command: pluginName, - toolbar: 'insert,50' - }); - } -}); - -/** - * The list of special characters visible in the "Special Character" dialog window. - * - * config.specialChars = [ '"', '’', [ '&custom;', 'Custom label' ] ]; - * config.specialChars = config.specialChars.concat( [ '"', [ '’', 'Custom label' ] ] ); - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.specialChars = [ - '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', - '<', '=', '>', '?', '@', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '[', ']', '^', '_', '`', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '{', '|', '}', '~', - "€", "‘", "’", "“", "”", "–", "—", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "®", "¯", "°", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ", "Œ", "œ", "Ŵ", "Ŷ", "ŵ", "ŷ", "‚", "‛", "„", "…", "™", "►", "•", "→", "⇒", "⇔", "♦", "≈" -]; diff --git a/addons/website/static/lib/ckeditor/plugins/stylescombo/lang/en.js b/addons/website/static/lib/ckeditor/plugins/stylescombo/lang/en.js deleted file mode 100644 index c9f9f5cd397..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/stylescombo/lang/en.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'stylescombo', 'en', { - label: 'Styles', - panelTitle: 'Formatting Styles', - panelTitle1: 'Block Styles', - panelTitle2: 'Inline Styles', - panelTitle3: 'Object Styles' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/stylescombo/plugin.js b/addons/website/static/lib/ckeditor/plugins/stylescombo/plugin.js deleted file mode 100644 index 3a33d0fe020..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/stylescombo/plugin.js +++ /dev/null @@ -1,179 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - 'use strict'; - - CKEDITOR.plugins.add( 'stylescombo', { - requires: 'richcombo', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - - init: function( editor ) { - var config = editor.config, - lang = editor.lang.stylescombo, - styles = {}, - stylesList = [], - combo, - allowedContent = []; - - editor.on( 'stylesSet', function( evt ) { - var stylesDefinitions = evt.data.styles; - - if ( !stylesDefinitions ) - return; - - var style, styleName; - - // Put all styles into an Array. - for ( var i = 0, count = stylesDefinitions.length; i < count; i++ ) { - var styleDefinition = stylesDefinitions[ i ]; - - if ( editor.blockless && ( styleDefinition.element in CKEDITOR.dtd.$block ) ) - continue; - - styleName = styleDefinition.name; - - style = new CKEDITOR.style( styleDefinition ); - - if ( !editor.filter.customConfig || editor.filter.check( style ) ) { - style._name = styleName; - style._.enterMode = config.enterMode; - - // Weight is used to sort styles (#9029). - style._.weight = i + ( style.type == CKEDITOR.STYLE_OBJECT ? 1 : style.type == CKEDITOR.STYLE_BLOCK ? 2 : 3 ) * 1000; - - styles[ styleName ] = style; - stylesList.push( style ); - allowedContent.push( style ); - } - } - - // Sorts the Array, so the styles get grouped by type in proper order (#9029). - stylesList.sort( function( styleA, styleB ) { return styleA._.weight - styleB._.weight; } ); - } ); - - editor.ui.addRichCombo( 'Styles', { - label: lang.label, - title: lang.panelTitle, - toolbar: 'styles,10', - allowedContent: allowedContent, - - panel: { - css: [ CKEDITOR.skin.getPath( 'editor' ) ].concat( config.contentsCss ), - multiSelect: true, - attributes: { 'aria-label': lang.panelTitle } - }, - - init: function() { - var style, styleName, lastType, type, i, count; - - // Loop over the Array, adding all items to the - // combo. - for ( i = 0, count = stylesList.length; i < count; i++ ) { - style = stylesList[ i ]; - styleName = style._name; - type = style.type; - - if ( type != lastType ) { - this.startGroup( lang[ 'panelTitle' + String( type ) ] ); - lastType = type; - } - - this.add( styleName, style.type == CKEDITOR.STYLE_OBJECT ? styleName : style.buildPreview(), styleName ); - } - - this.commit(); - }, - - onClick: function( value ) { - editor.focus(); - editor.fire( 'saveSnapshot' ); - - var style = styles[ value ], - elementPath = editor.elementPath(); - - editor[ style.checkActive( elementPath ) ? 'removeStyle' : 'applyStyle' ]( style ); - editor.fire( 'saveSnapshot' ); - }, - - onRender: function() { - editor.on( 'selectionChange', function( ev ) { - var currentValue = this.getValue(), - elementPath = ev.data.path, - elements = elementPath.elements; - - // For each element into the elements path. - for ( var i = 0, count = elements.length, element; i < count; i++ ) { - element = elements[ i ]; - - // Check if the element is removable by any of - // the styles. - for ( var value in styles ) { - if ( styles[ value ].checkElementRemovable( element, true ) ) { - if ( value != currentValue ) - this.setValue( value ); - return; - } - } - } - - // If no styles match, just empty it. - this.setValue( '' ); - }, this ); - }, - - onOpen: function() { - var selection = editor.getSelection(), - element = selection.getSelectedElement(), - elementPath = editor.elementPath( element ), - counter = [ 0, 0, 0, 0 ]; - this.showAll(); - this.unmarkAll(); - for ( var name in styles ) { - var style = styles[ name ], - type = style.type; - - // Check if block styles are applicable. - if ( type == CKEDITOR.STYLE_BLOCK && !elementPath.isContextFor( style.element ) ) { - this.hideItem( name ); - continue; - } - - if ( style.checkActive( elementPath ) ) - this.mark( name ); - else if ( type == CKEDITOR.STYLE_OBJECT && !style.checkApplicable( elementPath ) ) { - this.hideItem( name ); - counter[ type ]--; - } - - counter[ type ]++; - } - - if ( !counter[ CKEDITOR.STYLE_BLOCK ] ) - this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_BLOCK ) ] ); - - if ( !counter[ CKEDITOR.STYLE_INLINE ] ) - this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_INLINE ) ] ); - - if ( !counter[ CKEDITOR.STYLE_OBJECT ] ) - this.hideGroup( lang[ 'panelTitle' + String( CKEDITOR.STYLE_OBJECT ) ] ); - }, - - // Force a reload of the data - reset: function() { - if ( combo ) { - delete combo._.panel; - delete combo._.list; - combo._.committed = 0; - combo._.items = {}; - combo._.state = CKEDITOR.TRISTATE_OFF; - } - styles = {}; - stylesList = []; - } - }); - } - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/stylesheetparser/plugin.js b/addons/website/static/lib/ckeditor/plugins/stylesheetparser/plugin.js deleted file mode 100644 index 4ba18fb076d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/stylesheetparser/plugin.js +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview stylesheetParser plugin. - */ - -(function() { - // We want to extract only the elements with classes defined in the stylesheets: - function parseClasses( aRules, skipSelectors, validSelectors ) { - // aRules are just the different rules in the style sheets - // We want to merge them and them split them by commas, so we end up with only - // the selectors - var s = aRules.join( ' ' ); - // Remove selectors splitting the elements, leave only the class selector (.) - s = s.replace( /(,|>|\+|~)/g, ' ' ); - // Remove attribute selectors: table[border="0"] - s = s.replace( /\[[^\]]*/g, '' ); - // Remove Ids: div#main - s = s.replace( /#[^\s]*/g, '' ); - // Remove pseudo-selectors and pseudo-elements: :hover :nth-child(2n+1) ::before - s = s.replace( /\:{1,2}[^\s]*/g, '' ); - - s = s.replace( /\s+/g, ' ' ); - - var aSelectors = s.split( ' ' ), - aClasses = []; - - for ( var i = 0; i < aSelectors.length; i++ ) { - var selector = aSelectors[ i ]; - - if ( validSelectors.test( selector ) && !skipSelectors.test( selector ) ) { - // If we still don't know about this one, add it - if ( CKEDITOR.tools.indexOf( aClasses, selector ) == -1 ) - aClasses.push( selector ); - } - } - - return aClasses; - } - - function LoadStylesCSS( theDoc, skipSelectors, validSelectors ) { - var styles = [], - // It will hold all the rules of the applied stylesheets (except those internal to CKEditor) - aRules = [], - i; - - for ( i = 0; i < theDoc.styleSheets.length; i++ ) { - var sheet = theDoc.styleSheets[ i ], - node = sheet.ownerNode || sheet.owningElement; - - // Skip the internal stylesheets - if ( node.getAttribute( 'data-cke-temp' ) ) - continue; - - // Exclude stylesheets injected by extensions - if ( sheet.href && sheet.href.substr( 0, 9 ) == 'chrome://' ) - continue; - - // Bulletproof with x-domain content stylesheet. - try { - var sheetRules = sheet.cssRules || sheet.rules; - for ( var j = 0; j < sheetRules.length; j++ ) - aRules.push( sheetRules[ j ].selectorText ); - } catch ( e ) {} - } - - var aClasses = parseClasses( aRules, skipSelectors, validSelectors ); - - // Add each style to our "Styles" collection. - for ( i = 0; i < aClasses.length; i++ ) { - var oElement = aClasses[ i ].split( '.' ), - element = oElement[ 0 ].toLowerCase(), - sClassName = oElement[ 1 ]; - - styles.push({ - name: element + '.' + sClassName, - element: element, - attributes: { 'class': sClassName } - }); - } - - return styles; - } - - // Register a plugin named "stylesheetparser". - CKEDITOR.plugins.add( 'stylesheetparser', { - init: function( editor ) { - // Stylesheet parser is incompatible with filter (#10136). - editor.filter.disable(); - - var cachedDefinitions; - - editor.once( 'stylesSet', function( evt ) { - // Cancel event and fire it again when styles are ready. - evt.cancel(); - - // Overwrite editor#getStylesSet asap (contentDom is the first moment - // when editor.document is ready), but before stylescombo reads styles set (priority 5). - editor.once( 'contentDom', function() { - editor.getStylesSet( function( definitions ) { - // Rules that must be skipped - var skipSelectors = editor.config.stylesheetParser_skipSelectors || ( /(^body\.|^\.)/i ), - // Rules that are valid - validSelectors = editor.config.stylesheetParser_validSelectors || ( /\w+\.\w+/ ); - - cachedDefinitions = definitions.concat( LoadStylesCSS( editor.document.$, skipSelectors, validSelectors ) ); - - editor.getStylesSet = function( callback ) { - if ( cachedDefinitions ) - return callback( cachedDefinitions ); - }; - - editor.fire( 'stylesSet', { styles: cachedDefinitions } ); - } ); - } ); - }, null, null, 1 ); - } - }); -})(); - - -/** - * A regular expression that defines whether a CSS rule will be - * skipped by the Stylesheet Parser plugin. A CSS rule matching - * the regular expression will be ignored and will not be available - * in the Styles drop-down list. - * - * // Ignore rules for body and caption elements, classes starting with "high", and any class defined for no specific element. - * config.stylesheetParser_skipSelectors = /(^body\.|^caption\.|\.high|^\.)/i; - * - * @since 3.6 - * @cfg {RegExp} [stylesheetParser_skipSelectors=/(^body\.|^\.)/i] - * @member CKEDITOR.config - * @see CKEDITOR.config#stylesheetParser_validSelectors - */ - -/** - * A regular expression that defines which CSS rules will be used - * by the Stylesheet Parser plugin. A CSS rule matching the regular - * expression will be available in the Styles drop-down list. - * - * // Only add rules for p and span elements. - * config.stylesheetParser_validSelectors = /\^(p|span)\.\w+/; - * - * @since 3.6 - * @cfg {RegExp} [stylesheetParser_validSelectors=/\w+\.\w+/] - * @member CKEDITOR.config - * @see CKEDITOR.config#stylesheetParser_skipSelectors - */ diff --git a/addons/website/static/lib/ckeditor/plugins/tab/plugin.js b/addons/website/static/lib/ckeditor/plugins/tab/plugin.js deleted file mode 100644 index 20b03706081..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/tab/plugin.js +++ /dev/null @@ -1,301 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var meta = { - editorFocus: false, - modes: { wysiwyg:1,source:1 } - }; - - var blurCommand = { - exec: function( editor ) { - editor.container.focusNext( true, editor.tabIndex ); - } - }; - - var blurBackCommand = { - exec: function( editor ) { - editor.container.focusPrevious( true, editor.tabIndex ); - } - }; - - function selectNextCellCommand( backward ) { - return { - editorFocus: false, - canUndo: false, - modes: { wysiwyg:1 }, - exec: function( editor ) { - if ( editor.editable().hasFocus ) { - var sel = editor.getSelection(), - path = new CKEDITOR.dom.elementPath( sel.getCommonAncestor(), sel.root ), - cell; - - if ( ( cell = path.contains( { td:1,th:1 }, 1 ) ) ) { - var resultRange = editor.createRange(), - next = CKEDITOR.tools.tryThese( function() { - var row = cell.getParent(), - next = row.$.cells[ cell.$.cellIndex + ( backward ? -1 : 1 ) ]; - - // Invalid any empty value. - next.parentNode.parentNode; - return next; - }, function() { - var row = cell.getParent(), - table = row.getAscendant( 'table' ), - nextRow = table.$.rows[ row.$.rowIndex + ( backward ? -1 : 1 ) ]; - - return nextRow.cells[ backward ? nextRow.cells.length - 1 : 0 ]; - }); - - // Clone one more row at the end of table and select the first newly established cell. - if ( !( next || backward ) ) { - var table = cell.getAscendant( 'table' ).$, - cells = cell.getParent().$.cells; - - var newRow = new CKEDITOR.dom.element( table.insertRow( -1 ), editor.document ); - - for ( var i = 0, count = cells.length; i < count; i++ ) { - var newCell = newRow.append( new CKEDITOR.dom.element( cells[ i ], editor.document ).clone( false, false ) ); - !CKEDITOR.env.ie && newCell.appendBogus(); - } - - resultRange.moveToElementEditStart( newRow ); - } else if ( next ) { - next = new CKEDITOR.dom.element( next ); - resultRange.moveToElementEditStart( next ); - // Avoid selecting empty block makes the cursor blind. - if ( !( resultRange.checkStartOfBlock() && resultRange.checkEndOfBlock() ) ) - resultRange.selectNodeContents( next ); - } else - return true; - - resultRange.select( true ); - return true; - } - } - - return false; - } - }; - } - - CKEDITOR.plugins.add( 'tab', { - init: function( editor ) { - var tabTools = editor.config.enableTabKeyTools !== false, - tabSpaces = editor.config.tabSpaces || 0, - tabText = ''; - - while ( tabSpaces-- ) - tabText += '\xa0'; - - if ( tabText ) { - editor.on( 'key', function( ev ) { - if ( ev.data.keyCode == 9 ) // TAB - { - editor.insertHtml( tabText ); - ev.cancel(); - } - }); - } - - if ( tabTools ) { - editor.on( 'key', function( ev ) { - if ( ev.data.keyCode == 9 && editor.execCommand( 'selectNextCell' ) || // TAB - ev.data.keyCode == ( CKEDITOR.SHIFT + 9 ) && editor.execCommand( 'selectPreviousCell' ) ) // SHIFT+TAB - ev.cancel(); - }); - } - - editor.addCommand( 'blur', CKEDITOR.tools.extend( blurCommand, meta ) ); - editor.addCommand( 'blurBack', CKEDITOR.tools.extend( blurBackCommand, meta ) ); - editor.addCommand( 'selectNextCell', selectNextCellCommand() ); - editor.addCommand( 'selectPreviousCell', selectNextCellCommand( true ) ); - } - }); -})(); - -/** - * Moves the UI focus to the element following this element in the tabindex order. - * - * var element = CKEDITOR.document.getById( 'example' ); - * element.focusNext(); - * - * @param {Boolean} [ignoreChildren=false] - * @param {Number} [indexToUse] - * @member CKEDITOR.dom.element - */ -CKEDITOR.dom.element.prototype.focusNext = function( ignoreChildren, indexToUse ) { - var $ = this.$, - curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ), - passedCurrent, enteredCurrent, elected, electedTabIndex, element, elementTabIndex; - - if ( curTabIndex <= 0 ) { - // If this element has tabindex <= 0 then we must simply look for any - // element following it containing tabindex=0. - - element = this.getNextSourceNode( ignoreChildren, CKEDITOR.NODE_ELEMENT ); - - while ( element ) { - if ( element.isVisible() && element.getTabIndex() === 0 ) { - elected = element; - break; - } - - element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ); - } - } else { - // If this element has tabindex > 0 then we must look for: - // 1. An element following this element with the same tabindex. - // 2. The first element in source other with the lowest tabindex - // that is higher than this element tabindex. - // 3. The first element with tabindex=0. - - element = this.getDocument().getBody().getFirst(); - - while ( ( element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) { - if ( !passedCurrent ) { - if ( !enteredCurrent && element.equals( this ) ) { - enteredCurrent = true; - - // Ignore this element, if required. - if ( ignoreChildren ) { - if ( !( element = element.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) ) - break; - passedCurrent = 1; - } - } else if ( enteredCurrent && !this.contains( element ) ) - passedCurrent = 1; - } - - if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 ) - continue; - - if ( passedCurrent && elementTabIndex == curTabIndex ) { - elected = element; - break; - } - - if ( elementTabIndex > curTabIndex && ( !elected || !electedTabIndex || elementTabIndex < electedTabIndex ) ) { - elected = element; - electedTabIndex = elementTabIndex; - } else if ( !elected && elementTabIndex === 0 ) { - elected = element; - electedTabIndex = elementTabIndex; - } - } - } - - if ( elected ) - elected.focus(); -}; - -/** - * Moves the UI focus to the element before this element in the tabindex order. - * - * var element = CKEDITOR.document.getById( 'example' ); - * element.focusPrevious(); - * - * @param {Boolean} [ignoreChildren=false] - * @param {Number} [indexToUse] - * @member CKEDITOR.dom.element - */ -CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren, indexToUse ) { - var $ = this.$, - curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ), - passedCurrent, enteredCurrent, elected, - electedTabIndex = 0, - elementTabIndex; - - var element = this.getDocument().getBody().getLast(); - - while ( ( element = element.getPreviousSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) { - if ( !passedCurrent ) { - if ( !enteredCurrent && element.equals( this ) ) { - enteredCurrent = true; - - // Ignore this element, if required. - if ( ignoreChildren ) { - if ( !( element = element.getPreviousSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) ) - break; - passedCurrent = 1; - } - } else if ( enteredCurrent && !this.contains( element ) ) - passedCurrent = 1; - } - - if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 ) - continue; - - if ( curTabIndex <= 0 ) { - // If this element has tabindex <= 0 then we must look for: - // 1. An element before this one containing tabindex=0. - // 2. The last element with the highest tabindex. - - if ( passedCurrent && elementTabIndex === 0 ) { - elected = element; - break; - } - - if ( elementTabIndex > electedTabIndex ) { - elected = element; - electedTabIndex = elementTabIndex; - } - } else { - // If this element has tabindex > 0 we must look for: - // 1. An element preceeding this one, with the same tabindex. - // 2. The last element in source other with the highest tabindex - // that is lower than this element tabindex. - - if ( passedCurrent && elementTabIndex == curTabIndex ) { - elected = element; - break; - } - - if ( elementTabIndex < curTabIndex && ( !elected || elementTabIndex > electedTabIndex ) ) { - elected = element; - electedTabIndex = elementTabIndex; - } - } - } - - if ( elected ) - elected.focus(); -}; - -/** - * Intructs the editor to add a number of spaces (` `) to the text when - * hitting the *TAB* key. If set to zero, the *TAB* key will be used to move the - * cursor focus to the next element in the page, out of the editor focus. - * - * config.tabSpaces = 4; - * - * @cfg {Number} [tabSpaces=0] - * @member CKEDITOR.config - */ - -/** - * Allow context-sensitive tab key behaviors, including the following scenarios: - * - * When selection is anchored inside **table cells**: - * - * * If *TAB* is pressed, select the contents of the "next" cell. If in the last - * cell in the table, add a new row to it and focus its first cell. - * * If *SHIFT+TAB* is pressed, select the contents of the "previous" cell. - * Do nothing when it's in the first cell. - * - * Example: - * - * config.enableTabKeyTools = false; - * - * @cfg {Boolean} [enableTabKeyTools=true] - * @member CKEDITOR.config - */ - -// If the TAB key is not supposed to be enabled for navigation, the following -// settings could be used alternatively: -// config.keystrokes.push( -// [ CKEDITOR.ALT + 38 /*Arrow Up*/, 'selectPreviousCell' ], -// [ CKEDITOR.ALT + 40 /*Arrow Down*/, 'selectNextCell' ] -// ); diff --git a/addons/website/static/lib/ckeditor/plugins/table/dialogs/table.js b/addons/website/static/lib/ckeditor/plugins/table/dialogs/table.js deleted file mode 100755 index b35a1f7daff..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/table/dialogs/table.js +++ /dev/null @@ -1,556 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var defaultToPixel = CKEDITOR.tools.cssLength; - - var commitValue = function( data ) { - var id = this.id; - if ( !data.info ) - data.info = {}; - data.info[ id ] = this.getValue(); - }; - - function tableColumns( table ) { - var cols = 0, - maxCols = 0; - for ( var i = 0, row, rows = table.$.rows.length; i < rows; i++ ) { - row = table.$.rows[ i ], cols = 0; - for ( var j = 0, cell, cells = row.cells.length; j < cells; j++ ) { - cell = row.cells[ j ]; - cols += cell.colSpan; - } - - cols > maxCols && ( maxCols = cols ); - } - - return maxCols; - } - - - // Whole-positive-integer validator. - function validatorNum( msg ) { - return function() { - var value = this.getValue(), - pass = !!( CKEDITOR.dialog.validate.integer()( value ) && value > 0 ); - - if ( !pass ) { - alert( msg ); - this.select(); - } - - return pass; - }; - } - - function tableDialog( editor, command ) { - var makeElement = function( name ) { - return new CKEDITOR.dom.element( name, editor.document ); - }; - - var editable = editor.editable(); - - var dialogadvtab = editor.plugins.dialogadvtab; - - return { - title: editor.lang.table.title, - minWidth: 310, - minHeight: CKEDITOR.env.ie ? 310 : 280, - - onLoad: function() { - var dialog = this; - - var styles = dialog.getContentElement( 'advanced', 'advStyles' ); - - if ( styles ) { - styles.on( 'change', function( evt ) { - // Synchronize width value. - var width = this.getStyle( 'width', '' ), - txtWidth = dialog.getContentElement( 'info', 'txtWidth' ); - - txtWidth && txtWidth.setValue( width, true ); - - // Synchronize height value. - var height = this.getStyle( 'height', '' ), - txtHeight = dialog.getContentElement( 'info', 'txtHeight' ); - - txtHeight && txtHeight.setValue( height, true ); - }); - } - }, - - onShow: function() { - // Detect if there's a selected table. - var selection = editor.getSelection(), - ranges = selection.getRanges(), - table; - - var rowsInput = this.getContentElement( 'info', 'txtRows' ), - colsInput = this.getContentElement( 'info', 'txtCols' ), - widthInput = this.getContentElement( 'info', 'txtWidth' ), - heightInput = this.getContentElement( 'info', 'txtHeight' ); - - if ( command == 'tableProperties' ) { - var selected = selection.getSelectedElement(); - if ( selected && selected.is( 'table' ) ) - table = selected; - else if ( ranges.length > 0 ) { - // Webkit could report the following range on cell selection (#4948): - // <table><tr><td>[ </td></tr></table>] - if ( CKEDITOR.env.webkit ) - ranges[ 0 ].shrink( CKEDITOR.NODE_ELEMENT ); - - table = editor.elementPath( ranges[ 0 ].getCommonAncestor( true ) ).contains( 'table', 1 ); - } - - // Save a reference to the selected table, and push a new set of default values. - this._.selectedElement = table; - } - - // Enable or disable the row, cols, width fields. - if ( table ) { - this.setupContent( table ); - rowsInput && rowsInput.disable(); - colsInput && colsInput.disable(); - } else { - rowsInput && rowsInput.enable(); - colsInput && colsInput.enable(); - } - - // Call the onChange method for the widht and height fields so - // they get reflected into the Advanced tab. - widthInput && widthInput.onChange(); - heightInput && heightInput.onChange(); - }, - onOk: function() { - var selection = editor.getSelection(), - bms = this._.selectedElement && selection.createBookmarks(); - - var table = this._.selectedElement || makeElement( 'table' ), - me = this, - data = {}; - - this.commitContent( data, table ); - - if ( data.info ) { - var info = data.info; - - // Generate the rows and cols. - if ( !this._.selectedElement ) { - var tbody = table.append( makeElement( 'tbody' ) ), - rows = parseInt( info.txtRows, 10 ) || 0, - cols = parseInt( info.txtCols, 10 ) || 0; - - for ( var i = 0; i < rows; i++ ) { - var row = tbody.append( makeElement( 'tr' ) ); - for ( var j = 0; j < cols; j++ ) { - var cell = row.append( makeElement( 'td' ) ); - if ( !CKEDITOR.env.ie ) - cell.append( makeElement( 'br' ) ); - } - } - } - - // Modify the table headers. Depends on having rows and cols generated - // correctly so it can't be done in commit functions. - - // Should we make a <thead>? - var headers = info.selHeaders; - if ( !table.$.tHead && ( headers == 'row' || headers == 'both' ) ) { - var thead = new CKEDITOR.dom.element( table.$.createTHead() ); - tbody = table.getElementsByTag( 'tbody' ).getItem( 0 ); - var theRow = tbody.getElementsByTag( 'tr' ).getItem( 0 ); - - // Change TD to TH: - for ( i = 0; i < theRow.getChildCount(); i++ ) { - var th = theRow.getChild( i ); - // Skip bookmark nodes. (#6155) - if ( th.type == CKEDITOR.NODE_ELEMENT && !th.data( 'cke-bookmark' ) ) { - th.renameNode( 'th' ); - th.setAttribute( 'scope', 'col' ); - } - } - thead.append( theRow.remove() ); - } - - if ( table.$.tHead !== null && !( headers == 'row' || headers == 'both' ) ) { - // Move the row out of the THead and put it in the TBody: - thead = new CKEDITOR.dom.element( table.$.tHead ); - tbody = table.getElementsByTag( 'tbody' ).getItem( 0 ); - - var previousFirstRow = tbody.getFirst(); - while ( thead.getChildCount() > 0 ) { - theRow = thead.getFirst(); - for ( i = 0; i < theRow.getChildCount(); i++ ) { - var newCell = theRow.getChild( i ); - if ( newCell.type == CKEDITOR.NODE_ELEMENT ) { - newCell.renameNode( 'td' ); - newCell.removeAttribute( 'scope' ); - } - } - theRow.insertBefore( previousFirstRow ); - } - thead.remove(); - } - - // Should we make all first cells in a row TH? - if ( !this.hasColumnHeaders && ( headers == 'col' || headers == 'both' ) ) { - for ( row = 0; row < table.$.rows.length; row++ ) { - newCell = new CKEDITOR.dom.element( table.$.rows[ row ].cells[ 0 ] ); - newCell.renameNode( 'th' ); - newCell.setAttribute( 'scope', 'row' ); - } - } - - // Should we make all first TH-cells in a row make TD? If 'yes' we do it the other way round :-) - if ( ( this.hasColumnHeaders ) && !( headers == 'col' || headers == 'both' ) ) { - for ( i = 0; i < table.$.rows.length; i++ ) { - row = new CKEDITOR.dom.element( table.$.rows[ i ] ); - if ( row.getParent().getName() == 'tbody' ) { - newCell = new CKEDITOR.dom.element( row.$.cells[ 0 ] ); - newCell.renameNode( 'td' ); - newCell.removeAttribute( 'scope' ); - } - } - } - - // Set the width and height. - info.txtHeight ? table.setStyle( 'height', info.txtHeight ) : table.removeStyle( 'height' ); - info.txtWidth ? table.setStyle( 'width', info.txtWidth ) : table.removeStyle( 'width' ); - - if ( !table.getAttribute( 'style' ) ) - table.removeAttribute( 'style' ); - } - - // Insert the table element if we're creating one. - if ( !this._.selectedElement ) { - editor.insertElement( table ); - // Override the default cursor position after insertElement to place - // cursor inside the first cell (#7959), IE needs a while. - setTimeout( function() { - var firstCell = new CKEDITOR.dom.element( table.$.rows[ 0 ].cells[ 0 ] ); - var range = editor.createRange(); - range.moveToPosition( firstCell, CKEDITOR.POSITION_AFTER_START ); - range.select(); - }, 0 ); - } - // Properly restore the selection, (#4822) but don't break - // because of this, e.g. updated table caption. - else - try { - selection.selectBookmarks( bms ); - } catch ( er ) {} - }, - contents: [ - { - id: 'info', - label: editor.lang.table.title, - elements: [ - { - type: 'hbox', - widths: [ null, null ], - styles: [ 'vertical-align:top' ], - children: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'text', - id: 'txtRows', - 'default': 3, - label: editor.lang.table.rows, - required: true, - controlStyle: 'width:5em', - validate: validatorNum( editor.lang.table.invalidRows ), - setup: function( selectedElement ) { - this.setValue( selectedElement.$.rows.length ); - }, - commit: commitValue - }, - { - type: 'text', - id: 'txtCols', - 'default': 2, - label: editor.lang.table.columns, - required: true, - controlStyle: 'width:5em', - validate: validatorNum( editor.lang.table.invalidCols ), - setup: function( selectedTable ) { - this.setValue( tableColumns( selectedTable ) ); - }, - commit: commitValue - }, - { - type: 'html', - html: ' ' - }, - { - type: 'select', - id: 'selHeaders', - requiredContent: 'th', - 'default': '', - label: editor.lang.table.headers, - items: [ - [ editor.lang.table.headersNone, '' ], - [ editor.lang.table.headersRow, 'row' ], - [ editor.lang.table.headersColumn, 'col' ], - [ editor.lang.table.headersBoth, 'both' ] - ], - setup: function( selectedTable ) { - // Fill in the headers field. - var dialog = this.getDialog(); - dialog.hasColumnHeaders = true; - - // Check if all the first cells in every row are TH - for ( var row = 0; row < selectedTable.$.rows.length; row++ ) { - // If just one cell isn't a TH then it isn't a header column - var headCell = selectedTable.$.rows[ row ].cells[ 0 ]; - if ( headCell && headCell.nodeName.toLowerCase() != 'th' ) { - dialog.hasColumnHeaders = false; - break; - } - } - - // Check if the table contains <thead>. - if ( ( selectedTable.$.tHead !== null ) ) - this.setValue( dialog.hasColumnHeaders ? 'both' : 'row' ); - else - this.setValue( dialog.hasColumnHeaders ? 'col' : '' ); - }, - commit: commitValue - }, - { - type: 'text', - id: 'txtBorder', - requiredContent: 'table[border]', - // Avoid setting border which will then disappear. - 'default': editor.filter.check( 'table[border]' ) ? 1 : 0, - label: editor.lang.table.border, - controlStyle: 'width:3em', - validate: CKEDITOR.dialog.validate[ 'number' ]( editor.lang.table.invalidBorder ), - setup: function( selectedTable ) { - this.setValue( selectedTable.getAttribute( 'border' ) || '' ); - }, - commit: function( data, selectedTable ) { - if ( this.getValue() ) - selectedTable.setAttribute( 'border', this.getValue() ); - else - selectedTable.removeAttribute( 'border' ); - } - }, - { - id: 'cmbAlign', - type: 'select', - requiredContent: 'table[align]', - 'default': '', - label: editor.lang.common.align, - items: [ - [ editor.lang.common.notSet, '' ], - [ editor.lang.common.alignLeft, 'left' ], - [ editor.lang.common.alignCenter, 'center' ], - [ editor.lang.common.alignRight, 'right' ] - ], - setup: function( selectedTable ) { - this.setValue( selectedTable.getAttribute( 'align' ) || '' ); - }, - commit: function( data, selectedTable ) { - if ( this.getValue() ) - selectedTable.setAttribute( 'align', this.getValue() ); - else - selectedTable.removeAttribute( 'align' ); - } - } - ] - }, - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'hbox', - widths: [ '5em' ], - children: [ - { - type: 'text', - id: 'txtWidth', - requiredContent: 'table{width}', - controlStyle: 'width:5em', - label: editor.lang.common.width, - title: editor.lang.common.cssLengthTooltip, - // Smarter default table width. (#9600) - 'default': editor.filter.check( 'table{width}' ) ? ( editable.getSize( 'width' ) < 500 ? '100%' : 500 ) : 0, - getValue: defaultToPixel, - validate: CKEDITOR.dialog.validate.cssLength( editor.lang.common.invalidCssLength.replace( '%1', editor.lang.common.width ) ), - onChange: function() { - var styles = this.getDialog().getContentElement( 'advanced', 'advStyles' ); - styles && styles.updateStyle( 'width', this.getValue() ); - }, - setup: function( selectedTable ) { - var val = selectedTable.getStyle( 'width' ); - this.setValue( val ); - }, - commit: commitValue - } - ] - }, - { - type: 'hbox', - widths: [ '5em' ], - children: [ - { - type: 'text', - id: 'txtHeight', - requiredContent: 'table{height}', - controlStyle: 'width:5em', - label: editor.lang.common.height, - title: editor.lang.common.cssLengthTooltip, - 'default': '', - getValue: defaultToPixel, - validate: CKEDITOR.dialog.validate.cssLength( editor.lang.common.invalidCssLength.replace( '%1', editor.lang.common.height ) ), - onChange: function() { - var styles = this.getDialog().getContentElement( 'advanced', 'advStyles' ); - styles && styles.updateStyle( 'height', this.getValue() ); - }, - - setup: function( selectedTable ) { - var val = selectedTable.getStyle( 'height' ); - val && this.setValue( val ); - }, - commit: commitValue - } - ] - }, - { - type: 'html', - html: ' ' - }, - { - type: 'text', - id: 'txtCellSpace', - requiredContent: 'table[cellspacing]', - controlStyle: 'width:3em', - label: editor.lang.table.cellSpace, - 'default': editor.filter.check( 'table[cellspacing]' ) ? 1 : 0, - validate: CKEDITOR.dialog.validate.number( editor.lang.table.invalidCellSpacing ), - setup: function( selectedTable ) { - this.setValue( selectedTable.getAttribute( 'cellSpacing' ) || '' ); - }, - commit: function( data, selectedTable ) { - if ( this.getValue() ) - selectedTable.setAttribute( 'cellSpacing', this.getValue() ); - else - selectedTable.removeAttribute( 'cellSpacing' ); - } - }, - { - type: 'text', - id: 'txtCellPad', - requiredContent: 'table[cellpadding]', - controlStyle: 'width:3em', - label: editor.lang.table.cellPad, - 'default': editor.filter.check( 'table[cellpadding]' ) ? 1 : 0, - validate: CKEDITOR.dialog.validate.number( editor.lang.table.invalidCellPadding ), - setup: function( selectedTable ) { - this.setValue( selectedTable.getAttribute( 'cellPadding' ) || '' ); - }, - commit: function( data, selectedTable ) { - if ( this.getValue() ) - selectedTable.setAttribute( 'cellPadding', this.getValue() ); - else - selectedTable.removeAttribute( 'cellPadding' ); - } - } - ] - } - ] - }, - { - type: 'html', - align: 'right', - html: '' - }, - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'text', - id: 'txtCaption', - requiredContent: 'caption', - label: editor.lang.table.caption, - setup: function( selectedTable ) { - this.enable(); - - var nodeList = selectedTable.getElementsByTag( 'caption' ); - if ( nodeList.count() > 0 ) { - var caption = nodeList.getItem( 0 ); - var firstElementChild = caption.getFirst( CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT ) ); - - if ( firstElementChild && !firstElementChild.equals( caption.getBogus() ) ) { - this.disable(); - this.setValue( caption.getText() ); - return; - } - - caption = CKEDITOR.tools.trim( caption.getText() ); - this.setValue( caption ); - } - }, - commit: function( data, table ) { - if ( !this.isEnabled() ) - return; - - var caption = this.getValue(), - captionElement = table.getElementsByTag( 'caption' ); - if ( caption ) { - if ( captionElement.count() > 0 ) { - captionElement = captionElement.getItem( 0 ); - captionElement.setHtml( '' ); - } else { - captionElement = new CKEDITOR.dom.element( 'caption', editor.document ); - if ( table.getChildCount() ) - captionElement.insertBefore( table.getFirst() ); - else - captionElement.appendTo( table ); - } - captionElement.append( new CKEDITOR.dom.text( caption, editor.document ) ); - } else if ( captionElement.count() > 0 ) { - for ( var i = captionElement.count() - 1; i >= 0; i-- ) - captionElement.getItem( i ).remove(); - } - } - }, - { - type: 'text', - id: 'txtSummary', - requiredContent: 'table[summary]', - label: editor.lang.table.summary, - setup: function( selectedTable ) { - this.setValue( selectedTable.getAttribute( 'summary' ) || '' ); - }, - commit: function( data, selectedTable ) { - if ( this.getValue() ) - selectedTable.setAttribute( 'summary', this.getValue() ); - else - selectedTable.removeAttribute( 'summary' ); - } - } - ] - } - ] - }, - dialogadvtab && dialogadvtab.createAdvancedTab( editor, null, 'table' ) - ] - }; - } - - CKEDITOR.dialog.add( 'table', function( editor ) { - return tableDialog( editor, 'table' ); - }); - CKEDITOR.dialog.add( 'tableProperties', function( editor ) { - return tableDialog( editor, 'tableProperties' ); - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/table/icons/hidpi/table.png b/addons/website/static/lib/ckeditor/plugins/table/icons/hidpi/table.png Binary files differdeleted file mode 100644 index 992b9c894a1..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/table/icons/hidpi/table.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/table/icons/table.png b/addons/website/static/lib/ckeditor/plugins/table/icons/table.png Binary files differdeleted file mode 100644 index 038171635a3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/table/icons/table.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/table/lang/en.js b/addons/website/static/lib/ckeditor/plugins/table/lang/en.js deleted file mode 100644 index bc3e38c5418..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/table/lang/en.js +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'table', 'en', { - border: 'Border size', - caption: 'Caption', - cell: { - menu: 'Cell', - insertBefore: 'Insert Cell Before', - insertAfter: 'Insert Cell After', - deleteCell: 'Delete Cells', - merge: 'Merge Cells', - mergeRight: 'Merge Right', - mergeDown: 'Merge Down', - splitHorizontal: 'Split Cell Horizontally', - splitVertical: 'Split Cell Vertically', - title: 'Cell Properties', - cellType: 'Cell Type', - rowSpan: 'Rows Span', - colSpan: 'Columns Span', - wordWrap: 'Word Wrap', - hAlign: 'Horizontal Alignment', - vAlign: 'Vertical Alignment', - alignBaseline: 'Baseline', - bgColor: 'Background Color', - borderColor: 'Border Color', - data: 'Data', - header: 'Header', - yes: 'Yes', - no: 'No', - invalidWidth: 'Cell width must be a number.', - invalidHeight: 'Cell height must be a number.', - invalidRowSpan: 'Rows span must be a whole number.', - invalidColSpan: 'Columns span must be a whole number.', - chooseColor: 'Choose' - }, - cellPad: 'Cell padding', - cellSpace: 'Cell spacing', - column: { - menu: 'Column', - insertBefore: 'Insert Column Before', - insertAfter: 'Insert Column After', - deleteColumn: 'Delete Columns' - }, - columns: 'Columns', - deleteTable: 'Delete Table', - headers: 'Headers', - headersBoth: 'Both', - headersColumn: 'First column', - headersNone: 'None', - headersRow: 'First Row', - invalidBorder: 'Border size must be a number.', - invalidCellPadding: 'Cell padding must be a positive number.', - invalidCellSpacing: 'Cell spacing must be a positive number.', - invalidCols: 'Number of columns must be a number greater than 0.', - invalidHeight: 'Table height must be a number.', - invalidRows: 'Number of rows must be a number greater than 0.', - invalidWidth: 'Table width must be a number.', - menu: 'Table Properties', - row: { - menu: 'Row', - insertBefore: 'Insert Row Before', - insertAfter: 'Insert Row After', - deleteRow: 'Delete Rows' - }, - rows: 'Rows', - summary: 'Summary', - title: 'Table Properties', - toolbar: 'Table', - widthPc: 'percent', - widthPx: 'pixels', - widthUnit: 'width unit' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/table/plugin.js b/addons/website/static/lib/ckeditor/plugins/table/plugin.js deleted file mode 100755 index c9e8a930305..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/table/plugin.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'table', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'table', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( editor.blockless ) - return; - - var table = CKEDITOR.plugins.table, - lang = editor.lang.table; - - editor.addCommand( 'table', new CKEDITOR.dialogCommand( 'table', { - context: 'table', - allowedContent: 'table{width,height}[align,border,cellpadding,cellspacing,summary];' + - 'caption tbody thead tfoot;' + - 'th td tr[scope];' + - ( editor.plugins.dialogadvtab ? 'table' + editor.plugins.dialogadvtab.allowedContent() : '' ), - requiredContent: 'table', - contentTransformations: [ - [ 'table{width}: sizeToStyle', 'table[width]: sizeToAttribute' ] - ] - } ) ); - - function createDef( def ) { - return CKEDITOR.tools.extend( def || {}, { - contextSensitive: 1, - refresh: function( editor, path ) { - this.setState( path.contains( 'table', 1 ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - } - }); - } - - editor.addCommand( 'tableProperties', new CKEDITOR.dialogCommand( 'tableProperties', createDef() ) ); - editor.addCommand( 'tableDelete', createDef({ - exec: function( editor ) { - var path = editor.elementPath(), - table = path.contains( 'table', 1 ); - - if ( !table ) - return; - - // If the table's parent has only one child remove it as well (unless it's the body or a table cell) (#5416, #6289) - var parent = table.getParent(); - if ( parent.getChildCount() == 1 && !parent.is( 'body', 'td', 'th' ) ) - table = parent; - - var range = editor.createRange(); - range.moveToPosition( table, CKEDITOR.POSITION_BEFORE_START ); - table.remove(); - range.select(); - } - })); - - editor.ui.addButton && editor.ui.addButton( 'Table', { - label: lang.toolbar, - command: 'table', - toolbar: 'insert,30' - }); - - CKEDITOR.dialog.add( 'table', this.path + 'dialogs/table.js' ); - CKEDITOR.dialog.add( 'tableProperties', this.path + 'dialogs/table.js' ); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - editor.addMenuItems({ - table: { - label: lang.menu, - command: 'tableProperties', - group: 'table', - order: 5 - }, - - tabledelete: { - label: lang.deleteTable, - command: 'tableDelete', - group: 'table', - order: 1 - } - }); - } - - editor.on( 'doubleclick', function( evt ) { - var element = evt.data.element; - - if ( element.is( 'table' ) ) - evt.data.dialog = 'tableProperties'; - }); - - // If the "contextmenu" plugin is loaded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function() { - // menu item state is resolved on commands. - return { - tabledelete: CKEDITOR.TRISTATE_OFF, - table: CKEDITOR.TRISTATE_OFF - }; - }); - } - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/tableresize/plugin.js b/addons/website/static/lib/ckeditor/plugins/tableresize/plugin.js deleted file mode 100644 index 6bb85cab771..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/tableresize/plugin.js +++ /dev/null @@ -1,390 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var pxUnit = CKEDITOR.tools.cssLength, - needsIEHacks = CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ); - - function getWidth( el ) { - return CKEDITOR.env.ie ? el.$.clientWidth : parseInt( el.getComputedStyle( 'width' ), 10 ); - } - - function getBorderWidth( element, side ) { - var computed = element.getComputedStyle( 'border-' + side + '-width' ), - borderMap = { - thin: '0px', - medium: '1px', - thick: '2px' - }; - - if ( computed.indexOf( 'px' ) < 0 ) { - // look up keywords - if ( computed in borderMap && element.getComputedStyle( 'border-style' ) != 'none' ) - computed = borderMap[ computed ]; - else - computed = 0; - } - - return parseInt( computed, 10 ); - } - - // Gets the table row that contains the most columns. - function getMasterPillarRow( table ) { - var $rows = table.$.rows, - maxCells = 0, - cellsCount, $elected, $tr; - - for ( var i = 0, len = $rows.length; i < len; i++ ) { - $tr = $rows[ i ]; - cellsCount = $tr.cells.length; - - if ( cellsCount > maxCells ) { - maxCells = cellsCount; - $elected = $tr; - } - } - - return $elected; - } - - function buildTableColumnPillars( table ) { - var pillars = [], - pillarIndex = -1, - rtl = ( table.getComputedStyle( 'direction' ) == 'rtl' ); - - // Get the raw row element that cointains the most columns. - var $tr = getMasterPillarRow( table ); - - // Get the tbody element and position, which will be used to set the - // top and bottom boundaries. - var tbody = new CKEDITOR.dom.element( table.$.tBodies[ 0 ] ), - tbodyPosition = tbody.getDocumentPosition(); - - // Loop thorugh all cells, building pillars after each one of them. - for ( var i = 0, len = $tr.cells.length; i < len; i++ ) { - // Both the current cell and the successive one will be used in the - // pillar size calculation. - var td = new CKEDITOR.dom.element( $tr.cells[ i ] ), - nextTd = $tr.cells[ i + 1 ] && new CKEDITOR.dom.element( $tr.cells[ i + 1 ] ); - - pillarIndex += td.$.colSpan || 1; - - // Calculate the pillar boundary positions. - var pillarLeft, pillarRight, pillarWidth; - - var x = td.getDocumentPosition().x; - - // Calculate positions based on the current cell. - rtl ? pillarRight = x + getBorderWidth( td, 'left' ) : pillarLeft = x + td.$.offsetWidth - getBorderWidth( td, 'right' ); - - // Calculate positions based on the next cell, if available. - if ( nextTd ) { - x = nextTd.getDocumentPosition().x; - - rtl ? pillarLeft = x + nextTd.$.offsetWidth - getBorderWidth( nextTd, 'right' ) : pillarRight = x + getBorderWidth( nextTd, 'left' ); - } - // Otherwise calculate positions based on the table (for last cell). - else { - x = table.getDocumentPosition().x; - - rtl ? pillarLeft = x : pillarRight = x + table.$.offsetWidth; - } - - pillarWidth = Math.max( pillarRight - pillarLeft, 3 ); - - // The pillar should reflects exactly the shape of the hovered - // column border line. - pillars.push({ - table: table, - index: pillarIndex, - x: pillarLeft, - y: tbodyPosition.y, - width: pillarWidth, - height: tbody.$.offsetHeight, - rtl: rtl } ); - } - - return pillars; - } - - function getPillarAtPosition( pillars, positionX ) { - for ( var i = 0, len = pillars.length; i < len; i++ ) { - var pillar = pillars[ i ]; - - if ( positionX >= pillar.x && positionX <= ( pillar.x + pillar.width ) ) - return pillar; - } - - return null; - } - - function cancel( evt ) { - ( evt.data || evt ).preventDefault(); - } - - function columnResizer( editor ) { - var pillar, document, resizer, isResizing, startOffset, currentShift; - - var leftSideCells, rightSideCells, leftShiftBoundary, rightShiftBoundary; - - function detach() { - pillar = null; - currentShift = 0; - isResizing = 0; - - document.removeListener( 'mouseup', onMouseUp ); - resizer.removeListener( 'mousedown', onMouseDown ); - resizer.removeListener( 'mousemove', onMouseMove ); - - document.getBody().setStyle( 'cursor', 'auto' ); - - // Hide the resizer (remove it on IE7 - #5890). - needsIEHacks ? resizer.remove() : resizer.hide(); - } - - function resizeStart() { - // Before starting to resize, figure out which cells to change - // and the boundaries of this resizing shift. - - var columnIndex = pillar.index, - map = CKEDITOR.tools.buildTableMap( pillar.table ), - leftColumnCells = [], - rightColumnCells = [], - leftMinSize = Number.MAX_VALUE, - rightMinSize = leftMinSize, - rtl = pillar.rtl; - - for ( var i = 0, len = map.length; i < len; i++ ) { - var row = map[ i ], - leftCell = row[ columnIndex + ( rtl ? 1 : 0 ) ], - rightCell = row[ columnIndex + ( rtl ? 0 : 1 ) ]; - - leftCell = leftCell && new CKEDITOR.dom.element( leftCell ); - rightCell = rightCell && new CKEDITOR.dom.element( rightCell ); - - if ( !leftCell || !rightCell || !leftCell.equals( rightCell ) ) { - leftCell && ( leftMinSize = Math.min( leftMinSize, getWidth( leftCell ) ) ); - rightCell && ( rightMinSize = Math.min( rightMinSize, getWidth( rightCell ) ) ); - - leftColumnCells.push( leftCell ); - rightColumnCells.push( rightCell ); - } - } - - // Cache the list of cells to be resized. - leftSideCells = leftColumnCells; - rightSideCells = rightColumnCells; - - // Cache the resize limit boundaries. - leftShiftBoundary = pillar.x - leftMinSize; - rightShiftBoundary = pillar.x + rightMinSize; - - resizer.setOpacity( 0.5 ); - startOffset = parseInt( resizer.getStyle( 'left' ), 10 ); - currentShift = 0; - isResizing = 1; - - resizer.on( 'mousemove', onMouseMove ); - - // Prevent the native drag behavior otherwise 'mousemove' won't fire. - document.on( 'dragstart', cancel ); - } - - function resizeEnd() { - isResizing = 0; - - resizer.setOpacity( 0 ); - - currentShift && resizeColumn(); - - var table = pillar.table; - setTimeout( function() { - table.removeCustomData( '_cke_table_pillars' ); - }, 0 ); - - document.removeListener( 'dragstart', cancel ); - } - - function resizeColumn() { - var rtl = pillar.rtl, - cellsCount = rtl ? rightSideCells.length : leftSideCells.length; - - // Perform the actual resize to table cells, only for those by side of the pillar. - for ( var i = 0; i < cellsCount; i++ ) { - var leftCell = leftSideCells[ i ], - rightCell = rightSideCells[ i ], - table = pillar.table; - - // Defer the resizing to avoid any interference among cells. - CKEDITOR.tools.setTimeout( function( leftCell, leftOldWidth, rightCell, rightOldWidth, tableWidth, sizeShift ) { - leftCell && leftCell.setStyle( 'width', pxUnit( Math.max( leftOldWidth + sizeShift, 0 ) ) ); - rightCell && rightCell.setStyle( 'width', pxUnit( Math.max( rightOldWidth - sizeShift, 0 ) ) ); - - // If we're in the last cell, we need to resize the table as well - if ( tableWidth ) - table.setStyle( 'width', pxUnit( tableWidth + sizeShift * ( rtl ? -1 : 1 ) ) ); - }, 0, this, [ - leftCell, leftCell && getWidth( leftCell ), - rightCell, rightCell && getWidth( rightCell ), - ( !leftCell || !rightCell ) && ( getWidth( table ) + getBorderWidth( table, 'left' ) + getBorderWidth( table, 'right' ) ), - currentShift ] ); - } - } - - function onMouseDown( evt ) { - cancel( evt ); - - resizeStart(); - - document.on( 'mouseup', onMouseUp, this ); - } - - function onMouseUp( evt ) { - evt.removeListener(); - - resizeEnd(); - } - - function onMouseMove( evt ) { - move( evt.data.getPageOffset().x ); - } - - document = editor.document; - - resizer = CKEDITOR.dom.element.createFromHtml( '<div data-cke-temp=1 contenteditable=false unselectable=on ' + - 'style="position:absolute;cursor:col-resize;filter:alpha(opacity=0);opacity:0;' + - 'padding:0;background-color:#004;background-image:none;border:0px none;z-index:10"></div>', document ); - - // Except on IE6/7 (#5890), place the resizer after body to prevent it - // from being editable. - if ( !needsIEHacks ) - document.getDocumentElement().append( resizer ); - - this.attachTo = function( targetPillar ) { - // Accept only one pillar at a time. - if ( isResizing ) - return; - - // On IE6/7, we append the resizer everytime we need it. (#5890) - if ( needsIEHacks ) { - document.getBody().append( resizer ); - currentShift = 0; - } - - pillar = targetPillar; - - resizer.setStyles({ - width: pxUnit( targetPillar.width ), - height: pxUnit( targetPillar.height ), - left: pxUnit( targetPillar.x ), - top: pxUnit( targetPillar.y ) - }); - - // In IE6/7, it's not possible to have custom cursors for floating - // elements in an editable document. Show the resizer in that case, - // to give the user a visual clue. - needsIEHacks && resizer.setOpacity( 0.25 ); - - resizer.on( 'mousedown', onMouseDown, this ); - - document.getBody().setStyle( 'cursor', 'col-resize' ); - - // Display the resizer to receive events but don't show it, - // only change the cursor to resizable shape. - resizer.show(); - }; - - var move = this.move = function( posX ) { - if ( !pillar ) - return 0; - - if ( !isResizing && ( posX < pillar.x || posX > ( pillar.x + pillar.width ) ) ) { - detach(); - return 0; - } - - var resizerNewPosition = posX - Math.round( resizer.$.offsetWidth / 2 ); - - if ( isResizing ) { - if ( resizerNewPosition == leftShiftBoundary || resizerNewPosition == rightShiftBoundary ) - return 1; - - resizerNewPosition = Math.max( resizerNewPosition, leftShiftBoundary ); - resizerNewPosition = Math.min( resizerNewPosition, rightShiftBoundary ); - - currentShift = resizerNewPosition - startOffset; - } - - resizer.setStyle( 'left', pxUnit( resizerNewPosition ) ); - - return 1; - }; - } - - function clearPillarsCache( evt ) { - var target = evt.data.getTarget(); - - if ( evt.name == 'mouseout' ) { - // Bypass interal mouse move. - if ( !target.is( 'table' ) ) - return; - - var dest = new CKEDITOR.dom.element( evt.data.$.relatedTarget || evt.data.$.toElement ); - while ( dest && dest.$ && !dest.equals( target ) && !dest.is( 'body' ) ) - dest = dest.getParent(); - if ( !dest || dest.equals( target ) ) - return; - } - - target.getAscendant( 'table', 1 ).removeCustomData( '_cke_table_pillars' ); - evt.removeListener(); - } - - CKEDITOR.plugins.add( 'tableresize', { - requires: 'tabletools', - - init: function( editor ) { - editor.on( 'contentDom', function() { - var resizer; - - editor.document.getBody().on( 'mousemove', function( evt ) { - evt = evt.data; - - var pageX = evt.getPageOffset().x; - - // If we're already attached to a pillar, simply move the - // resizer. - if ( resizer && resizer.move( pageX ) ) { - cancel( evt ); - return; - } - - // Considering table, tr, td, tbody but nothing else. - var target = evt.getTarget(), - table, pillars; - - if ( !target.is( 'table' ) && !target.getAscendant( 'tbody', 1 ) ) - return; - - table = target.getAscendant( 'table', 1 ); - - if ( !( pillars = table.getCustomData( '_cke_table_pillars' ) ) ) { - // Cache table pillars calculation result. - table.setCustomData( '_cke_table_pillars', ( pillars = buildTableColumnPillars( table ) ) ); - table.on( 'mouseout', clearPillarsCache ); - table.on( 'mousedown', clearPillarsCache ); - } - - var pillar = getPillarAtPosition( pillars, pageX ); - if ( pillar ) { - !resizer && ( resizer = new columnResizer( editor ) ); - resizer.attachTo( pillar ); - } - }); - }); - } - }); - -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/tabletools/dialogs/tableCell.js b/addons/website/static/lib/ckeditor/plugins/tabletools/dialogs/tableCell.js deleted file mode 100644 index f0b7971b5ac..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/tabletools/dialogs/tableCell.js +++ /dev/null @@ -1,418 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'cellProperties', function( editor ) { - var langTable = editor.lang.table, - langCell = langTable.cell, - langCommon = editor.lang.common, - validate = CKEDITOR.dialog.validate, - widthPattern = /^(\d+(?:\.\d+)?)(px|%)$/, - heightPattern = /^(\d+(?:\.\d+)?)px$/, - bind = CKEDITOR.tools.bind, - spacer = { type: 'html', html: ' ' }, - rtl = editor.lang.dir == 'rtl', - colorDialog = editor.plugins.colordialog; - - return { - title: langCell.title, - minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 450 : 410, - minHeight: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ? 230 : 220, - contents: [ - { - id: 'info', - label: langCell.title, - accessKey: 'I', - elements: [ - { - type: 'hbox', - widths: [ '40%', '5%', '40%' ], - children: [ - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'hbox', - widths: [ '70%', '30%' ], - children: [ - { - type: 'text', - id: 'width', - width: '100px', - label: langCommon.width, - validate: validate[ 'number' ]( langCell.invalidWidth ), - - // Extra labelling of width unit type. - onLoad: function() { - var widthType = this.getDialog().getContentElement( 'info', 'widthType' ), - labelElement = widthType.getElement(), - inputElement = this.getInputElement(), - ariaLabelledByAttr = inputElement.getAttribute( 'aria-labelledby' ); - - inputElement.setAttribute( 'aria-labelledby', [ ariaLabelledByAttr, labelElement.$.id ].join( ' ' ) ); - }, - - setup: function( element ) { - var widthAttr = parseInt( element.getAttribute( 'width' ), 10 ), - widthStyle = parseInt( element.getStyle( 'width' ), 10 ); - - !isNaN( widthAttr ) && this.setValue( widthAttr ); - !isNaN( widthStyle ) && this.setValue( widthStyle ); - }, - commit: function( element ) { - var value = parseInt( this.getValue(), 10 ), - unit = this.getDialog().getValueOf( 'info', 'widthType' ); - - if ( !isNaN( value ) ) - element.setStyle( 'width', value + unit ); - else - element.removeStyle( 'width' ); - - element.removeAttribute( 'width' ); - }, - 'default': '' - }, - { - type: 'select', - id: 'widthType', - label: editor.lang.table.widthUnit, - labelStyle: 'visibility:hidden', - 'default': 'px', - items: [ - [ langTable.widthPx, 'px' ], - [ langTable.widthPc, '%' ] - ], - setup: function( selectedCell ) { - var widthMatch = widthPattern.exec( selectedCell.getStyle( 'width' ) || selectedCell.getAttribute( 'width' ) ); - if ( widthMatch ) - this.setValue( widthMatch[ 2 ] ); - } - } - ] - }, - { - type: 'hbox', - widths: [ '70%', '30%' ], - children: [ - { - type: 'text', - id: 'height', - label: langCommon.height, - width: '100px', - 'default': '', - validate: validate[ 'number' ]( langCell.invalidHeight ), - - // Extra labelling of height unit type. - onLoad: function() { - var heightType = this.getDialog().getContentElement( 'info', 'htmlHeightType' ), - labelElement = heightType.getElement(), - inputElement = this.getInputElement(), - ariaLabelledByAttr = inputElement.getAttribute( 'aria-labelledby' ); - - inputElement.setAttribute( 'aria-labelledby', [ ariaLabelledByAttr, labelElement.$.id ].join( ' ' ) ); - }, - - setup: function( element ) { - var heightAttr = parseInt( element.getAttribute( 'height' ), 10 ), - heightStyle = parseInt( element.getStyle( 'height' ), 10 ); - - !isNaN( heightAttr ) && this.setValue( heightAttr ); - !isNaN( heightStyle ) && this.setValue( heightStyle ); - }, - commit: function( element ) { - var value = parseInt( this.getValue(), 10 ); - - if ( !isNaN( value ) ) - element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) ); - else - element.removeStyle( 'height' ); - - element.removeAttribute( 'height' ); - } - }, - { - id: 'htmlHeightType', - type: 'html', - html: '<br />' + langTable.widthPx - } - ] - }, - spacer, - { - type: 'select', - id: 'wordWrap', - label: langCell.wordWrap, - 'default': 'yes', - items: [ - [ langCell.yes, 'yes' ], - [ langCell.no, 'no' ] - ], - setup: function( element ) { - var wordWrapAttr = element.getAttribute( 'noWrap' ), - wordWrapStyle = element.getStyle( 'white-space' ); - - if ( wordWrapStyle == 'nowrap' || wordWrapAttr ) - this.setValue( 'no' ); - }, - commit: function( element ) { - if ( this.getValue() == 'no' ) - element.setStyle( 'white-space', 'nowrap' ); - else - element.removeStyle( 'white-space' ); - - element.removeAttribute( 'noWrap' ); - } - }, - spacer, - { - type: 'select', - id: 'hAlign', - label: langCell.hAlign, - 'default': '', - items: [ - [ langCommon.notSet, '' ], - [ langCommon.alignLeft, 'left' ], - [ langCommon.alignCenter, 'center' ], - [ langCommon.alignRight, 'right' ] - ], - setup: function( element ) { - var alignAttr = element.getAttribute( 'align' ), - textAlignStyle = element.getStyle( 'text-align' ); - - this.setValue( textAlignStyle || alignAttr || '' ); - }, - commit: function( selectedCell ) { - var value = this.getValue(); - - if ( value ) - selectedCell.setStyle( 'text-align', value ); - else - selectedCell.removeStyle( 'text-align' ); - - selectedCell.removeAttribute( 'align' ); - } - }, - { - type: 'select', - id: 'vAlign', - label: langCell.vAlign, - 'default': '', - items: [ - [ langCommon.notSet, '' ], - [ langCommon.alignTop, 'top' ], - [ langCommon.alignMiddle, 'middle' ], - [ langCommon.alignBottom, 'bottom' ], - [ langCell.alignBaseline, 'baseline' ] - ], - setup: function( element ) { - var vAlignAttr = element.getAttribute( 'vAlign' ), - vAlignStyle = element.getStyle( 'vertical-align' ); - - switch ( vAlignStyle ) { - // Ignore all other unrelated style values.. - case 'top': - case 'middle': - case 'bottom': - case 'baseline': - break; - default: - vAlignStyle = ''; - } - - this.setValue( vAlignStyle || vAlignAttr || '' ); - }, - commit: function( element ) { - var value = this.getValue(); - - if ( value ) - element.setStyle( 'vertical-align', value ); - else - element.removeStyle( 'vertical-align' ); - - element.removeAttribute( 'vAlign' ); - } - } - ] - }, - spacer, - { - type: 'vbox', - padding: 0, - children: [ - { - type: 'select', - id: 'cellType', - label: langCell.cellType, - 'default': 'td', - items: [ - [ langCell.data, 'td' ], - [ langCell.header, 'th' ] - ], - setup: function( selectedCell ) { - this.setValue( selectedCell.getName() ); - }, - commit: function( selectedCell ) { - selectedCell.renameNode( this.getValue() ); - } - }, - spacer, - { - type: 'text', - id: 'rowSpan', - label: langCell.rowSpan, - 'default': '', - validate: validate.integer( langCell.invalidRowSpan ), - setup: function( selectedCell ) { - var attrVal = parseInt( selectedCell.getAttribute( 'rowSpan' ), 10 ); - if ( attrVal && attrVal != 1 ) - this.setValue( attrVal ); - }, - commit: function( selectedCell ) { - var value = parseInt( this.getValue(), 10 ); - if ( value && value != 1 ) - selectedCell.setAttribute( 'rowSpan', this.getValue() ); - else - selectedCell.removeAttribute( 'rowSpan' ); - } - }, - { - type: 'text', - id: 'colSpan', - label: langCell.colSpan, - 'default': '', - validate: validate.integer( langCell.invalidColSpan ), - setup: function( element ) { - var attrVal = parseInt( element.getAttribute( 'colSpan' ), 10 ); - if ( attrVal && attrVal != 1 ) - this.setValue( attrVal ); - }, - commit: function( selectedCell ) { - var value = parseInt( this.getValue(), 10 ); - if ( value && value != 1 ) - selectedCell.setAttribute( 'colSpan', this.getValue() ); - else - selectedCell.removeAttribute( 'colSpan' ); - } - }, - spacer, - { - type: 'hbox', - padding: 0, - widths: [ '60%', '40%' ], - children: [ - { - type: 'text', - id: 'bgColor', - label: langCell.bgColor, - 'default': '', - setup: function( element ) { - var bgColorAttr = element.getAttribute( 'bgColor' ), - bgColorStyle = element.getStyle( 'background-color' ); - - this.setValue( bgColorStyle || bgColorAttr ); - }, - commit: function( selectedCell ) { - var value = this.getValue(); - - if ( value ) - selectedCell.setStyle( 'background-color', this.getValue() ); - else - selectedCell.removeStyle( 'background-color' ); - - selectedCell.removeAttribute( 'bgColor' ); - } - }, - colorDialog ? { - type: 'button', - id: 'bgColorChoose', - "class": 'colorChooser', - label: langCell.chooseColor, - onLoad: function() { - // Stick the element to the bottom (#5587) - this.getElement().getParent().setStyle( 'vertical-align', 'bottom' ); - }, - onClick: function() { - editor.getColorFromDialog( function( color ) { - if ( color ) - this.getDialog().getContentElement( 'info', 'bgColor' ).setValue( color ); - this.focus(); - }, this ); - } - } : spacer - ] - }, - spacer, - { - type: 'hbox', - padding: 0, - widths: [ '60%', '40%' ], - children: [ - { - type: 'text', - id: 'borderColor', - label: langCell.borderColor, - 'default': '', - setup: function( element ) { - var borderColorAttr = element.getAttribute( 'borderColor' ), - borderColorStyle = element.getStyle( 'border-color' ); - - this.setValue( borderColorStyle || borderColorAttr ); - }, - commit: function( selectedCell ) { - var value = this.getValue(); - if ( value ) - selectedCell.setStyle( 'border-color', this.getValue() ); - else - selectedCell.removeStyle( 'border-color' ); - - selectedCell.removeAttribute( 'borderColor' ); - } - }, - - colorDialog ? { - type: 'button', - id: 'borderColorChoose', - "class": 'colorChooser', - label: langCell.chooseColor, - style: ( rtl ? 'margin-right' : 'margin-left' ) + ': 10px', - onLoad: function() { - // Stick the element to the bottom (#5587) - this.getElement().getParent().setStyle( 'vertical-align', 'bottom' ); - }, - onClick: function() { - editor.getColorFromDialog( function( color ) { - if ( color ) - this.getDialog().getContentElement( 'info', 'borderColor' ).setValue( color ); - this.focus(); - }, this ); - } - } : spacer - ] - } - ] - } - ] - } - ] - } - ], - onShow: function() { - this.cells = CKEDITOR.plugins.tabletools.getSelectedCells( this._.editor.getSelection() ); - this.setupContent( this.cells[ 0 ] ); - }, - onOk: function() { - var selection = this._.editor.getSelection(), - bookmarks = selection.createBookmarks(); - - var cells = this.cells; - for ( var i = 0; i < cells.length; i++ ) - this.commitContent( cells[ i ] ); - - this._.editor.forceNextSelectionCheck(); - selection.selectBookmarks( bookmarks ); - this._.editor.selectionChange(); - } - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/tabletools/plugin.js b/addons/website/static/lib/ckeditor/plugins/tabletools/plugin.js deleted file mode 100644 index 36e16b88145..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/tabletools/plugin.js +++ /dev/null @@ -1,1030 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var cellNodeRegex = /^(?:td|th)$/; - - function getSelectedCells( selection ) { - var ranges = selection.getRanges(); - var retval = []; - var database = {}; - - function moveOutOfCellGuard( node ) { - // Apply to the first cell only. - if ( retval.length > 0 ) - return; - - // If we are exiting from the first </td>, then the td should definitely be - // included. - if ( node.type == CKEDITOR.NODE_ELEMENT && cellNodeRegex.test( node.getName() ) && !node.getCustomData( 'selected_cell' ) ) { - CKEDITOR.dom.element.setMarker( database, node, 'selected_cell', true ); - retval.push( node ); - } - } - - for ( var i = 0; i < ranges.length; i++ ) { - var range = ranges[ i ]; - - if ( range.collapsed ) { - // Walker does not handle collapsed ranges yet - fall back to old API. - var startNode = range.getCommonAncestor(); - var nearestCell = startNode.getAscendant( 'td', true ) || startNode.getAscendant( 'th', true ); - if ( nearestCell ) - retval.push( nearestCell ); - } else { - var walker = new CKEDITOR.dom.walker( range ); - var node; - walker.guard = moveOutOfCellGuard; - - while ( ( node = walker.next() ) ) { - // If may be possible for us to have a range like this: - // <td>^1</td><td>^2</td> - // The 2nd td shouldn't be included. - // - // So we have to take care to include a td we've entered only when we've - // walked into its children. - - if ( node.type != CKEDITOR.NODE_ELEMENT || !node.is( CKEDITOR.dtd.table ) ) { - var parent = node.getAscendant( 'td', true ) || node.getAscendant( 'th', true ); - if ( parent && !parent.getCustomData( 'selected_cell' ) ) { - CKEDITOR.dom.element.setMarker( database, parent, 'selected_cell', true ); - retval.push( parent ); - } - } - } - } - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - return retval; - } - - function getFocusElementAfterDelCells( cellsToDelete ) { - var i = 0, - last = cellsToDelete.length - 1, - database = {}, - cell, focusedCell, tr; - - while ( ( cell = cellsToDelete[ i++ ] ) ) - CKEDITOR.dom.element.setMarker( database, cell, 'delete_cell', true ); - - // 1.first we check left or right side focusable cell row by row; - i = 0; - while ( ( cell = cellsToDelete[ i++ ] ) ) { - if ( ( focusedCell = cell.getPrevious() ) && !focusedCell.getCustomData( 'delete_cell' ) || ( focusedCell = cell.getNext() ) && !focusedCell.getCustomData( 'delete_cell' ) ) { - CKEDITOR.dom.element.clearAllMarkers( database ); - return focusedCell; - } - } - - CKEDITOR.dom.element.clearAllMarkers( database ); - - // 2. then we check the toppest row (outside the selection area square) focusable cell - tr = cellsToDelete[ 0 ].getParent(); - if ( ( tr = tr.getPrevious() ) ) - return tr.getLast(); - - // 3. last we check the lowerest row focusable cell - tr = cellsToDelete[ last ].getParent(); - if ( ( tr = tr.getNext() ) ) - return tr.getChild( 0 ); - - return null; - } - - function insertRow( selection, insertBefore ) { - var cells = getSelectedCells( selection ), - firstCell = cells[ 0 ], - table = firstCell.getAscendant( 'table' ), - doc = firstCell.getDocument(), - startRow = cells[ 0 ].getParent(), - startRowIndex = startRow.$.rowIndex, - lastCell = cells[ cells.length - 1 ], - endRowIndex = lastCell.getParent().$.rowIndex + lastCell.$.rowSpan - 1, - endRow = new CKEDITOR.dom.element( table.$.rows[ endRowIndex ] ), - rowIndex = insertBefore ? startRowIndex : endRowIndex, - row = insertBefore ? startRow : endRow; - - var map = CKEDITOR.tools.buildTableMap( table ), - cloneRow = map[ rowIndex ], - nextRow = insertBefore ? map[ rowIndex - 1 ] : map[ rowIndex + 1 ], - width = map[ 0 ].length; - - var newRow = doc.createElement( 'tr' ); - for ( var i = 0; cloneRow[ i ] && i < width; i++ ) { - var cell; - // Check whether there's a spanning row here, do not break it. - if ( cloneRow[ i ].rowSpan > 1 && nextRow && cloneRow[ i ] == nextRow[ i ] ) { - cell = cloneRow[ i ]; - cell.rowSpan += 1; - } else { - cell = new CKEDITOR.dom.element( cloneRow[ i ] ).clone(); - cell.removeAttribute( 'rowSpan' ); - !CKEDITOR.env.ie && cell.appendBogus(); - newRow.append( cell ); - cell = cell.$; - } - - i += cell.colSpan - 1; - } - - insertBefore ? newRow.insertBefore( row ) : newRow.insertAfter( row ); - } - - function deleteRows( selectionOrRow ) { - if ( selectionOrRow instanceof CKEDITOR.dom.selection ) { - var cells = getSelectedCells( selectionOrRow ), - firstCell = cells[ 0 ], - table = firstCell.getAscendant( 'table' ), - map = CKEDITOR.tools.buildTableMap( table ), - startRow = cells[ 0 ].getParent(), - startRowIndex = startRow.$.rowIndex, - lastCell = cells[ cells.length - 1 ], - endRowIndex = lastCell.getParent().$.rowIndex + lastCell.$.rowSpan - 1, - rowsToDelete = []; - - // Delete cell or reduce cell spans by checking through the table map. - for ( var i = startRowIndex; i <= endRowIndex; i++ ) { - var mapRow = map[ i ], - row = new CKEDITOR.dom.element( table.$.rows[ i ] ); - - for ( var j = 0; j < mapRow.length; j++ ) { - var cell = new CKEDITOR.dom.element( mapRow[ j ] ), - cellRowIndex = cell.getParent().$.rowIndex; - - if ( cell.$.rowSpan == 1 ) - cell.remove(); - // Row spanned cell. - else { - // Span row of the cell, reduce spanning. - cell.$.rowSpan -= 1; - // Root row of the cell, root cell to next row. - if ( cellRowIndex == i ) { - var nextMapRow = map[ i + 1 ]; - nextMapRow[ j - 1 ] ? cell.insertAfter( new CKEDITOR.dom.element( nextMapRow[ j - 1 ] ) ) : new CKEDITOR.dom.element( table.$.rows[ i + 1 ] ).append( cell, 1 ); - } - } - - j += cell.$.colSpan - 1; - } - - rowsToDelete.push( row ); - } - - var rows = table.$.rows; - - // Where to put the cursor after rows been deleted? - // 1. Into next sibling row if any; - // 2. Into previous sibling row if any; - // 3. Into table's parent element if it's the very last row. - var cursorPosition = new CKEDITOR.dom.element( rows[ endRowIndex + 1 ] || ( startRowIndex > 0 ? rows[ startRowIndex - 1 ] : null ) || table.$.parentNode ); - - for ( i = rowsToDelete.length; i >= 0; i-- ) - deleteRows( rowsToDelete[ i ] ); - - return cursorPosition; - } else if ( selectionOrRow instanceof CKEDITOR.dom.element ) { - table = selectionOrRow.getAscendant( 'table' ); - - if ( table.$.rows.length == 1 ) - table.remove(); - else - selectionOrRow.remove(); - } - - return null; - } - - function getCellColIndex( cell, isStart ) { - var row = cell.getParent(), - rowCells = row.$.cells; - - var colIndex = 0; - for ( var i = 0; i < rowCells.length; i++ ) { - var mapCell = rowCells[ i ]; - colIndex += isStart ? 1 : mapCell.colSpan; - if ( mapCell == cell.$ ) - break; - } - - return colIndex - 1; - } - - function getColumnsIndices( cells, isStart ) { - var retval = isStart ? Infinity : 0; - for ( var i = 0; i < cells.length; i++ ) { - var colIndex = getCellColIndex( cells[ i ], isStart ); - if ( isStart ? colIndex < retval : colIndex > retval ) - retval = colIndex; - } - return retval; - } - - function insertColumn( selection, insertBefore ) { - var cells = getSelectedCells( selection ), - firstCell = cells[ 0 ], - table = firstCell.getAscendant( 'table' ), - startCol = getColumnsIndices( cells, 1 ), - lastCol = getColumnsIndices( cells ), - colIndex = insertBefore ? startCol : lastCol; - - var map = CKEDITOR.tools.buildTableMap( table ), - cloneCol = [], - nextCol = [], - height = map.length; - - for ( var i = 0; i < height; i++ ) { - cloneCol.push( map[ i ][ colIndex ] ); - var nextCell = insertBefore ? map[ i ][ colIndex - 1 ] : map[ i ][ colIndex + 1 ]; - nextCol.push( nextCell ); - } - - for ( i = 0; i < height; i++ ) { - var cell; - - if ( !cloneCol[ i ] ) - continue; - - // Check whether there's a spanning column here, do not break it. - if ( cloneCol[ i ].colSpan > 1 && nextCol[ i ] == cloneCol[ i ] ) { - cell = cloneCol[ i ]; - cell.colSpan += 1; - } else { - cell = new CKEDITOR.dom.element( cloneCol[ i ] ).clone(); - cell.removeAttribute( 'colSpan' ); - !CKEDITOR.env.ie && cell.appendBogus(); - cell[ insertBefore ? 'insertBefore' : 'insertAfter' ].call( cell, new CKEDITOR.dom.element( cloneCol[ i ] ) ); - cell = cell.$; - } - - i += cell.rowSpan - 1; - } - } - - function deleteColumns( selectionOrCell ) { - var cells = getSelectedCells( selectionOrCell ), - firstCell = cells[ 0 ], - lastCell = cells[ cells.length - 1 ], - table = firstCell.getAscendant( 'table' ), - map = CKEDITOR.tools.buildTableMap( table ), - startColIndex, endColIndex, - rowsToDelete = []; - - // Figure out selected cells' column indices. - for ( var i = 0, rows = map.length; i < rows; i++ ) { - for ( var j = 0, cols = map[ i ].length; j < cols; j++ ) { - if ( map[ i ][ j ] == firstCell.$ ) - startColIndex = j; - if ( map[ i ][ j ] == lastCell.$ ) - endColIndex = j; - } - } - - // Delete cell or reduce cell spans by checking through the table map. - for ( i = startColIndex; i <= endColIndex; i++ ) { - for ( j = 0; j < map.length; j++ ) { - var mapRow = map[ j ], - row = new CKEDITOR.dom.element( table.$.rows[ j ] ), - cell = new CKEDITOR.dom.element( mapRow[ i ] ); - - if ( cell.$ ) { - if ( cell.$.colSpan == 1 ) - cell.remove(); - // Reduce the col spans. - else - cell.$.colSpan -= 1; - - j += cell.$.rowSpan - 1; - - if ( !row.$.cells.length ) - rowsToDelete.push( row ); - } - } - } - - var firstRowCells = table.$.rows[ 0 ] && table.$.rows[ 0 ].cells; - - // Where to put the cursor after columns been deleted? - // 1. Into next cell of the first row if any; - // 2. Into previous cell of the first row if any; - // 3. Into table's parent element; - var cursorPosition = new CKEDITOR.dom.element( firstRowCells[ startColIndex ] || ( startColIndex ? firstRowCells[ startColIndex - 1 ] : table.$.parentNode ) ); - - // Delete table rows only if all columns are gone (do not remove empty row). - if ( rowsToDelete.length == rows ) - table.remove(); - - return cursorPosition; - } - - function getFocusElementAfterDelCols( cells ) { - var cellIndexList = [], - table = cells[ 0 ] && cells[ 0 ].getAscendant( 'table' ), - i, length, targetIndex, targetCell; - - // get the cellIndex list of delete cells - for ( i = 0, length = cells.length; i < length; i++ ) - cellIndexList.push( cells[ i ].$.cellIndex ); - - // get the focusable column index - cellIndexList.sort(); - for ( i = 1, length = cellIndexList.length; i < length; i++ ) { - if ( cellIndexList[ i ] - cellIndexList[ i - 1 ] > 1 ) { - targetIndex = cellIndexList[ i - 1 ] + 1; - break; - } - } - - if ( !targetIndex ) - targetIndex = cellIndexList[ 0 ] > 0 ? ( cellIndexList[ 0 ] - 1 ) : ( cellIndexList[ cellIndexList.length - 1 ] + 1 ); - - // scan row by row to get the target cell - var rows = table.$.rows; - for ( i = 0, length = rows.length; i < length; i++ ) { - targetCell = rows[ i ].cells[ targetIndex ]; - if ( targetCell ) - break; - } - - return targetCell ? new CKEDITOR.dom.element( targetCell ) : table.getPrevious(); - } - - function insertCell( selection, insertBefore ) { - var startElement = selection.getStartElement(); - var cell = startElement.getAscendant( 'td', 1 ) || startElement.getAscendant( 'th', 1 ); - - if ( !cell ) - return; - - // Create the new cell element to be added. - var newCell = cell.clone(); - if ( !CKEDITOR.env.ie ) - newCell.appendBogus(); - - if ( insertBefore ) - newCell.insertBefore( cell ); - else - newCell.insertAfter( cell ); - } - - function deleteCells( selectionOrCell ) { - if ( selectionOrCell instanceof CKEDITOR.dom.selection ) { - var cellsToDelete = getSelectedCells( selectionOrCell ); - var table = cellsToDelete[ 0 ] && cellsToDelete[ 0 ].getAscendant( 'table' ); - var cellToFocus = getFocusElementAfterDelCells( cellsToDelete ); - - for ( var i = cellsToDelete.length - 1; i >= 0; i-- ) - deleteCells( cellsToDelete[ i ] ); - - if ( cellToFocus ) - placeCursorInCell( cellToFocus, true ); - else if ( table ) - table.remove(); - } else if ( selectionOrCell instanceof CKEDITOR.dom.element ) { - var tr = selectionOrCell.getParent(); - if ( tr.getChildCount() == 1 ) - tr.remove(); - else - selectionOrCell.remove(); - } - } - - // Remove filler at end and empty spaces around the cell content. - function trimCell( cell ) { - var bogus = cell.getBogus(); - bogus && bogus.remove(); - cell.trim(); - } - - function placeCursorInCell( cell, placeAtEnd ) { - var range = new CKEDITOR.dom.range( cell.getDocument() ); - if ( !range[ 'moveToElementEdit' + ( placeAtEnd ? 'End' : 'Start' ) ]( cell ) ) { - range.selectNodeContents( cell ); - range.collapse( placeAtEnd ? false : true ); - } - range.select( true ); - } - - function cellInRow( tableMap, rowIndex, cell ) { - var oRow = tableMap[ rowIndex ]; - if ( typeof cell == 'undefined' ) - return oRow; - - for ( var c = 0; oRow && c < oRow.length; c++ ) { - if ( cell.is && oRow[ c ] == cell.$ ) - return c; - else if ( c == cell ) - return new CKEDITOR.dom.element( oRow[ c ] ); - } - return cell.is ? -1 : null; - } - - function cellInCol( tableMap, colIndex ) { - var oCol = []; - for ( var r = 0; r < tableMap.length; r++ ) { - var row = tableMap[ r ]; - oCol.push( row[ colIndex ] ); - - // Avoid adding duplicate cells. - if ( row[ colIndex ].rowSpan > 1 ) - r += row[ colIndex ].rowSpan - 1; - } - return oCol; - } - - function mergeCells( selection, mergeDirection, isDetect ) { - var cells = getSelectedCells( selection ); - - // Invalid merge request if: - // 1. In batch mode despite that less than two selected. - // 2. In solo mode while not exactly only one selected. - // 3. Cells distributed in different table groups (e.g. from both thead and tbody). - var commonAncestor; - if ( ( mergeDirection ? cells.length != 1 : cells.length < 2 ) || ( commonAncestor = selection.getCommonAncestor() ) && commonAncestor.type == CKEDITOR.NODE_ELEMENT && commonAncestor.is( 'table' ) ) { - return false; - } - - var cell, - firstCell = cells[ 0 ], - table = firstCell.getAscendant( 'table' ), - map = CKEDITOR.tools.buildTableMap( table ), - mapHeight = map.length, - mapWidth = map[ 0 ].length, - startRow = firstCell.getParent().$.rowIndex, - startColumn = cellInRow( map, startRow, firstCell ); - - if ( mergeDirection ) { - var targetCell; - try { - var rowspan = parseInt( firstCell.getAttribute( 'rowspan' ), 10 ) || 1; - var colspan = parseInt( firstCell.getAttribute( 'colspan' ), 10 ) || 1; - - targetCell = map[ mergeDirection == 'up' ? ( startRow - rowspan ) : mergeDirection == 'down' ? ( startRow + rowspan ) : startRow ][ - mergeDirection == 'left' ? - ( startColumn - colspan ) : - mergeDirection == 'right' ? ( startColumn + colspan ) : startColumn ]; - - } catch ( er ) { - return false; - } - - // 1. No cell could be merged. - // 2. Same cell actually. - if ( !targetCell || firstCell.$ == targetCell ) - return false; - - // Sort in map order regardless of the DOM sequence. - cells[ ( mergeDirection == 'up' || mergeDirection == 'left' ) ? 'unshift' : 'push' ]( new CKEDITOR.dom.element( targetCell ) ); - } - - // Start from here are merging way ignorance (merge up/right, batch merge). - var doc = firstCell.getDocument(), - lastRowIndex = startRow, - totalRowSpan = 0, - totalColSpan = 0, - // Use a documentFragment as buffer when appending cell contents. - frag = !isDetect && new CKEDITOR.dom.documentFragment( doc ), - dimension = 0; - - for ( var i = 0; i < cells.length; i++ ) { - cell = cells[ i ]; - - var tr = cell.getParent(), - cellFirstChild = cell.getFirst(), - colSpan = cell.$.colSpan, - rowSpan = cell.$.rowSpan, - rowIndex = tr.$.rowIndex, - colIndex = cellInRow( map, rowIndex, cell ); - - // Accumulated the actual places taken by all selected cells. - dimension += colSpan * rowSpan; - // Accumulated the maximum virtual spans from column and row. - totalColSpan = Math.max( totalColSpan, colIndex - startColumn + colSpan ); - totalRowSpan = Math.max( totalRowSpan, rowIndex - startRow + rowSpan ); - - if ( !isDetect ) { - // Trim all cell fillers and check to remove empty cells. - if ( trimCell( cell ), cell.getChildren().count() ) { - // Merge vertically cells as two separated paragraphs. - if ( rowIndex != lastRowIndex && cellFirstChild && !( cellFirstChild.isBlockBoundary && cellFirstChild.isBlockBoundary( { br:1 } ) ) ) { - var last = frag.getLast( CKEDITOR.dom.walker.whitespaces( true ) ); - if ( last && !( last.is && last.is( 'br' ) ) ) - frag.append( 'br' ); - } - - cell.moveChildren( frag ); - } - i ? cell.remove() : cell.setHtml( '' ); - } - lastRowIndex = rowIndex; - } - - if ( !isDetect ) { - frag.moveChildren( firstCell ); - - if ( !CKEDITOR.env.ie ) - firstCell.appendBogus(); - - if ( totalColSpan >= mapWidth ) - firstCell.removeAttribute( 'rowSpan' ); - else - firstCell.$.rowSpan = totalRowSpan; - - if ( totalRowSpan >= mapHeight ) - firstCell.removeAttribute( 'colSpan' ); - else - firstCell.$.colSpan = totalColSpan; - - // Swip empty <tr> left at the end of table due to the merging. - var trs = new CKEDITOR.dom.nodeList( table.$.rows ), - count = trs.count(); - - for ( i = count - 1; i >= 0; i-- ) { - var tailTr = trs.getItem( i ); - if ( !tailTr.$.cells.length ) { - tailTr.remove(); - count++; - continue; - } - } - - return firstCell; - } - // Be able to merge cells only if actual dimension of selected - // cells equals to the caculated rectangle. - else - return ( totalRowSpan * totalColSpan ) == dimension; - } - - function verticalSplitCell( selection, isDetect ) { - var cells = getSelectedCells( selection ); - if ( cells.length > 1 ) - return false; - else if ( isDetect ) - return true; - - var cell = cells[ 0 ], - tr = cell.getParent(), - table = tr.getAscendant( 'table' ), - map = CKEDITOR.tools.buildTableMap( table ), - rowIndex = tr.$.rowIndex, - colIndex = cellInRow( map, rowIndex, cell ), - rowSpan = cell.$.rowSpan, - newCell, newRowSpan, newCellRowSpan, newRowIndex; - - if ( rowSpan > 1 ) { - newRowSpan = Math.ceil( rowSpan / 2 ); - newCellRowSpan = Math.floor( rowSpan / 2 ); - newRowIndex = rowIndex + newRowSpan; - var newCellTr = new CKEDITOR.dom.element( table.$.rows[ newRowIndex ] ), - newCellRow = cellInRow( map, newRowIndex ), - candidateCell; - - newCell = cell.clone(); - - // Figure out where to insert the new cell by checking the vitual row. - for ( var c = 0; c < newCellRow.length; c++ ) { - candidateCell = newCellRow[ c ]; - // Catch first cell actually following the column. - if ( candidateCell.parentNode == newCellTr.$ && c > colIndex ) { - newCell.insertBefore( new CKEDITOR.dom.element( candidateCell ) ); - break; - } else - candidateCell = null; - } - - // The destination row is empty, append at will. - if ( !candidateCell ) - newCellTr.append( newCell, true ); - } else { - newCellRowSpan = newRowSpan = 1; - - newCellTr = tr.clone(); - newCellTr.insertAfter( tr ); - newCellTr.append( newCell = cell.clone() ); - - var cellsInSameRow = cellInRow( map, rowIndex ); - for ( var i = 0; i < cellsInSameRow.length; i++ ) - cellsInSameRow[ i ].rowSpan++; - } - - if ( !CKEDITOR.env.ie ) - newCell.appendBogus(); - - cell.$.rowSpan = newRowSpan; - newCell.$.rowSpan = newCellRowSpan; - if ( newRowSpan == 1 ) - cell.removeAttribute( 'rowSpan' ); - if ( newCellRowSpan == 1 ) - newCell.removeAttribute( 'rowSpan' ); - - return newCell; - } - - function horizontalSplitCell( selection, isDetect ) { - var cells = getSelectedCells( selection ); - if ( cells.length > 1 ) - return false; - else if ( isDetect ) - return true; - - var cell = cells[ 0 ], - tr = cell.getParent(), - table = tr.getAscendant( 'table' ), - map = CKEDITOR.tools.buildTableMap( table ), - rowIndex = tr.$.rowIndex, - colIndex = cellInRow( map, rowIndex, cell ), - colSpan = cell.$.colSpan, - newCell, newColSpan, newCellColSpan; - - if ( colSpan > 1 ) { - newColSpan = Math.ceil( colSpan / 2 ); - newCellColSpan = Math.floor( colSpan / 2 ); - } else { - newCellColSpan = newColSpan = 1; - var cellsInSameCol = cellInCol( map, colIndex ); - for ( var i = 0; i < cellsInSameCol.length; i++ ) - cellsInSameCol[ i ].colSpan++; - } - newCell = cell.clone(); - newCell.insertAfter( cell ); - if ( !CKEDITOR.env.ie ) - newCell.appendBogus(); - - cell.$.colSpan = newColSpan; - newCell.$.colSpan = newCellColSpan; - if ( newColSpan == 1 ) - cell.removeAttribute( 'colSpan' ); - if ( newCellColSpan == 1 ) - newCell.removeAttribute( 'colSpan' ); - - return newCell; - } - // Context menu on table caption incorrect (#3834) - var contextMenuTags = { thead:1,tbody:1,tfoot:1,td:1,tr:1,th:1 }; - - CKEDITOR.plugins.tabletools = { - requires: 'table,dialog,contextmenu', - init: function( editor ) { - var lang = editor.lang.table; - - function createDef( def ) { - return CKEDITOR.tools.extend( def || {}, { - contextSensitive: 1, - refresh: function( editor, path ) { - this.setState( path.contains( { td:1,th:1 }, 1 ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - } - }); - } - function addCmd( name, def ) { - var cmd = editor.addCommand( name, def ); - editor.addFeature( cmd ); - } - - addCmd( 'cellProperties', new CKEDITOR.dialogCommand( 'cellProperties', createDef( { - allowedContent: 'td th{width,height,border-color,background-color,white-space,vertical-align,text-align}[colspan,rowspan]', - requiredContent: 'table' - } ) ) ); - CKEDITOR.dialog.add( 'cellProperties', this.path + 'dialogs/tableCell.js' ); - - addCmd( 'rowDelete', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - placeCursorInCell( deleteRows( selection ) ); - } - } ) ); - - addCmd( 'rowInsertBefore', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertRow( selection, true ); - } - } ) ); - - addCmd( 'rowInsertAfter', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertRow( selection ); - } - } ) ); - - addCmd( 'columnDelete', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - var element = deleteColumns( selection ); - element && placeCursorInCell( element, true ); - } - } ) ); - - addCmd( 'columnInsertBefore', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertColumn( selection, true ); - } - } ) ); - - addCmd( 'columnInsertAfter', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertColumn( selection ); - } - } ) ); - - addCmd( 'cellDelete', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - deleteCells( selection ); - } - } ) ); - - addCmd( 'cellMerge', createDef( { - allowedContent: 'td[colspan,rowspan]', - requiredContent: 'td[colspan,rowspan]', - exec: function( editor ) { - placeCursorInCell( mergeCells( editor.getSelection() ), true ); - } - } ) ); - - addCmd( 'cellMergeRight', createDef( { - allowedContent: 'td[colspan]', - requiredContent: 'td[colspan]', - exec: function( editor ) { - placeCursorInCell( mergeCells( editor.getSelection(), 'right' ), true ); - } - } ) ); - - addCmd( 'cellMergeDown', createDef( { - allowedContent: 'td[rowspan]', - requiredContent: 'td[rowspan]', - exec: function( editor ) { - placeCursorInCell( mergeCells( editor.getSelection(), 'down' ), true ); - } - } ) ); - - addCmd( 'cellVerticalSplit', createDef( { - allowedContent: 'td[rowspan]', - requiredContent: 'td[rowspan]', - exec: function( editor ) { - placeCursorInCell( verticalSplitCell( editor.getSelection() ) ); - } - } ) ); - - addCmd( 'cellHorizontalSplit', createDef( { - allowedContent: 'td[colspan]', - requiredContent: 'td[colspan]', - exec: function( editor ) { - placeCursorInCell( horizontalSplitCell( editor.getSelection() ) ); - } - } ) ); - - addCmd( 'cellInsertBefore', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertCell( selection, true ); - } - } ) ); - - addCmd( 'cellInsertAfter', createDef( { - requiredContent: 'table', - exec: function( editor ) { - var selection = editor.getSelection(); - insertCell( selection ); - } - } ) ); - - // If the "menu" plugin is loaded, register the menu items. - if ( editor.addMenuItems ) { - editor.addMenuItems({ - tablecell: { - label: lang.cell.menu, - group: 'tablecell', - order: 1, - getItems: function() { - var selection = editor.getSelection(), - cells = getSelectedCells( selection ); - return { - tablecell_insertBefore: CKEDITOR.TRISTATE_OFF, - tablecell_insertAfter: CKEDITOR.TRISTATE_OFF, - tablecell_delete: CKEDITOR.TRISTATE_OFF, - tablecell_merge: mergeCells( selection, null, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED, - tablecell_merge_right: mergeCells( selection, 'right', true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED, - tablecell_merge_down: mergeCells( selection, 'down', true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED, - tablecell_split_vertical: verticalSplitCell( selection, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED, - tablecell_split_horizontal: horizontalSplitCell( selection, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED, - tablecell_properties: cells.length > 0 ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED - }; - } - }, - - tablecell_insertBefore: { - label: lang.cell.insertBefore, - group: 'tablecell', - command: 'cellInsertBefore', - order: 5 - }, - - tablecell_insertAfter: { - label: lang.cell.insertAfter, - group: 'tablecell', - command: 'cellInsertAfter', - order: 10 - }, - - tablecell_delete: { - label: lang.cell.deleteCell, - group: 'tablecell', - command: 'cellDelete', - order: 15 - }, - - tablecell_merge: { - label: lang.cell.merge, - group: 'tablecell', - command: 'cellMerge', - order: 16 - }, - - tablecell_merge_right: { - label: lang.cell.mergeRight, - group: 'tablecell', - command: 'cellMergeRight', - order: 17 - }, - - tablecell_merge_down: { - label: lang.cell.mergeDown, - group: 'tablecell', - command: 'cellMergeDown', - order: 18 - }, - - tablecell_split_horizontal: { - label: lang.cell.splitHorizontal, - group: 'tablecell', - command: 'cellHorizontalSplit', - order: 19 - }, - - tablecell_split_vertical: { - label: lang.cell.splitVertical, - group: 'tablecell', - command: 'cellVerticalSplit', - order: 20 - }, - - tablecell_properties: { - label: lang.cell.title, - group: 'tablecellproperties', - command: 'cellProperties', - order: 21 - }, - - tablerow: { - label: lang.row.menu, - group: 'tablerow', - order: 1, - getItems: function() { - return { - tablerow_insertBefore: CKEDITOR.TRISTATE_OFF, - tablerow_insertAfter: CKEDITOR.TRISTATE_OFF, - tablerow_delete: CKEDITOR.TRISTATE_OFF - }; - } - }, - - tablerow_insertBefore: { - label: lang.row.insertBefore, - group: 'tablerow', - command: 'rowInsertBefore', - order: 5 - }, - - tablerow_insertAfter: { - label: lang.row.insertAfter, - group: 'tablerow', - command: 'rowInsertAfter', - order: 10 - }, - - tablerow_delete: { - label: lang.row.deleteRow, - group: 'tablerow', - command: 'rowDelete', - order: 15 - }, - - tablecolumn: { - label: lang.column.menu, - group: 'tablecolumn', - order: 1, - getItems: function() { - return { - tablecolumn_insertBefore: CKEDITOR.TRISTATE_OFF, - tablecolumn_insertAfter: CKEDITOR.TRISTATE_OFF, - tablecolumn_delete: CKEDITOR.TRISTATE_OFF - }; - } - }, - - tablecolumn_insertBefore: { - label: lang.column.insertBefore, - group: 'tablecolumn', - command: 'columnInsertBefore', - order: 5 - }, - - tablecolumn_insertAfter: { - label: lang.column.insertAfter, - group: 'tablecolumn', - command: 'columnInsertAfter', - order: 10 - }, - - tablecolumn_delete: { - label: lang.column.deleteColumn, - group: 'tablecolumn', - command: 'columnDelete', - order: 15 - } - }); - } - - // If the "contextmenu" plugin is laoded, register the listeners. - if ( editor.contextMenu ) { - editor.contextMenu.addListener( function( element, selection, path ) { - var cell = path.contains( { 'td':1,'th':1 }, 1 ); - if ( cell && !cell.isReadOnly() ) { - return { - tablecell: CKEDITOR.TRISTATE_OFF, - tablerow: CKEDITOR.TRISTATE_OFF, - tablecolumn: CKEDITOR.TRISTATE_OFF - }; - } - - return null; - }); - } - }, - - getSelectedCells: getSelectedCells - - }; - CKEDITOR.plugins.add( 'tabletools', CKEDITOR.plugins.tabletools ); -})(); - -/** - * Create a two-dimension array that reflects the actual layout of table cells, - * with cell spans, with mappings to the original td elements. - * - * @param {CKEDITOR.dom.element} table - * @member CKEDITOR.tools - */ -CKEDITOR.tools.buildTableMap = function( table ) { - var aRows = table.$.rows; - - // Row and Column counters. - var r = -1; - - var aMap = []; - - for ( var i = 0; i < aRows.length; i++ ) { - r++; - !aMap[ r ] && ( aMap[ r ] = [] ); - - var c = -1; - - for ( var j = 0; j < aRows[ i ].cells.length; j++ ) { - var oCell = aRows[ i ].cells[ j ]; - - c++; - while ( aMap[ r ][ c ] ) - c++; - - var iColSpan = isNaN( oCell.colSpan ) ? 1 : oCell.colSpan; - var iRowSpan = isNaN( oCell.rowSpan ) ? 1 : oCell.rowSpan; - - for ( var rs = 0; rs < iRowSpan; rs++ ) { - if ( !aMap[ r + rs ] ) - aMap[ r + rs ] = []; - - for ( var cs = 0; cs < iColSpan; cs++ ) { - aMap[ r + rs ][ c + cs ] = aRows[ i ].cells[ j ]; - } - } - - c += iColSpan - 1; - } - } - return aMap; -}; diff --git a/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.css b/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.css deleted file mode 100644 index dfc80b922dc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.css +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ - -.cke_tpl_list -{ - border: #dcdcdc 2px solid; - background-color: #ffffff; - overflow-y: auto; - overflow-x: hidden; - width: 100%; - height: 220px; -} - -.cke_tpl_item -{ - margin: 5px; - padding: 7px; - border: #eeeeee 1px solid; - *width: 88%; -} - -.cke_tpl_preview -{ - border-collapse: separate; - text-indent:0; - width: 100%; -} -.cke_tpl_preview td -{ - padding: 2px; - vertical-align: middle; -} -.cke_tpl_preview .cke_tpl_preview_img -{ - width: 100px; -} -.cke_tpl_preview span -{ - white-space: normal; -} - -.cke_tpl_title -{ - font-weight: bold; -} - -.cke_tpl_list a:hover .cke_tpl_item, -.cke_tpl_list a:focus .cke_tpl_item, -.cke_tpl_list a:active .cke_tpl_item -{ - border: #ff9933 1px solid; - background-color: #fffacd; -} - -.cke_tpl_list a:hover *, -.cke_tpl_list a:focus *, -.cke_tpl_list a:active * -{ - cursor: pointer; -} - -/* IE6 contextual selectors childs won't get :hover transition until, - the hover style of the link itself contains certain CSS declarations.*/ -.cke_browser_ie6 .cke_tpl_list a:active, -.cke_browser_ie6 .cke_tpl_list a:hover, -.cke_browser_ie6 .cke_tpl_list a:focus -{ - background-position: 0 0; -} - -.cke_hc .cke_tpl_list a:hover .cke_tpl_item, -.cke_hc .cke_tpl_list a:focus .cke_tpl_item, -.cke_hc .cke_tpl_list a:active .cke_tpl_item -{ - border-width: 3px; -} - -.cke_tpl_empty, .cke_tpl_loading -{ - text-align: center; - padding: 5px; -} diff --git a/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.js b/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.js deleted file mode 100644 index b4de0b8237b..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/dialogs/templates.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - var doc = CKEDITOR.document; - - CKEDITOR.dialog.add( 'templates', function( editor ) { - // Constructs the HTML view of the specified templates data. - function renderTemplatesList( container, templatesDefinitions ) { - // clear loading wait text. - container.setHtml( '' ); - - for ( var i = 0, totalDefs = templatesDefinitions.length; i < totalDefs; i++ ) { - var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ), - imagesPath = definition.imagesPath, - templates = definition.templates, - count = templates.length; - - for ( var j = 0; j < count; j++ ) { - var template = templates[ j ], - item = createTemplateItem( template, imagesPath ); - item.setAttribute( 'aria-posinset', j + 1 ); - item.setAttribute( 'aria-setsize', count ); - container.append( item ); - } - } - } - - function createTemplateItem( template, imagesPath ) { - var item = CKEDITOR.dom.element.createFromHtml( '<a href="javascript:void(0)" tabIndex="-1" role="option" >' + - '<div class="cke_tpl_item"></div>' + - '</a>' ); - - // Build the inner HTML of our new item DIV. - var html = '<table style="width:350px;" class="cke_tpl_preview" role="presentation"><tr>'; - - if ( template.image && imagesPath ) - html += '<td class="cke_tpl_preview_img"><img src="' + CKEDITOR.getUrl( imagesPath + template.image ) + '"' + ( CKEDITOR.env.ie6Compat ? ' onload="this.width=this.width"' : '' ) + ' alt="" title=""></td>'; - - html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>'; - - if ( template.description ) - html += '<span>' + template.description + '</span>'; - - html += '</td></tr></table>'; - - item.getFirst().setHtml( html ); - - item.on( 'click', function() { - insertTemplate( template.html ); - }); - - return item; - } - - // Insert the specified template content into editor. - // @param {Number} index - function insertTemplate( html ) { - var dialog = CKEDITOR.dialog.getCurrent(), - isReplace = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' ); - - if ( isReplace ) { - editor.fire( 'saveSnapshot' ); - // Everything should happen after the document is loaded (#4073). - editor.setData( html, function() { - dialog.hide(); - - // Place the cursor at the first editable place. - var range = editor.createRange(); - range.moveToElementEditStart( editor.editable() ); - range.select(); - setTimeout( function() { - editor.fire( 'saveSnapshot' ); - }, 0 ); - - } ); - } else { - editor.insertHtml( html ); - dialog.hide(); - } - } - - function keyNavigation( evt ) { - var target = evt.data.getTarget(), - onList = listContainer.equals( target ); - - // Keyboard navigation for template list. - if ( onList || listContainer.contains( target ) ) { - var keystroke = evt.data.getKeystroke(), - items = listContainer.getElementsByTag( 'a' ), - focusItem; - - if ( items ) { - // Focus not yet onto list items? - if ( onList ) - focusItem = items.getItem( 0 ); - else { - switch ( keystroke ) { - case 40: // ARROW-DOWN - focusItem = target.getNext(); - break; - - case 38: // ARROW-UP - focusItem = target.getPrevious(); - break; - - case 13: // ENTER - case 32: // SPACE - target.fire( 'click' ); - } - } - - if ( focusItem ) { - focusItem.focus(); - evt.data.preventDefault(); - } - } - } - } - - // Load skin at first. - var plugin = CKEDITOR.plugins.get( 'templates' ); - CKEDITOR.document.appendStyleSheet( CKEDITOR.getUrl( plugin.path + 'dialogs/templates.css' ) ); - - - var listContainer; - - var templateListLabelId = 'cke_tpl_list_label_' + CKEDITOR.tools.getNextNumber(), - lang = editor.lang.templates, - config = editor.config; - return { - title: editor.lang.templates.title, - - minWidth: CKEDITOR.env.ie ? 440 : 400, - minHeight: 340, - - contents: [ - { - id: 'selectTpl', - label: lang.title, - elements: [ - { - type: 'vbox', - padding: 5, - children: [ - { - id: 'selectTplText', - type: 'html', - html: '<span>' + - lang.selectPromptMsg + - '</span>' - }, - { - id: 'templatesList', - type: 'html', - focus: true, - html: '<div class="cke_tpl_list" tabIndex="-1" role="listbox" aria-labelledby="' + templateListLabelId + '">' + - '<div class="cke_tpl_loading"><span></span></div>' + - '</div>' + - '<span class="cke_voice_label" id="' + templateListLabelId + '">' + lang.options + '</span>' - }, - { - id: 'chkInsertOpt', - type: 'checkbox', - label: lang.insertOption, - 'default': config.templates_replaceContent - } - ] - } - ] - } - ], - - buttons: [ CKEDITOR.dialog.cancelButton ], - - onShow: function() { - var templatesListField = this.getContentElement( 'selectTpl', 'templatesList' ); - listContainer = templatesListField.getElement(); - - CKEDITOR.loadTemplates( config.templates_files, function() { - var templates = ( config.templates || 'default' ).split( ',' ); - - if ( templates.length ) { - renderTemplatesList( listContainer, templates ); - templatesListField.focus(); - } else { - listContainer.setHtml( '<div class="cke_tpl_empty">' + - '<span>' + lang.emptyListMsg + '</span>' + - '</div>' ); - } - }); - - this._.element.on( 'keydown', keyNavigation ); - }, - - onHide: function() { - this._.element.removeListener( 'keydown', keyNavigation ); - } - }; - }); -})(); diff --git a/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates-rtl.png b/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates-rtl.png Binary files differdeleted file mode 100644 index 9a263404144..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates.png b/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates.png Binary files differdeleted file mode 100644 index 9a263404144..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/icons/hidpi/templates.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/templates/icons/templates-rtl.png b/addons/website/static/lib/ckeditor/plugins/templates/icons/templates-rtl.png Binary files differdeleted file mode 100644 index 202b6045fc7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/icons/templates-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/templates/icons/templates.png b/addons/website/static/lib/ckeditor/plugins/templates/icons/templates.png Binary files differdeleted file mode 100644 index 202b6045fc7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/icons/templates.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/templates/lang/en.js b/addons/website/static/lib/ckeditor/plugins/templates/lang/en.js deleted file mode 100644 index 612707456e3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/lang/en.js +++ /dev/null @@ -1,12 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'templates', 'en', { - button: 'Templates', - emptyListMsg: '(No templates defined)', - insertOption: 'Replace actual contents', - options: 'Template Options', - selectPromptMsg: 'Please select the template to open in the editor', - title: 'Content Templates' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/templates/plugin.js b/addons/website/static/lib/ckeditor/plugins/templates/plugin.js deleted file mode 100644 index b46128425dc..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/plugin.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - CKEDITOR.plugins.add( 'templates', { - requires: 'dialog', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'templates,templates-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - CKEDITOR.dialog.add( 'templates', CKEDITOR.getUrl( this.path + 'dialogs/templates.js' ) ); - - editor.addCommand( 'templates', new CKEDITOR.dialogCommand( 'templates' ) ); - - editor.ui.addButton && editor.ui.addButton( 'Templates', { - label: editor.lang.templates.button, - command: 'templates', - toolbar: 'doctools,10' - }); - } - }); - - var templates = {}, - loadedTemplatesFiles = {}; - - CKEDITOR.addTemplates = function( name, definition ) { - templates[ name ] = definition; - }; - - CKEDITOR.getTemplates = function( name ) { - return templates[ name ]; - }; - - CKEDITOR.loadTemplates = function( templateFiles, callback ) { - // Holds the templates files to be loaded. - var toLoad = []; - - // Look for pending template files to get loaded. - for ( var i = 0, count = templateFiles.length; i < count; i++ ) { - if ( !loadedTemplatesFiles[ templateFiles[ i ] ] ) { - toLoad.push( templateFiles[ i ] ); - loadedTemplatesFiles[ templateFiles[ i ] ] = 1; - } - } - - if ( toLoad.length ) - CKEDITOR.scriptLoader.load( toLoad, callback ); - else - setTimeout( callback, 0 ); - }; -})(); - - - -/** - * The templates definition set to use. It accepts a list of names separated by - * comma. It must match definitions loaded with the {@link #templates_files} setting. - * - * config.templates = 'my_templates'; - * - * @cfg {String} [templates='default'] - * @member CKEDITOR.config - */ - -/** - * The list of templates definition files to load. - * - * config.templates_files = [ - * '/editor_templates/site_default.js', - * 'http://www.example.com/user_templates.js - * ]; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.templates_files = [ - CKEDITOR.getUrl( 'plugins/templates/templates/default.js' ) - ]; - -/** - * Whether the "Replace actual contents" checkbox is checked by default in the - * Templates dialog. - * - * config.templates_replaceContent = false; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.templates_replaceContent = true; diff --git a/addons/website/static/lib/ckeditor/plugins/templates/templates/default.js b/addons/website/static/lib/ckeditor/plugins/templates/templates/default.js deleted file mode 100644 index 4d2c2af4b1d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/templates/templates/default.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -// Register a templates definition set named "default". -CKEDITOR.addTemplates( 'default', { - // The name of sub folder which hold the shortcut preview images of the - // templates. - imagesPath: CKEDITOR.getUrl( CKEDITOR.plugins.getPath( 'templates' ) + 'templates/images/' ), - - // The templates definitions. - templates: [ - { - title: 'Image and Title', - image: 'template1.gif', - description: 'One main image with a title and text that surround the image.', - html: '<h3>' + - '<img style="margin-right: 10px" height="100" width="100" align="left"/>' + - 'Type the title here' + - '</h3>' + - '<p>' + - 'Type the text here' + - '</p>' - }, - { - title: 'Strange Template', - image: 'template2.gif', - description: 'A template that defines two colums, each one with a title, and some text.', - html: '<table cellspacing="0" cellpadding="0" style="width:100%" border="0">' + - '<tr>' + - '<td style="width:50%">' + - '<h3>Title 1</h3>' + - '</td>' + - '<td></td>' + - '<td style="width:50%">' + - '<h3>Title 2</h3>' + - '</td>' + - '</tr>' + - '<tr>' + - '<td>' + - 'Text 1' + - '</td>' + - '<td></td>' + - '<td>' + - 'Text 2' + - '</td>' + - '</tr>' + - '</table>' + - '<p>' + - 'More text goes here.' + - '</p>' - }, - { - title: 'Text and Table', - image: 'template3.gif', - description: 'A title with some text and a table.', - html: '<div style="width: 80%">' + - '<h3>' + - 'Title goes here' + - '</h3>' + - '<table style="width:150px;float: right" cellspacing="0" cellpadding="0" border="1">' + - '<caption style="border:solid 1px black">' + - '<strong>Table title</strong>' + - '</caption>' + - '<tr>' + - '<td> </td>' + - '<td> </td>' + - '<td> </td>' + - '</tr>' + - '<tr>' + - '<td> </td>' + - '<td> </td>' + - '<td> </td>' + - '</tr>' + - '<tr>' + - '<td> </td>' + - '<td> </td>' + - '<td> </td>' + - '</tr>' + - '</table>' + - '<p>' + - 'Type the text here' + - '</p>' + - '</div>' - } - ] -}); diff --git a/addons/website/static/lib/ckeditor/plugins/toolbar/lang/en.js b/addons/website/static/lib/ckeditor/plugins/toolbar/lang/en.js deleted file mode 100644 index cb441b18cd0..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/toolbar/lang/en.js +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'toolbar', 'en', { - toolbarCollapse: 'Collapse Toolbar', - toolbarExpand: 'Expand Toolbar', - toolbarGroups: { - document: 'Document', - clipboard: 'Clipboard/Undo', - editing: 'Editing', - forms: 'Forms', - basicstyles: 'Basic Styles', - paragraph: 'Paragraph', - links: 'Links', - insert: 'Insert', - styles: 'Styles', - colors: 'Colors', - tools: 'Tools' - }, - toolbars: 'Editor toolbars' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/toolbar/plugin.js b/addons/website/static/lib/ckeditor/plugins/toolbar/plugin.js deleted file mode 100644 index 2ddcf63c3a5..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/toolbar/plugin.js +++ /dev/null @@ -1,770 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "toolbar" plugin. Renders the default toolbar interface in - * the editor. - */ - -(function() { - var toolbox = function() { - this.toolbars = []; - this.focusCommandExecuted = false; - }; - - toolbox.prototype.focus = function() { - for ( var t = 0, toolbar; toolbar = this.toolbars[ t++ ]; ) { - for ( var i = 0, item; item = toolbar.items[ i++ ]; ) { - if ( item.focus ) { - item.focus(); - return; - } - } - } - }; - - var commands = { - toolbarFocus: { - modes: { wysiwyg:1,source:1 }, - readOnly: 1, - - exec: function( editor ) { - if ( editor.toolbox ) { - editor.toolbox.focusCommandExecuted = true; - - // Make the first button focus accessible for IE. (#3417) - // Adobe AIR instead need while of delay. - if ( CKEDITOR.env.ie || CKEDITOR.env.air ) - setTimeout( function() { - editor.toolbox.focus(); - }, 100 ); - else - editor.toolbox.focus(); - } - } - } - }; - - CKEDITOR.plugins.add( 'toolbar', { - requires: 'button', - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - - init: function( editor ) { - var endFlag; - - var itemKeystroke = function( item, keystroke ) { - var next, toolbar; - var rtl = editor.lang.dir == 'rtl', - toolbarGroupCycling = editor.config.toolbarGroupCycling; - - toolbarGroupCycling = toolbarGroupCycling === undefined || toolbarGroupCycling; - - switch ( keystroke ) { - case 9: // TAB - case CKEDITOR.SHIFT + 9: // SHIFT + TAB - // Cycle through the toolbars, starting from the one - // closest to the current item. - while ( !toolbar || !toolbar.items.length ) { - toolbar = keystroke == 9 ? ( ( toolbar ? toolbar.next : item.toolbar.next ) || editor.toolbox.toolbars[ 0 ] ) : ( ( toolbar ? toolbar.previous : item.toolbar.previous ) || editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ] ); - - // Look for the first item that accepts focus. - if ( toolbar.items.length ) { - item = toolbar.items[ endFlag ? ( toolbar.items.length - 1 ) : 0 ]; - while ( item && !item.focus ) { - item = endFlag ? item.previous : item.next; - - if ( !item ) - toolbar = 0; - } - } - } - - if ( item ) - item.focus(); - - return false; - - case rtl ? 37: - 39 : // RIGHT-ARROW - case 40: // DOWN-ARROW - next = item; - do { - // Look for the next item in the toolbar. - next = next.next; - - // If it's the last item, cycle to the first one. - if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ 0 ]; - } - while ( next && !next.focus ) - - // If available, just focus it, otherwise focus the - // first one. - if ( next ) - next.focus(); - else - // Send a TAB. - itemKeystroke( item, 9 ); - - return false; - - case rtl ? 39: - 37 : // LEFT-ARROW - case 38: // UP-ARROW - next = item; - do { - // Look for the previous item in the toolbar. - next = next.previous; - - // If it's the first item, cycle to the last one. - if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ item.toolbar.items.length - 1 ]; - } - while ( next && !next.focus ) - - // If available, just focus it, otherwise focus the - // last one. - if ( next ) - next.focus(); - else { - endFlag = 1; - // Send a SHIFT + TAB. - itemKeystroke( item, CKEDITOR.SHIFT + 9 ); - endFlag = 0; - } - - return false; - - case 27: // ESC - editor.focus(); - return false; - - case 13: // ENTER - case 32: // SPACE - item.execute(); - return false; - } - return true; - }; - - editor.on( 'uiSpace', function( event ) { - if ( event.data.space != editor.config.toolbarLocation ) - return; - - // Create toolbar only once. - event.removeListener(); - - editor.toolbox = new toolbox(); - - var labelId = CKEDITOR.tools.getNextId(); - - var output = [ - '<span id="', labelId, '" class="cke_voice_label">', editor.lang.toolbar.toolbars, '</span>', - '<span id="' + editor.ui.spaceId( 'toolbox' ) + '" class="cke_toolbox" role="group" aria-labelledby="', labelId, '" onmousedown="return false;">' ]; - - var expanded = editor.config.toolbarStartupExpanded !== false, - groupStarted, pendingSeparator; - - // If the toolbar collapser will be available, we'll have - // an additional container for all toolbars. - if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE ) - output.push( '<span class="cke_toolbox_main"' + ( expanded ? '>' : ' style="display:none">' ) ); - - var toolbars = editor.toolbox.toolbars, - toolbar = getToolbarConfig( editor ); - - for ( var r = 0; r < toolbar.length; r++ ) { - var toolbarId, - toolbarObj = 0, - toolbarName, - row = toolbar[ r ], - items; - - // It's better to check if the row object is really - // available because it's a common mistake to leave - // an extra comma in the toolbar definition - // settings, which leads on the editor not loading - // at all in IE. (#3983) - if ( !row ) - continue; - - if ( groupStarted ) { - output.push( '</span>' ); - groupStarted = 0; - pendingSeparator = 0; - } - - if ( row === '/' ) { - output.push( '<span class="cke_toolbar_break"></span>' ); - continue; - } - - items = row.items || row; - - // Create all items defined for this toolbar. - for ( var i = 0; i < items.length; i++ ) { - var item = items[ i ], - canGroup; - - if ( item ) { - if ( item.type == CKEDITOR.UI_SEPARATOR ) { - // Do not add the separator immediately. Just save - // it be included if we already have something in - // the toolbar and if a new item is to be added (later). - pendingSeparator = groupStarted && item; - continue; - } - - canGroup = item.canGroup !== false; - - // Initialize the toolbar first, if needed. - if ( !toolbarObj ) { - // Create the basic toolbar object. - toolbarId = CKEDITOR.tools.getNextId(); - toolbarObj = { id: toolbarId, items: [] }; - toolbarName = row.name && ( editor.lang.toolbar.toolbarGroups[ row.name ] || row.name ); - - // Output the toolbar opener. - output.push( '<span id="', toolbarId, '" class="cke_toolbar"', ( toolbarName ? ' aria-labelledby="' + toolbarId + '_label"' : '' ), ' role="toolbar">' ); - - // If a toolbar name is available, send the voice label. - toolbarName && output.push( '<span id="', toolbarId, '_label" class="cke_voice_label">', toolbarName, '</span>' ); - - output.push( '<span class="cke_toolbar_start"></span>' ); - - // Add the toolbar to the "editor.toolbox.toolbars" - // array. - var index = toolbars.push( toolbarObj ) - 1; - - // Create the next/previous reference. - if ( index > 0 ) { - toolbarObj.previous = toolbars[ index - 1 ]; - toolbarObj.previous.next = toolbarObj; - } - } - - if ( canGroup ) { - if ( !groupStarted ) { - output.push( '<span class="cke_toolgroup" role="presentation">' ); - groupStarted = 1; - } - } else if ( groupStarted ) { - output.push( '</span>' ); - groupStarted = 0; - } - - function addItem( item ) { - var itemObj = item.render( editor, output ); - index = toolbarObj.items.push( itemObj ) - 1; - - if ( index > 0 ) { - itemObj.previous = toolbarObj.items[ index - 1 ]; - itemObj.previous.next = itemObj; - } - - itemObj.toolbar = toolbarObj; - itemObj.onkey = itemKeystroke; - - // Fix for #3052: - // Prevent JAWS from focusing the toolbar after document load. - itemObj.onfocus = function() { - if ( !editor.toolbox.focusCommandExecuted ) - editor.focus(); - }; - } - - if ( pendingSeparator ) { - addItem( pendingSeparator ); - pendingSeparator = 0; - } - - addItem( item ); - } - } - - if ( groupStarted ) { - output.push( '</span>' ); - groupStarted = 0; - pendingSeparator = 0; - } - - if ( toolbarObj ) - output.push( '<span class="cke_toolbar_end"></span></span>' ); - } - - if ( editor.config.toolbarCanCollapse ) - output.push( '</span>' ); - - // Not toolbar collapser for inline mode. - if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE ) { - var collapserFn = CKEDITOR.tools.addFunction( function() { - editor.execCommand( 'toolbarCollapse' ); - }); - - editor.on( 'destroy', function() { - CKEDITOR.tools.removeFunction( collapserFn ); - }); - - editor.addCommand( 'toolbarCollapse', { - readOnly: 1, - exec: function( editor ) { - var collapser = editor.ui.space( 'toolbar_collapser' ), - toolbox = collapser.getPrevious(), - contents = editor.ui.space( 'contents' ), - toolboxContainer = toolbox.getParent(), - contentHeight = parseInt( contents.$.style.height, 10 ), - previousHeight = toolboxContainer.$.offsetHeight, - minClass = 'cke_toolbox_collapser_min', - collapsed = collapser.hasClass( minClass ); - - if ( !collapsed ) { - toolbox.hide(); - collapser.addClass( minClass ); - collapser.setAttribute( 'title', editor.lang.toolbar.toolbarExpand ); - } else { - toolbox.show(); - collapser.removeClass( minClass ); - collapser.setAttribute( 'title', editor.lang.toolbar.toolbarCollapse ); - } - - // Update collapser symbol. - collapser.getFirst().setText( collapsed ? '\u25B2' : // BLACK UP-POINTING TRIANGLE - '\u25C0' ); // BLACK LEFT-POINTING TRIANGLE - - var dy = toolboxContainer.$.offsetHeight - previousHeight; - contents.setStyle( 'height', ( contentHeight - dy ) + 'px' ); - - editor.fire( 'resize' ); - }, - - modes: { wysiwyg:1,source:1 } - }); - - editor.setKeystroke( CKEDITOR.ALT + ( CKEDITOR.env.ie || CKEDITOR.env.webkit ? 189 : 109 ) /*-*/, 'toolbarCollapse' ); - - output.push( '<a title="' + ( expanded ? editor.lang.toolbar.toolbarCollapse : editor.lang.toolbar.toolbarExpand ) - + '" id="' + editor.ui.spaceId( 'toolbar_collapser' ) - + '" tabIndex="-1" class="cke_toolbox_collapser' ); - - if ( !expanded ) - output.push( ' cke_toolbox_collapser_min' ); - - output.push( '" onclick="CKEDITOR.tools.callFunction(' + collapserFn + ')">', '<span class="cke_arrow">▲</span>', // BLACK UP-POINTING TRIANGLE - '</a>' ); - } - - output.push( '</span>' ); - event.data.html += output.join( '' ); - }); - - editor.on( 'destroy', function() { - - if ( this.toolbox ) - { - var toolbars, - index = 0, - i, items, instance; - toolbars = this.toolbox.toolbars; - for ( ; index < toolbars.length; index++ ) { - items = toolbars[ index ].items; - for ( i = 0; i < items.length; i++ ) { - instance = items[ i ]; - if ( instance.clickFn ) - CKEDITOR.tools.removeFunction( instance.clickFn ); - if ( instance.keyDownFn ) - CKEDITOR.tools.removeFunction( instance.keyDownFn ); - } - } - } - }); - - // Manage editor focus when navigating the toolbar. - editor.on( 'uiReady', function() { - var toolbox = editor.ui.space( 'toolbox' ); - toolbox && editor.focusManager.add( toolbox, 1 ); - }); - - editor.addCommand( 'toolbarFocus', commands.toolbarFocus ); - editor.setKeystroke( CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ); - - editor.ui.add( '-', CKEDITOR.UI_SEPARATOR, {} ); - editor.ui.addHandler( CKEDITOR.UI_SEPARATOR, { - create: function() { - return { - render: function( editor, output ) { - output.push( '<span class="cke_toolbar_separator" role="separator"></span>' ); - return {}; - } - }; - } - }); - } - }); - - function getToolbarConfig( editor ) { - var removeButtons = editor.config.removeButtons; - - removeButtons = removeButtons && removeButtons.split( ',' ); - - function buildToolbarConfig() { - - // Object containing all toolbar groups used by ui items. - var lookup = getItemDefinedGroups(); - - // Take the base for the new toolbar, which is basically a toolbar - // definition without items. - var toolbar = CKEDITOR.tools.clone( editor.config.toolbarGroups ) || getPrivateToolbarGroups( editor ); - - // Fill the toolbar groups with the available ui items. - for ( var i = 0; i < toolbar.length; i++ ) { - var toolbarGroup = toolbar[ i ]; - - // Skip toolbar break. - if ( toolbarGroup == '/' ) - continue; - // Handle simply group name item. - else if ( typeof toolbarGroup == 'string' ) - toolbarGroup = toolbar[ i ] = { name: toolbarGroup }; - - var items, subGroups = toolbarGroup.groups; - - // Look for items that match sub groups. - if ( subGroups ) { - for ( var j = 0, sub; j < subGroups.length; j++ ) { - sub = subGroups[ j ]; - - // If any ui item is registered for this subgroup. - items = lookup[ sub ]; - items && fillGroup( toolbarGroup, items ); - } - } - - // Add the main group items as well. - items = lookup[ toolbarGroup.name ]; - items && fillGroup( toolbarGroup, items ); - } - - return toolbar; - } - - // Returns an object containing all toolbar groups used by ui items. - function getItemDefinedGroups() { - var groups = {}, - itemName, item, itemToolbar, group, order; - - for ( itemName in editor.ui.items ) { - item = editor.ui.items[ itemName ]; - itemToolbar = item.toolbar || 'others'; - if ( itemToolbar ) { - // Break the toolbar property into its parts: "group_name[,order]". - itemToolbar = itemToolbar.split( ',' ); - group = itemToolbar[ 0 ]; - order = parseInt( itemToolbar[ 1 ] || -1, 10 ); - - // Initialize the group, if necessary. - groups[ group ] || ( groups[ group ] = [] ); - - // Push the data used to build the toolbar later. - groups[ group ].push( { name: itemName, order: order} ); - } - } - - // Put the items in the right order. - for ( group in groups ) { - groups[ group ] = groups[ group ].sort( function( a, b ) { - return a.order == b.order ? 0 : - b.order < 0 ? -1 : - a.order < 0 ? 1 : - a.order < b.order ? -1 : - 1; - }); - } - - return groups; - } - - function fillGroup( toolbarGroup, uiItems ) { - if ( uiItems.length ) { - if ( toolbarGroup.items ) - toolbarGroup.items.push( editor.ui.create( '-' ) ); - else - toolbarGroup.items = []; - - var item, name; - while ( ( item = uiItems.shift() ) ) { - name = typeof item == 'string' ? item : item.name; - - // Ignore items that are configured to be removed. - if ( !removeButtons || CKEDITOR.tools.indexOf( removeButtons, name ) == -1 ) { - item = editor.ui.create( name ); - - if ( !item ) - continue; - - if ( !editor.addFeature( item ) ) - continue; - - toolbarGroup.items.push( item ); - } - } - } - } - - function populateToolbarConfig( config ) { - var toolbar = [], - i, group, newGroup; - - for ( i = 0; i < config.length; ++i ) { - group = config[ i ]; - newGroup = {}; - - if ( group == '/' ) - toolbar.push( group ); - else if ( CKEDITOR.tools.isArray( group) ) { - fillGroup( newGroup, CKEDITOR.tools.clone( group ) ); - toolbar.push( newGroup ); - } - else if ( group.items ) { - fillGroup( newGroup, CKEDITOR.tools.clone( group.items ) ); - newGroup.name = group.name; - toolbar.push( newGroup); - } - } - - return toolbar; - } - - var toolbar = editor.config.toolbar; - - // If it is a string, return the relative "toolbar_name" config. - if ( typeof toolbar == 'string' ) - toolbar = editor.config[ 'toolbar_' + toolbar ]; - - return ( editor.toolbar = toolbar ? populateToolbarConfig( toolbar ) : buildToolbarConfig() ); - } - - /** - * Add toolbar group. See {@link CKEDITOR.config#toolbarGroups} for more details. - * - * **Note:** This method won't modify toolbar groups set explicitly by - * {@link CKEDITOR.config#toolbarGroups}. It will extend only default setting. - * - * @param {String} name Group name. - * @param {Number/String} previous Name of group after which this one - * should be added or `0` if this group should be the first one. - * @param {String} [subgroupOf] Name of parent group. - * @member CKEDITOR.ui - */ - CKEDITOR.ui.prototype.addToolbarGroup = function( name, previous, subgroupOf ) { - // The toolbarGroups from the privates is the one we gonna use for automatic toolbar creation. - var toolbarGroups = getPrivateToolbarGroups( this.editor ), - atStart = previous === 0, - newGroup = { name: name }; - - if ( subgroupOf ) { - // Transform the subgroupOf name in the real subgroup object. - subgroupOf = CKEDITOR.tools.search( toolbarGroups, function( group ) { - return group.name == subgroupOf; - }); - - if ( subgroupOf ) { - !subgroupOf.groups && ( subgroupOf.groups = [] ) ; - - if ( previous ) { - // Search the "previous" item and add the new one after it. - previous = CKEDITOR.tools.indexOf( subgroupOf.groups, previous ); - if ( previous >= 0 ) { - subgroupOf.groups.splice( previous + 1, 0, name ); - return; - } - } - - // If no previous found. - - if ( atStart ) - subgroupOf.groups.splice( 0, 0, name ); - else - subgroupOf.groups.push( name ); - return; - } else { - // Ignore "previous" if subgroupOf has not been found. - previous = null; - } - } - - if ( previous ) { - // Transform the "previous" name into its index. - previous = CKEDITOR.tools.indexOf( toolbarGroups, function( group ) { - return group.name == previous; - }); - } - - if ( atStart ) - toolbarGroups.splice( 0, 0, name ); - else if ( typeof previous == 'number' ) - toolbarGroups.splice( previous + 1, 0, newGroup ); - else - toolbarGroups.push( name ); - }; - - function getPrivateToolbarGroups( editor ) { - return editor._.toolbarGroups || ( editor._.toolbarGroups = [ - { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, - { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, - { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, - { name: 'forms' }, - '/', - { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, - { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align' ] }, - { name: 'links' }, - { name: 'insert' }, - '/', - { name: 'styles' }, - { name: 'colors' }, - { name: 'tools' }, - { name: 'others' }, - { name: 'about' } - ]); - } -})(); - -/** - * Separator UI element. - * - * @readonly - * @property {String} [='separator'] - * @member CKEDITOR - */ -CKEDITOR.UI_SEPARATOR = 'separator'; - -/** - * The "UI space" to which rendering the toolbar. For the default editor implementation, - * the recommended options are `'top'` and `'bottom'`. - * - * config.toolbarLocation = 'bottom'; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.toolbarLocation = 'top'; - -/** - * The toolbox (alias toolbar) definition. It is a toolbar name or an array of - * toolbars (strips), each one being also an array, containing a list of UI items. - * - * If set to `null`, generate toolbar automatically using all available buttons - * and {@link #toolbarGroups} as a toolbar groups layout. - * - * // Defines a toolbar with only one strip containing the "Source" button, a - * // separator and the "Bold" and "Italic" buttons. - * config.toolbar = [ - * [ 'Source', '-', 'Bold', 'Italic' ] - * ]; - * - * // Similar to example the above, defines a "Basic" toolbar with only one strip containing three buttons. - * // Note that this setting is composed by "toolbar_" added by the toolbar name, which in this case is called "Basic". - * // This second part of the setting name can be anything. You must use this name in the CKEDITOR.config.toolbar setting, - * // so you instruct the editor which toolbar_(name) setting to use. - * config.toolbar_Basic = [ - * [ 'Source', '-', 'Bold', 'Italic' ] - * ]; - * // Load toolbar_Name where Name = Basic. - * config.toolbar = 'Basic'; - * - * @cfg {Array/String} [toolbar=null] - * @member CKEDITOR.config - */ - -/** - * The toolbar groups definition. - * - * If toolbar layout isn't explicitly defined by {@link #toolbar} setting, then - * this setting is used to group all defined buttons (see {@link CKEDITOR.ui#addButton}). - * Buttons are associated with toolbar groups by `toolbar` property in their definition objects. - * - * New groups may be dynamically added during the editor and plugins initialization by - * {@link CKEDITOR.ui#addToolbarGroup}. Although only if default setting was used. - * - * // Default setting. - * config.toolbarGroups = [ - * { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, - * { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, - * { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, - * { name: 'forms' }, - * '/', - * { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, - * { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align' ] }, - * { name: 'links' }, - * { name: 'insert' }, - * '/', - * { name: 'styles' }, - * { name: 'colors' }, - * { name: 'tools' }, - * { name: 'others' }, - * { name: 'about' } - * ]; - * - * @cfg {Array} [toolbarGroups=see example] - * @member CKEDITOR.config - */ - -/** - * Whether the toolbar can be collapsed by the user. If disabled, the collapser - * button will not be displayed. - * - * config.toolbarCanCollapse = true; - * - * @cfg {Boolean} [toolbarCanCollapse=false] - * @member CKEDITOR.config - */ - -/** - * Whether the toolbar must start expanded when the editor is loaded. - * - * Setting this option to `false` will affect toolbar only when - * {@link #toolbarCanCollapse} is set to `true`: - * - * config.toolbarCanCollapse = true; - * config.toolbarStartupExpanded = false; - * - * @cfg {Boolean} [toolbarStartupExpanded=true] - * @member CKEDITOR.config - */ - -/** - * When enabled, makes the arrow keys navigation cycle within the current - * toolbar group. Otherwise the arrows will move through all items available in - * the toolbar. The *TAB* key will still be used to quickly jump among the - * toolbar groups. - * - * config.toolbarGroupCycling = false; - * - * @since 3.6 - * @cfg {Boolean} [toolbarGroupCycling=true] - * @member CKEDITOR.config - */ - -/** - * List of toolbar button names that must not be rendered. This will work as - * well for non-button toolbar items, like the Font combos. - * - * config.removeButtons = 'Underline,JustifyCenter'; - * - * This configuration should not be overused, having - * {@link CKEDITOR.config#removePlugins} removing features from the editor. In - * some cases though, a single plugin may define a set of toolbar buttons and - * removeButtons may be useful when just a few of them are to be removed. - * - * @cfg {String} [removeButtons] - * @member CKEDITOR.config - */ - -/** - * Toolbar definition used by the editor. It is crated from the - * {@link CKEDITOR.config#toolbar} if it is set or automatically - * based on {@link CKEDITOR.config#toolbarGroups}. - * - * @readonly - * @property {Object} toolbar - * @member CKEDITOR.editor - */ diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/dialogs/uicolor.js b/addons/website/static/lib/ckeditor/plugins/uicolor/dialogs/uicolor.js deleted file mode 100644 index 64430c86062..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/dialogs/uicolor.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.dialog.add( 'uicolor', function( editor ) { - var dialog, picker, pickerContents, - // Actual UI color value. - uiColor = editor.getUiColor(), - pickerId = 'cke_uicolor_picker' + CKEDITOR.tools.getNextNumber(); - - function setNewPickerColor( color ) { - // Convert HEX representation to RGB, stripping # char. - if ( /^#/.test( color ) ) - color = window.YAHOO.util.Color.hex2rgb( color.substr( 1 ) ); - picker.setValue( color, true ); - // Refresh picker UI. - picker.refresh( pickerId ); - } - - function setNewUiColor( color ) { - editor.setUiColor( color ); - // Write new config string into textbox. - dialog._.contents.tab1.configBox.setValue( 'config.uiColor = "#' + picker.get( "hex" ) + '"' ); - } - - pickerContents = { - id: 'yuiColorPicker', - type: 'html', - html: "<div id='" + pickerId + "' class='cke_uicolor_picker' style='width: 360px; height: 200px; position: relative;'></div>", - onLoad: function( event ) { - var url = CKEDITOR.getUrl( 'plugins/uicolor/yui/' ); - - // Create new color picker widget. - picker = new window.YAHOO.widget.ColorPicker( pickerId, { - showhsvcontrols: true, - showhexcontrols: true, - images: { - PICKER_THUMB: url + "assets/picker_thumb.png", - HUE_THUMB: url + "assets/hue_thumb.png" - } - }); - - // Make Yahoo widget available to public. - this.picker = picker; - - // Set actual UI color to the picker. - if ( uiColor ) - setNewPickerColor( uiColor ); - - // Subscribe to the rgbChange event. - picker.on( "rgbChange", function() { - // Reset predefined box. - dialog._.contents.tab1.predefined.setValue( '' ); - setNewUiColor( '#' + picker.get( 'hex' ) ); - }); - - // Fix input class names. - var inputs = new CKEDITOR.dom.nodeList( picker.getElementsByTagName( 'input' ) ); - for ( var i = 0; i < inputs.count(); i++ ) - inputs.getItem( i ).addClass( 'cke_dialog_ui_input_text' ); - } - }; - - return { - title: editor.lang.uicolor.title, - minWidth: 360, - minHeight: 320, - onLoad: function() { - dialog = this; - this.setupContent(); - - // #3808 - if ( CKEDITOR.env.ie7Compat ) - dialog.parts.contents.setStyle( 'overflow', 'hidden' ); - }, - contents: [ - { - id: 'tab1', - label: '', - title: '', - expand: true, - padding: 0, - elements: [ - pickerContents, - { - id: 'tab1', - type: 'vbox', - children: [ - { - type: 'hbox', - children: [ - { - id: 'predefined', - type: 'select', - 'default': '', - label: editor.lang.uicolor.predefined, - items: [ - [ '' ], - [ 'Light blue', '#9AB8F3' ], - [ 'Sand', '#D2B48C' ], - [ 'Metallic', '#949AAA' ], - [ 'Purple', '#C2A3C7' ], - [ 'Olive', '#A2C980' ], - [ 'Happy green', '#9BD446' ], - [ 'Jezebel Blue', '#14B8C4' ], - [ 'Burn', '#FF893A' ], - [ 'Easy red', '#FF6969' ], - [ 'Pisces 3', '#48B4F2' ], - [ 'Aquarius 5', '#487ED4' ], - [ 'Absinthe', '#A8CF76' ], - [ 'Scrambled Egg', '#C7A622' ], - [ 'Hello monday', '#8E8D80' ], - [ 'Lovely sunshine', '#F1E8B1' ], - [ 'Recycled air', '#B3C593' ], - [ 'Down', '#BCBCA4' ], - [ 'Mark Twain', '#CFE91D' ], - [ 'Specks of dust', '#D1B596' ], - [ 'Lollipop', '#F6CE23' ] - ], - onChange: function() { - var color = this.getValue(); - if ( color ) { - setNewPickerColor( color ); - setNewUiColor( color ); - // Refresh predefined preview box. - CKEDITOR.document.getById( 'predefinedPreview' ).setStyle( 'background', color ); - } else - CKEDITOR.document.getById( 'predefinedPreview' ).setStyle( 'background', '' ); - }, - onShow: function() { - var color = editor.getUiColor(); - if ( color ) - this.setValue( color ); - } - }, - { - id: 'predefinedPreview', - type: 'html', - html: '<div id="cke_uicolor_preview" style="border: 1px solid black; padding: 3px; width: 30px;">' + - '<div id="predefinedPreview" style="width: 30px; height: 30px;"> </div>' + - '</div>' - } - ] - }, - { - id: 'configBox', - type: 'text', - label: editor.lang.uicolor.config, - onShow: function() { - var color = editor.getUiColor(); - if ( color ) - this.setValue( 'config.uiColor = "' + color + '"' ); - } - } - ] - } - ] - } - ], - buttons: [ CKEDITOR.dialog.okButton ] - }; -}); diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/icons/hidpi/uicolor.png b/addons/website/static/lib/ckeditor/plugins/uicolor/icons/hidpi/uicolor.png Binary files differdeleted file mode 100644 index e6efa4a30fe..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/icons/hidpi/uicolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/icons/uicolor.png b/addons/website/static/lib/ckeditor/plugins/uicolor/icons/uicolor.png Binary files differdeleted file mode 100644 index d5739dffeaf..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/icons/uicolor.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/lang/en.js b/addons/website/static/lib/ckeditor/plugins/uicolor/lang/en.js deleted file mode 100644 index edbbc5ae54e..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/lang/en.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.setLang( 'uicolor', 'en', { - title: 'UI Color Picker', - preview: 'Live preview', - config: 'Paste this string into your config.js file', - predefined: 'Predefined color sets' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/plugin.js b/addons/website/static/lib/ckeditor/plugins/uicolor/plugin.js deleted file mode 100644 index 60ffc9edd85..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/plugin.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -CKEDITOR.plugins.add( 'uicolor', { - requires: 'dialog', - lang: 'bg,cs,cy,da,de,el,en,eo,et,fa,fi,fr,he,hr,it,ku,mk,nb,nl,no,pl,tr,ug,uk,vi,zh-cn', // %REMOVE_LINE_CORE% - icons: 'uicolor', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - if ( CKEDITOR.env.ie6Compat ) - return; - - editor.addCommand( 'uicolor', new CKEDITOR.dialogCommand( 'uicolor' ) ); - editor.ui.addButton && editor.ui.addButton( 'UIColor', { - label: editor.lang.uicolor.title, - command: 'uicolor', - toolbar: 'tools,1' - }); - CKEDITOR.dialog.add( 'uicolor', this.path + 'dialogs/uicolor.js' ); - - // Load YUI js files. - CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( 'plugins/uicolor/yui/yui.js' ) ); - - // Load YUI css files. - CKEDITOR.document.appendStyleSheet( CKEDITOR.getUrl( 'plugins/uicolor/yui/assets/yui.css' ) ); - } -}); diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_bg.png b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_bg.png Binary files differdeleted file mode 100644 index d9bcdeb5c49..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_bg.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_thumb.png b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_thumb.png Binary files differdeleted file mode 100644 index 14d5db48624..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/hue_thumb.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_mask.png b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_mask.png Binary files differdeleted file mode 100644 index f8d91932b37..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_mask.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_thumb.png b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_thumb.png Binary files differdeleted file mode 100644 index 78445a2fe06..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/picker_thumb.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/yui.css b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/yui.css deleted file mode 100644 index 1bb7c759b60..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/assets/yui.css +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -.yui-h-slider,.yui-v-slider{position:relative;}.yui-h-slider .yui-slider-thumb,.yui-v-slider .yui-slider-thumb{position:absolute;cursor:default;}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px;}.yui-skin-sam .yui-h-slider .yui-slider-thumb{top:4px;}.yui-skin-sam .yui-v-slider{background:url(bg-v.gif) no-repeat 12px 0;height:228px;width:48px;} - -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -.cke_uicolor_picker .yui-picker-panel{background:#e3e3e3;border-color:#888;}.cke_uicolor_picker .yui-picker-panel .hd{background-color:#ccc;font-size:100%;line-height:100%;border:1px solid #e3e3e3;font-weight:bold;overflow:hidden;padding:6px;color:#000;}.cke_uicolor_picker .yui-picker-panel .bd{background:#e8e8e8;margin:1px;height:200px;}.cke_uicolor_picker .yui-picker-panel .ft{background:#e8e8e8;margin:1px;padding:1px;}.cke_uicolor_picker .yui-picker{position:relative;}.cke_uicolor_picker .yui-picker-hue-thumb{cursor:default;width:18px;height:18px;top:-8px;left:-2px;z-index:9;position:absolute;}.cke_uicolor_picker .yui-picker-hue-bg{-moz-outline:none;outline:0 none;position:absolute;left:200px;height:183px;width:14px;background:url(hue_bg.png) no-repeat;top:4px;}.cke_uicolor_picker .yui-picker-bg{-moz-outline:none;outline:0 none;position:absolute;top:4px;left:4px;height:182px;width:182px;background-color:#F00;background-image:url(picker_mask.png);}*html .cke_uicolor_picker .yui-picker-bg{background-image:none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='picker_mask.png',sizingMethod='scale');}.cke_uicolor_picker .yui-picker-mask{position:absolute;z-index:1;top:0;left:0;}.cke_uicolor_picker .yui-picker-thumb{cursor:default;width:11px;height:11px;z-index:9;position:absolute;top:-4px;left:-4px;}.cke_uicolor_picker .yui-picker-swatch{position:absolute;left:240px;top:4px;height:60px;width:55px;border:1px solid #888;}.cke_uicolor_picker .yui-picker-websafe-swatch{position:absolute;left:304px;top:4px;height:24px;width:24px;border:1px solid #888;}.cke_uicolor_picker .yui-picker-controls{position:absolute;top:72px;left:226px;font:1em monospace;}.cke_uicolor_picker .yui-picker-controls .hd{background:transparent;border-width:0!important;}.cke_uicolor_picker .yui-picker-controls .bd{height:100px;border-width:0!important;}.cke_uicolor_picker .yui-picker-controls ul{float:left;padding:0 2px 0 0;margin:0;}.cke_uicolor_picker .yui-picker-controls li{padding:2px;list-style:none;margin:0;}.cke_uicolor_picker .yui-picker-controls input{font-size:.85em;width:2.4em;}.cke_uicolor_picker .yui-picker-hex-controls{clear:both;padding:2px;}.cke_uicolor_picker .yui-picker-hex-controls input{width:4.6em;}.cke_uicolor_picker .yui-picker-controls a{font:1em arial,helvetica,clean,sans-serif;display:block;*display:inline-block;padding:0;color:#000;} diff --git a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/yui.js b/addons/website/static/lib/ckeditor/plugins/uicolor/yui/yui.js deleted file mode 100644 index 7af40801022..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/uicolor/yui/yui.js +++ /dev/null @@ -1,5914 +0,0 @@ -/*jsl:ignoreall*/ -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -if ( typeof YAHOO == "undefined" || !YAHOO ) { - var YAHOO = {}; -} -YAHOO.namespace = function() { - var A = arguments, - E = null, - C, B, D; - for ( C = 0; C < A.length; C = C + 1 ) { - D = ( "" + A[ C ] ).split( "." ); - E = YAHOO; - for ( B = ( D[ 0 ] == "YAHOO" ) ? 1 : 0; B < D.length; B = B + 1 ) { - E[ D[ B ] ] = E[ D[ B ] ] || {}; - E = E[ D[ B ] ]; - } - } - return E; -}; -YAHOO.log = function( D, A, C ) { - var B = YAHOO.widget.Logger; - if ( B && B.log ) { - return B.log( D, A, C ); - } else { - return false; - } -}; -YAHOO.register = function( A, E, D ) { - var I = YAHOO.env.modules, - B, H, G, F, C; - if ( !I[ A ] ) { - I[ A ] = { versions: [], builds: [] }; - } - B = I[ A ]; - H = D.version; - G = D.build; - F = YAHOO.env.listeners; - B.name = A; - B.version = H; - B.build = G; - B.versions.push( H ); - B.builds.push( G ); - B.mainClass = E; - for ( C = 0; C < F.length; C = C + 1 ) { - F[ C ]( B ); - } - if ( E ) { - E.VERSION = H; - E.BUILD = G; - } else { - YAHOO.log( "mainClass is undefined for module " + A, "warn" ); - } -}; -YAHOO.env = YAHOO.env || { modules: [], listeners: [] }; YAHOO.env.getVersion = function( A ) { - return YAHOO.env.modules[ A ] || null; -}; -YAHOO.env.ua = function() { - var C = { ie: 0, opera: 0, gecko: 0, webkit: 0, mobile: null, air: 0, caja: 0 }, - B = navigator.userAgent, - A; if ( ( /KHTML/ ).test( B ) ) { - C.webkit = 1; - } - A = B.match( /AppleWebKit\/([^\s]*)/ ); - if ( A && A[ 1 ] ) { - C.webkit = parseFloat( A[ 1 ] ); - if ( / Mobile\//.test( B ) ) { - C.mobile = "Apple"; - } else { - A = B.match( /NokiaN[^\/]*/ ); - if ( A ) { - C.mobile = A[ 0 ]; - } - } - A = B.match( /AdobeAIR\/([^\s]*)/ ); - if ( A ) { - C.air = A[ 0 ]; - } - } - if ( !C.webkit ) { - A = B.match( /Opera[\s\/]([^\s]*)/ ); - if ( A && A[ 1 ] ) { - C.opera = parseFloat( A[ 1 ] ); - A = B.match( /Opera Mini[^;]*/ ); - if ( A ) { - C.mobile = A[ 0 ]; - } - } else { - A = B.match( /MSIE\s([^;]*)/ ); - if ( A && A[ 1 ] ) { - C.ie = parseFloat( A[ 1 ] ); - } else { - A = B.match( /Gecko\/([^\s]*)/ ); - if ( A ) { - C.gecko = 1; - A = B.match( /rv:([^\s\)]*)/ ); - if ( A && A[ 1 ] ) { - C.gecko = parseFloat( A[ 1 ] ); - } - } - } - } - } - A = B.match( /Caja\/([^\s]*)/ ); - if ( A && A[ 1 ] ) { - C.caja = parseFloat( A[ 1 ] ); - } - return C; -}(); -(function() { - YAHOO.namespace( "util", "widget", "example" ); - if ( "undefined" !== typeof YAHOO_config ) { - var B = YAHOO_config.listener, - A = YAHOO.env.listeners, - D = true, - C; - if ( B ) { - for ( C = 0; C < A.length; C = C + 1 ) { - if ( A[ C ] == B ) { - D = false; - break; - } - } - if ( D ) { - A.push( B ); - } - } - } -})(); -YAHOO.lang = YAHOO.lang || {}; -(function() { - var B = YAHOO.lang, - F = "[object Array]", - C = "[object Function]", - A = Object.prototype, - E = [ "toString", "valueOf" ], - D = { - isArray: function( G ) { - return A.toString.apply( G ) === F; - }, - isBoolean: function( G ) { - return typeof G === "boolean"; - }, - isFunction: function( G ) { - return A.toString.apply( G ) === C; - }, - isNull: function( G ) { - return G === null; - }, - isNumber: function( G ) { - return typeof G === "number" && isFinite( G ); - }, - isObject: function( G ) { - return ( G && ( typeof G === "object" || B.isFunction( G ) ) ) || false; - }, - isString: function( G ) { - return typeof G === "string"; - }, - isUndefined: function( G ) { - return typeof G === "undefined"; - }, - _IEEnumFix: ( YAHOO.env.ua.ie ) ? - function( I, H ) { - var G, K, J; for ( G = 0; G < E.length; G = G + 1 ) { - K = E[ G ]; - J = H[ K ]; - if ( B.isFunction( J ) && J != A[ K ] ) { - I[ K ] = J; - } - } - } : function() {}, - extend: function( J, K, I ) { - if ( !K || !J ) { - throw new Error( "extend failed, please check that " + "all dependencies are included." ); - } - var H = function() {}, - G; - H.prototype = K.prototype; - J.prototype = new H(); - J.prototype.constructor = J; - J.superclass = K.prototype; - if ( K.prototype.constructor == A.constructor ) { - K.prototype.constructor = K; - } - if ( I ) { - for ( G in I ) { - if ( B.hasOwnProperty( I, G ) ) { - J.prototype[ G ] = I[ G ]; - } - } - B._IEEnumFix( J.prototype, I ); - } - }, - augmentObject: function( K, J ) { - if ( !J || !K ) { - throw new Error( "Absorb failed, verify dependencies." ); - } - var G = arguments, - I, L, - H = G[ 2 ]; - if ( H && H !== true ) { - for ( I = 2; I < G.length; I = I + 1 ) { - K[ G[ I ] ] = J[ G[ I ] ]; - } - } else { - for ( L in J ) { - if ( H || !( L in K ) ) { - K[ L ] = J[ L ]; - } - } - B._IEEnumFix( K, J ); - } - }, - augmentProto: function( J, I ) { - if ( !I || !J ) { - throw new Error( "Augment failed, verify dependencies." ); - } - var G = [ J.prototype, I.prototype ], - H; - for ( H = 2; H < arguments.length; H = H + 1 ) { - G.push( arguments[ H ] ); - } - B.augmentObject.apply( this, G ); - }, - dump: function( G, L ) { - var I, K, - N = [], - O = "{...}", - H = "f(){...}", - M = ", ", - J = " => "; - if ( !B.isObject( G ) ) { - return G + ""; - } else { - if ( G instanceof Date || ( "nodeType" in G && "tagName" in G ) ) { - return G; - } else { - if ( B.isFunction( G ) ) { - return H; - } - } - } - L = ( B.isNumber( L ) ) ? L : 3; - if ( B.isArray( G ) ) { - N.push( "[" ); - for ( I = 0, K = G.length; I < K; I = I + 1 ) { - if ( B.isObject( G[ I ] ) ) { - N.push( ( L > 0 ) ? B.dump( G[ I ], L - 1 ) : O ); - } else { - N.push( G[ I ] ); - } - N.push( M ); - } - if ( N.length > 1 ) { - N.pop(); - } - N.push( "]" ); - } else { - N.push( "{" ); - for ( I in G ) { - if ( B.hasOwnProperty( G, I ) ) { - N.push( I + J ); - if ( B.isObject( G[ I ] ) ) { - N.push( ( L > 0 ) ? B.dump( G[ I ], L - 1 ) : O ); - } else { - N.push( G[ I ] ); - } - N.push( M ); - } - } - if ( N.length > 1 ) { - N.pop(); - } - N.push( "}" ); - } - return N.join( "" ); - }, - substitute: function( V, H, O ) { - var L, K, J, R, S, U, - Q = [], - I, - M = "dump", - P = " ", - G = "{", - T = "}", - N; - for ( ;; ) { - L = V.lastIndexOf( G ); - if ( L < 0 ) { - break; - } - K = V.indexOf( T, L ); - if ( L + 1 >= K ) { - break; - } - I = V.substring( L + 1, K ); - R = I; - U = null; - J = R.indexOf( P ); - if ( J > -1 ) { - U = R.substring( J + 1 ); - R = R.substring( 0, J ); - } - S = H[ R ]; - if ( O ) { - S = O( R, S, U ); - } - if ( B.isObject( S ) ) { - if ( B.isArray( S ) ) { - S = B.dump( S, parseInt( U, 10 ) ); - } else { - U = U || ""; - N = U.indexOf( M ); - if ( N > -1 ) { - U = U.substring( 4 ); - } - if ( S.toString === A.toString || N > -1 ) { - S = B.dump( S, parseInt( U, 10 ) ); - } else { - S = S.toString(); - } - } - } else { - if ( !B.isString( S ) && !B.isNumber( S ) ) { - S = "~-" + Q.length + "-~"; - Q[ Q.length ] = I; - } - } - V = V.substring( 0, L ) + S + V.substring( K + 1 ); - } - for ( L = Q.length - 1; L >= 0; L = L - 1 ) { - V = V.replace( new RegExp( "~-" + L + "-~" ), "{" + Q[ L ] + "}", "g" ); - } - return V; - }, - trim: function( G ) { - try { - return G.replace( /^\s+|\s+$/g, "" ); - } catch ( H ) { - return G; - } - }, - merge: function() { - var J = {}, - H = arguments, - G = H.length, - I; - for ( I = 0; I < G; I = I + 1 ) { - B.augmentObject( J, H[ I ], true ); - } - return J; - }, - later: function( N, H, O, J, K ) { - N = N || 0; H = H || {}; - var I = O, - M = J, - L, G; - if ( B.isString( O ) ) { - I = H[ O ]; - } - if ( !I ) { - throw new TypeError( "method undefined" ); - } - if ( !B.isArray( M ) ) { - M = [ J ]; - } - L = function() { - I.apply( H, M ); - }; - G = ( K ) ? setInterval( L, N ) : setTimeout( L, N ); - return { - interval: K, cancel: function() { - if ( this.interval ) { - clearInterval( G ); - } else { - clearTimeout( G ); - } - } }; - }, - isValue: function( G ) { - return ( B.isObject( G ) || B.isString( G ) || B.isNumber( G ) || B.isBoolean( G ) ); - } }; B.hasOwnProperty = ( A.hasOwnProperty ) ? - function( G, H ) { - return G && G.hasOwnProperty( H ); - } : function( G, H ) { - return !B.isUndefined( G[ H ] ) && G.constructor.prototype[ H ] !== G[ H ]; - }; - D.augmentObject( B, D, true ); - YAHOO.util.Lang = B; - B.augment = B.augmentProto; - YAHOO.augment = B.augmentProto; - YAHOO.extend = B.extend; -})(); -YAHOO.register( "yahoo", YAHOO, { version: "2.7.0", build: "1796" } ); -(function() { - YAHOO.env._id_counter = YAHOO.env._id_counter || 0; - var E = YAHOO.util, - L = YAHOO.lang, - m = YAHOO.env.ua, - A = YAHOO.lang.trim, - d = {}, - h = {}, - N = /^t(?:able|d|h)$/i, - X = /color$/i, - K = window.document, - W = K.documentElement, - e = "ownerDocument", - n = "defaultView", - v = "documentElement", - t = "compatMode", - b = "offsetLeft", - P = "offsetTop", - u = "offsetParent", - Z = "parentNode", - l = "nodeType", - C = "tagName", - O = "scrollLeft", - i = "scrollTop", - Q = "getBoundingClientRect", - w = "getComputedStyle", - a = "currentStyle", - M = "CSS1Compat", - c = "BackCompat", - g = "class", - F = "className", - J = "", - B = " ", - s = "(?:^|\\s)", - k = "(?= |$)", - U = "g", - p = "position", - f = "fixed", - V = "relative", - j = "left", - o = "top", - r = "medium", - q = "borderLeftWidth", - R = "borderTopWidth", - D = m.opera, - I = m.webkit, - H = m.gecko, - T = m.ie; - E.Dom = { - CUSTOM_ATTRIBUTES: ( !W.hasAttribute ) ? { "for": "htmlFor", "class": F } : { "htmlFor": "for", "className": g }, - get: function( y ) { - var AA, Y, z, x, G; if ( y ) { - if ( y[ l ] || y.item ) { - return y; - } - if ( typeof y === "string" ) { - AA = y; - y = K.getElementById( y ); - if ( y && y.id === AA ) { - return y; - } else { - if ( y && K.all ) { - y = null; - Y = K.all[ AA ]; - for ( x = 0, G = Y.length; x < G; ++x ) { - if ( Y[ x ].id === AA ) { - return Y[ x ]; - } - } - } - } - return y; - } - if ( y.DOM_EVENTS ) { - y = y.get( "element" ); - } - if ( "length" in y ) { - z = []; - for ( x = 0, G = y.length; x < G; ++x ) { - z[ z.length ] = E.Dom.get( y[ x ] ); - } - return z; - } - return y; - } - return null; - }, - getComputedStyle: function( G, Y ) { - if ( window[ w ] ) { - return G[ e ][ n ][ w ]( G, null )[ Y ]; - } else { - if ( G[ a ] ) { - return E.Dom.IE_ComputedStyle.get( G, Y ); - } - } - }, - getStyle: function( G, Y ) { - return E.Dom.batch( G, E.Dom._getStyle, Y ); - }, - _getStyle: function() { - if ( window[ w ] ) { - return function( G, y ) { - y = ( y === "float" ) ? y = "cssFloat" : E.Dom._toCamel( y ); - var x = G.style[ y ], - Y; - if ( !x ) { - Y = G[ e ][ n ][ w ]( G, null ); - if ( Y ) { - x = Y[ y ]; - } - } - return x; - }; - } else { - if ( W[ a ] ) { - return function( G, y ) { - var x; - switch ( y ) { - case "opacity": - x = 100; - try { - x = G.filters[ "DXImageTransform.Microsoft.Alpha" ].opacity; - } catch ( z ) { - try { - x = G.filters( "alpha" ).opacity; - } catch ( Y ) {} - } - return x / 100;case "float": - y = "styleFloat";default: - y = E.Dom._toCamel( y ); - x = G[ a ] ? G[ a ][ y ] : null; - return ( G.style[ y ] || x ); - } - }; - } - } - }(), setStyle: function( G, Y, x ) { - E.Dom.batch( G, E.Dom._setStyle, { prop: Y, val: x } ); - }, - _setStyle: function() { - if ( T ) { - return function( Y, G ) { - var x = E.Dom._toCamel( G.prop ), - y = G.val; - if ( Y ) { - switch ( x ) { - case "opacity": - if ( L.isString( Y.style.filter ) ) { - Y.style.filter = "alpha(opacity=" + y * 100 + ")"; - if ( !Y[ a ] || !Y[ a ].hasLayout ) { - Y.style.zoom = 1; - } - } - break;case "float": - x = "styleFloat";default: - Y.style[ x ] = y; - } - } else {} - }; - } else { - return function( Y, G ) { - var x = E.Dom._toCamel( G.prop ), - y = G.val; - if ( Y ) { - if ( x == "float" ) { - x = "cssFloat"; - } - Y.style[ x ] = y; - } else {} - }; - } - }(), getXY: function( G ) { - return E.Dom.batch( G, E.Dom._getXY ); - }, - _canPosition: function( G ) { - return ( E.Dom._getStyle( G, "display" ) !== "none" && E.Dom._inDoc( G ) ); - }, - _getXY: function() { - if ( K[ v ][ Q ] ) { - return function( y ) { - var z, Y, AA, AF, AE, AD, AC, G, x, - AB = Math.floor, - AG = false; - if ( E.Dom._canPosition( y ) ) { - AA = y[ Q ](); - AF = y[ e ]; - z = E.Dom.getDocumentScrollLeft( AF ); - Y = E.Dom.getDocumentScrollTop( AF ); - AG = [ AB( AA[ j ] ), AB( AA[ o ] ) ]; - if ( T && m.ie < 8 ) { - AE = 2; - AD = 2; - AC = AF[ t ]; - G = S( AF[ v ], q ); - x = S( AF[ v ], R ); - if ( m.ie === 6 ) { - if ( AC !== c ) { - AE = 0; - AD = 0; - } - } - if ( ( AC == c ) ) { - if ( G !== r ) { - AE = parseInt( G, 10 ); - } - if ( x !== r ) { - AD = parseInt( x, 10 ); - } - } - AG[ 0 ] -= AE; - AG[ 1 ] -= AD; - } - if ( ( Y || z ) ) { - AG[ 0 ] += z; - AG[ 1 ] += Y; - } - AG[ 0 ] = AB( AG[ 0 ] ); - AG[ 1 ] = AB( AG[ 1 ] ); - } else {} - return AG; - }; - } else { - return function( y ) { - var x, Y, AA, AB, AC, - z = false, - G = y; - if ( E.Dom._canPosition( y ) ) { - z = [ y[ b ], y[ P ] ]; - x = E.Dom.getDocumentScrollLeft( y[ e ] ); - Y = E.Dom.getDocumentScrollTop( y[ e ] ); - AC = ( ( H || m.webkit > 519 ) ? true : false ); - while ( ( G = G[ u ] ) ) { - z[ 0 ] += G[ b ]; - z[ 1 ] += G[ P ]; - if ( AC ) { - z = E.Dom._calcBorders( G, z ); - } - } - if ( E.Dom._getStyle( y, p ) !== f ) { - G = y; - while ( ( G = G[ Z ] ) && G[ C ] ) { - AA = G[ i ]; - AB = G[ O ]; - if ( H && ( E.Dom._getStyle( G, "overflow" ) !== "visible" ) ) { - z = E.Dom._calcBorders( G, z ); - } - if ( AA || AB ) { - z[ 0 ] -= AB; - z[ 1 ] -= AA; - } - } - z[ 0 ] += x; - z[ 1 ] += Y; - } else { - if ( D ) { - z[ 0 ] -= x; - z[ 1 ] -= Y; - } else { - if ( I || H ) { - z[ 0 ] += x; - z[ 1 ] += Y; - } - } - } - z[ 0 ] = Math.floor( z[ 0 ] ); - z[ 1 ] = Math.floor( z[ 1 ] ); - } else {} - return z; - }; - } - }(), getX: function( G ) { - var Y = function( x ) { - return E.Dom.getXY( x )[ 0 ]; - }; - return E.Dom.batch( G, Y, E.Dom, true ); - }, - getY: function( G ) { - var Y = function( x ) { - return E.Dom.getXY( x )[ 1 ]; - }; - return E.Dom.batch( G, Y, E.Dom, true ); - }, - setXY: function( G, x, Y ) { - E.Dom.batch( G, E.Dom._setXY, { pos: x, noRetry: Y } ); - }, - _setXY: function( G, z ) { - var AA = E.Dom._getStyle( G, p ), - y = E.Dom.setStyle, - AD = z.pos, - Y = z.noRetry, - AB = [ parseInt( E.Dom.getComputedStyle( G, j ), 10 ), parseInt( E.Dom.getComputedStyle( G, o ), 10 ) ], - AC, x; - if ( AA == "static" ) { - AA = V; - y( G, p, AA ); - } - AC = E.Dom._getXY( G ); - if ( !AD || AC === false ) { - return false; - } - if ( isNaN( AB[ 0 ] ) ) { - AB[ 0 ] = ( AA == V ) ? 0 : G[ b ]; - } - if ( isNaN( AB[ 1 ] ) ) { - AB[ 1 ] = ( AA == V ) ? 0 : G[ P ]; - } - if ( AD[ 0 ] !== null ) { - y( G, j, AD[ 0 ] - AC[ 0 ] + AB[ 0 ] + "px" ); - } - if ( AD[ 1 ] !== null ) { - y( G, o, AD[ 1 ] - AC[ 1 ] + AB[ 1 ] + "px" ); - } - if ( !Y ) { - x = E.Dom._getXY( G ); - if ( ( AD[ 0 ] !== null && x[ 0 ] != AD[ 0 ] ) || ( AD[ 1 ] !== null && x[ 1 ] != AD[ 1 ] ) ) { - E.Dom._setXY( G, { pos: AD, noRetry: true } ); - } - } - }, - setX: function( Y, G ) { - E.Dom.setXY( Y, [ G, null ] ); - }, - setY: function( G, Y ) { - E.Dom.setXY( G, [ null, Y ] ); - }, - getRegion: function( G ) { - var Y = function( x ) { - var y = false; - if ( E.Dom._canPosition( x ) ) { - y = E.Region.getRegion( x ); - } else {} - return y; - }; - return E.Dom.batch( G, Y, E.Dom, true ); - }, - getClientWidth: function() { - return E.Dom.getViewportWidth(); - }, - getClientHeight: function() { - return E.Dom.getViewportHeight(); - }, - getElementsByClassName: function( AB, AF, AC, AE, x, AD ) { - AB = L.trim( AB ); - AF = AF || "*"; - AC = ( AC ) ? E.Dom.get( AC ) : null || K; - if ( !AC ) { - return []; - } - var Y = [], - G = AC.getElementsByTagName( AF ), - z = E.Dom.hasClass; - for ( var y = 0, AA = G.length; y < AA; ++y ) { - if ( z( G[ y ], AB ) ) { - Y[ Y.length ] = G[ y ]; - } - } - if ( AE ) { - E.Dom.batch( Y, AE, x, AD ); - } - return Y; - }, - hasClass: function( Y, G ) { - return E.Dom.batch( Y, E.Dom._hasClass, G ); - }, - _hasClass: function( x, Y ) { - var G = false, - y; if ( x && Y ) { - y = E.Dom.getAttribute( x, F ) || J; - if ( Y.exec ) { - G = Y.test( y ); - } else { - G = Y && ( B + y + B ).indexOf( B + Y + B ) > -1; - } - } else {} - return G; - }, - addClass: function( Y, G ) { - return E.Dom.batch( Y, E.Dom._addClass, G ); - }, - _addClass: function( x, Y ) { - var G = false, - y; if ( x && Y ) { - y = E.Dom.getAttribute( x, F ) || J; - if ( !E.Dom._hasClass( x, Y ) ) { - E.Dom.setAttribute( x, F, A( y + B + Y ) ); - G = true; - } - } else {} - return G; - }, - removeClass: function( Y, G ) { - return E.Dom.batch( Y, E.Dom._removeClass, G ); - }, - _removeClass: function( y, x ) { - var Y = false, - AA, z, G; if ( y && x ) { - AA = E.Dom.getAttribute( y, F ) || J; - E.Dom.setAttribute( y, F, AA.replace( E.Dom._getClassRegex( x ), J ) ); - z = E.Dom.getAttribute( y, F ); - if ( AA !== z ) { - E.Dom.setAttribute( y, F, A( z ) ); - Y = true; - if ( E.Dom.getAttribute( y, F ) === "" ) { - G = ( y.hasAttribute && y.hasAttribute( g ) ) ? g : F; - y.removeAttribute( G ); - } - } - } else {} - return Y; - }, - replaceClass: function( x, Y, G ) { - return E.Dom.batch( x, E.Dom._replaceClass, { from: Y, to: G } ); - }, - _replaceClass: function( y, x ) { - var Y, AB, AA, - G = false, - z; if ( y && x ) { - AB = x.from; - AA = x.to; - if ( !AA ) { - G = false; - } else { - if ( !AB ) { - G = E.Dom._addClass( y, x.to ); - } else { - if ( AB !== AA ) { - z = E.Dom.getAttribute( y, F ) || J; - Y = ( B + z.replace( E.Dom._getClassRegex( AB ), B + AA ) ).split( E.Dom._getClassRegex( AA ) ); - Y.splice( 1, 0, B + AA ); - E.Dom.setAttribute( y, F, A( Y.join( J ) ) ); - G = true; - } - } - } - } else {} - return G; - }, - generateId: function( G, x ) { - x = x || "yui-gen"; var Y = function( y ) { - if ( y && y.id ) { - return y.id; - } - var z = x + YAHOO.env._id_counter++; - if ( y ) { - if ( y[ e ].getElementById( z ) ) { - return E.Dom.generateId( y, z + x ); - } - y.id = z; - } - return z; - }; - return E.Dom.batch( G, Y, E.Dom, true ) || Y.apply( E.Dom, arguments ); - }, - isAncestor: function( Y, x ) { - Y = E.Dom.get( Y ); - x = E.Dom.get( x ); - var G = false; - if ( ( Y && x ) && ( Y[ l ] && x[ l ] ) ) { - if ( Y.contains && Y !== x ) { - G = Y.contains( x ); - } else { - if ( Y.compareDocumentPosition ) { - G = !!( Y.compareDocumentPosition( x ) & 16 ); - } - } - } else {} - return G; - }, - inDocument: function( G, Y ) { - return E.Dom._inDoc( E.Dom.get( G ), Y ); - }, - _inDoc: function( Y, x ) { - var G = false; if ( Y && Y[ C ] ) { - x = x || Y[ e ]; - G = E.Dom.isAncestor( x[ v ], Y ); - } else {} - return G; - }, - getElementsBy: function( Y, AF, AB, AD, y, AC, AE ) { - AF = AF || "*"; AB = ( AB ) ? E.Dom.get( AB ) : null || K; - if ( !AB ) { - return []; - } - var x = [], - G = AB.getElementsByTagName( AF ); - for ( var z = 0, AA = G.length; z < AA; ++z ) { - if ( Y( G[ z ] ) ) { - if ( AE ) { - x = G[ z ]; - break; - } else { - x[ x.length ] = G[ z ]; - } - } - } - if ( AD ) { - E.Dom.batch( x, AD, y, AC ); - } - return x; - }, - getElementBy: function( x, G, Y ) { - return E.Dom.getElementsBy( x, G, Y, null, null, null, true ); - }, - batch: function( x, AB, AA, z ) { - var y = [], - Y = ( z ) ? AA : window; - x = ( x && ( x[ C ] || x.item ) ) ? x : E.Dom.get( x ); - if ( x && AB ) { - if ( x[ C ] || x.length === undefined ) { - return AB.call( Y, x, AA ); - } - for ( var G = 0; G < x.length; ++G ) { - y[ y.length ] = AB.call( Y, x[ G ], AA ); - } - } else { - return false; - } - return y; - }, - getDocumentHeight: function() { - var Y = ( K[ t ] != M || I ) ? K.body.scrollHeight : W.scrollHeight, - G = Math.max( Y, E.Dom.getViewportHeight() ); - return G; - }, - getDocumentWidth: function() { - var Y = ( K[ t ] != M || I ) ? K.body.scrollWidth : W.scrollWidth, - G = Math.max( Y, E.Dom.getViewportWidth() ); - return G; - }, - getViewportHeight: function() { - var G = self.innerHeight, - Y = K[ t ]; - if ( ( Y || T ) && !D ) { - G = ( Y == M ) ? W.clientHeight : K.body.clientHeight; - } - return G; - }, - getViewportWidth: function() { - var G = self.innerWidth, - Y = K[ t ]; - if ( Y || T ) { - G = ( Y == M ) ? W.clientWidth : K.body.clientWidth; - } - return G; - }, - getAncestorBy: function( G, Y ) { - while ( ( G = G[ Z ] ) ) { - if ( E.Dom._testElement( G, Y ) ) { - return G; - } - } - return null; - }, - getAncestorByClassName: function( Y, G ) { - Y = E.Dom.get( Y ); - if ( !Y ) { - return null; - } - var x = function( y ) { - return E.Dom.hasClass( y, G ); - }; - return E.Dom.getAncestorBy( Y, x ); - }, - getAncestorByTagName: function( Y, G ) { - Y = E.Dom.get( Y ); - if ( !Y ) { - return null; - } - var x = function( y ) { - return y[ C ] && y[ C ].toUpperCase() == G.toUpperCase(); - }; - return E.Dom.getAncestorBy( Y, x ); - }, - getPreviousSiblingBy: function( G, Y ) { - while ( G ) { - G = G.previousSibling; - if ( E.Dom._testElement( G, Y ) ) { - return G; - } - } - return null; - }, - getPreviousSibling: function( G ) { - G = E.Dom.get( G ); - if ( !G ) { - return null; - } - return E.Dom.getPreviousSiblingBy( G ); - }, - getNextSiblingBy: function( G, Y ) { - while ( G ) { - G = G.nextSibling; - if ( E.Dom._testElement( G, Y ) ) { - return G; - } - } - return null; - }, - getNextSibling: function( G ) { - G = E.Dom.get( G ); - if ( !G ) { - return null; - } - return E.Dom.getNextSiblingBy( G ); - }, - getFirstChildBy: function( G, x ) { - var Y = ( E.Dom._testElement( G.firstChild, x ) ) ? G.firstChild : null; - return Y || E.Dom.getNextSiblingBy( G.firstChild, x ); - }, - getFirstChild: function( G, Y ) { - G = E.Dom.get( G ); - if ( !G ) { - return null; - } - return E.Dom.getFirstChildBy( G ); - }, - getLastChildBy: function( G, x ) { - if ( !G ) { - return null; - } - var Y = ( E.Dom._testElement( G.lastChild, x ) ) ? G.lastChild : null; - return Y || E.Dom.getPreviousSiblingBy( G.lastChild, x ); - }, - getLastChild: function( G ) { - G = E.Dom.get( G ); - return E.Dom.getLastChildBy( G ); - }, - getChildrenBy: function( Y, y ) { - var x = E.Dom.getFirstChildBy( Y, y ), - G = x ? [ x ] : []; - E.Dom.getNextSiblingBy( x, function( z ) { - if ( !y || y( z ) ) { - G[ G.length ] = z; - } - return false; - }); - return G; - }, - getChildren: function( G ) { - G = E.Dom.get( G ); - if ( !G ) {} - return E.Dom.getChildrenBy( G ); - }, - getDocumentScrollLeft: function( G ) { - G = G || K; return Math.max( G[ v ].scrollLeft, G.body.scrollLeft ); - }, - getDocumentScrollTop: function( G ) { - G = G || K; return Math.max( G[ v ].scrollTop, G.body.scrollTop ); - }, - insertBefore: function( Y, G ) { - Y = E.Dom.get( Y ); - G = E.Dom.get( G ); - if ( !Y || !G || !G[ Z ] ) { - return null; - } - return G[ Z ].insertBefore( Y, G ); - }, - insertAfter: function( Y, G ) { - Y = E.Dom.get( Y ); - G = E.Dom.get( G ); - if ( !Y || !G || !G[ Z ] ) { - return null; - } - if ( G.nextSibling ) { - return G[ Z ].insertBefore( Y, G.nextSibling ); - } else { - return G[ Z ].appendChild( Y ); - } - }, - getClientRegion: function() { - var x = E.Dom.getDocumentScrollTop(), - Y = E.Dom.getDocumentScrollLeft(), - y = E.Dom.getViewportWidth() + Y, - G = E.Dom.getViewportHeight() + x; - return new E.Region( x, y, G, Y ); - }, - setAttribute: function( Y, G, x ) { - G = E.Dom.CUSTOM_ATTRIBUTES[ G ] || G; - Y.setAttribute( G, x ); - }, - getAttribute: function( Y, G ) { - G = E.Dom.CUSTOM_ATTRIBUTES[ G ] || G; - return Y.getAttribute( G ); - }, - _toCamel: function( Y ) { - var x = d; - - function G( y, z ) { - return z.toUpperCase(); - } - return x[ Y ] || ( x[ Y ] = Y.indexOf( "-" ) === -1 ? Y : Y.replace( /-([a-z])/gi, G ) ); - }, - _getClassRegex: function( Y ) { - var G; if ( Y !== undefined ) { - if ( Y.exec ) { - G = Y; - } else { - G = h[ Y ]; - if ( !G ) { - Y = Y.replace( E.Dom._patterns.CLASS_RE_TOKENS, "\\$1" ); - G = h[ Y ] = new RegExp( s + Y + k, U ); - } - } - } - return G; - }, - _patterns: { ROOT_TAG: /^body|html$/i, CLASS_RE_TOKENS: /([\.\(\)\^\$\*\+\?\|\[\]\{\}])/g }, - _testElement: function( G, Y ) { - return G && G[ l ] == 1 && ( !Y || Y( G ) ); - }, - _calcBorders: function( x, y ) { - var Y = parseInt( E.Dom[ w ]( x, R ), 10 ) || 0, - G = parseInt( E.Dom[ w ]( x, q ), 10 ) || 0; - if ( H ) { - if ( N.test( x[ C ] ) ) { - Y = 0; - G = 0; - } - } - y[ 0 ] += G; - y[ 1 ] += Y; - return y; - } }; var S = E.Dom[ w ]; - if ( m.opera ) { - E.Dom[ w ] = function( Y, G ) { - var x = S( Y, G ); - if ( X.test( G ) ) { - x = E.Dom.Color.toRGB( x ); - } - return x; - }; - } - if ( m.webkit ) { - E.Dom[ w ] = function( Y, G ) { - var x = S( Y, G ); - if ( x === "rgba(0, 0, 0, 0)" ) { - x = "transparent"; - } - return x; - }; - } -})(); -YAHOO.util.Region = function( C, D, A, B ) { - this.top = C; - this.y = C; - this[ 1 ] = C; - this.right = D; - this.bottom = A; - this.left = B; - this.x = B; - this[ 0 ] = B; - this.width = this.right - this.left; - this.height = this.bottom - this.top; -}; -YAHOO.util.Region.prototype.contains = function( A ) { - return ( A.left >= this.left && A.right <= this.right && A.top >= this.top && A.bottom <= this.bottom ); -}; -YAHOO.util.Region.prototype.getArea = function() { - return ( ( this.bottom - this.top ) * ( this.right - this.left ) ); -}; -YAHOO.util.Region.prototype.intersect = function( E ) { - var C = Math.max( this.top, E.top ), - D = Math.min( this.right, E.right ), - A = Math.min( this.bottom, E.bottom ), - B = Math.max( this.left, E.left ); - if ( A >= C && D >= B ) { - return new YAHOO.util.Region( C, D, A, B ); - } else { - return null; - } -}; -YAHOO.util.Region.prototype.union = function( E ) { - var C = Math.min( this.top, E.top ), - D = Math.max( this.right, E.right ), - A = Math.max( this.bottom, E.bottom ), - B = Math.min( this.left, E.left ); - return new YAHOO.util.Region( C, D, A, B ); -}; -YAHOO.util.Region.prototype.toString = function() { - return ( "Region {" + "top: " + this.top + ", right: " + this.right + ", bottom: " + this.bottom + ", left: " + this.left + ", height: " + this.height + ", width: " + this.width + "}" ); -}; -YAHOO.util.Region.getRegion = function( D ) { - var F = YAHOO.util.Dom.getXY( D ), - C = F[ 1 ], - E = F[ 0 ] + D.offsetWidth, - A = F[ 1 ] + D.offsetHeight, - B = F[ 0 ]; - return new YAHOO.util.Region( C, E, A, B ); -}; -YAHOO.util.Point = function( A, B ) { - if ( YAHOO.lang.isArray( A ) ) { - B = A[ 1 ]; - A = A[ 0 ]; - } - YAHOO.util.Point.superclass.constructor.call( this, B, A, B, A ); -}; -YAHOO.extend( YAHOO.util.Point, YAHOO.util.Region ); -(function() { - var B = YAHOO.util, - A = "clientTop", - F = "clientLeft", - J = "parentNode", - K = "right", - W = "hasLayout", - I = "px", - U = "opacity", - L = "auto", - D = "borderLeftWidth", - G = "borderTopWidth", - P = "borderRightWidth", - V = "borderBottomWidth", - S = "visible", - Q = "transparent", - N = "height", - E = "width", - H = "style", - T = "currentStyle", - R = /^width|height$/, - O = /^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i, - M = { - get: function( X, Z ) { - var Y = "", - a = X[ T ][ Z ]; - if ( Z === U ) { - Y = B.Dom.getStyle( X, U ); - } else { - if ( !a || ( a.indexOf && a.indexOf( I ) > -1 ) ) { - Y = a; - } else { - if ( B.Dom.IE_COMPUTED[ Z ] ) { - Y = B.Dom.IE_COMPUTED[ Z ]( X, Z ); - } else { - if ( O.test( a ) ) { - Y = B.Dom.IE.ComputedStyle.getPixel( X, Z ); - } else { - Y = a; - } - } - } - } - return Y; - }, - getOffset: function( Z, e ) { - var b = Z[ T ][ e ], - X = e.charAt( 0 ).toUpperCase() + e.substr( 1 ), - c = "offset" + X, - Y = "pixel" + X, - a = "", - d; - if ( b == L ) { - d = Z[ c ]; - if ( d === undefined ) { - a = 0; - } - a = d; - if ( R.test( e ) ) { - Z[ H ][ e ] = d; - if ( Z[ c ] > d ) { - a = d - ( Z[ c ] - d ); - } - Z[ H ][ e ] = L; - } - } else { - if ( !Z[ H ][ Y ] && !Z[ H ][ e ] ) { - Z[ H ][ e ] = b; - } - a = Z[ H ][ Y ]; - } - return a + I; - }, - getBorderWidth: function( X, Z ) { - var Y = null; if ( !X[ T ][ W ] ) { - X[ H ].zoom = 1; - } - switch ( Z ) { - case G: - Y = X[ A ]; - break;case V: - Y = X.offsetHeight - X.clientHeight - X[ A ]; - break;case D: - Y = X[ F ]; - break;case P: - Y = X.offsetWidth - X.clientWidth - X[ F ]; - break; - } - return Y + I; - }, - getPixel: function( Y, X ) { - var a = null, - b = Y[ T ][ K ], - Z = Y[ T ][ X ]; - Y[ H ][ K ] = Z; - a = Y[ H ].pixelRight; - Y[ H ][ K ] = b; - return a + I; - }, - getMargin: function( Y, X ) { - var Z; if ( Y[ T ][ X ] == L ) { - Z = 0 + I; - } else { - Z = B.Dom.IE.ComputedStyle.getPixel( Y, X ); - } - return Z; - }, - getVisibility: function( Y, X ) { - var Z; while ( ( Z = Y[ T ] ) && Z[ X ] == "inherit" ) { - Y = Y[ J ]; - } - return ( Z ) ? Z[ X ] : S; - }, - getColor: function( Y, X ) { - return B.Dom.Color.toRGB( Y[ T ][ X ] ) || Q; - }, - getBorderColor: function( Y, X ) { - var Z = Y[ T ], - a = Z[ X ] || Z.color; - return B.Dom.Color.toRGB( B.Dom.Color.toHex( a ) ); - } }, - C = {}; - C.top = C.right = C.bottom = C.left = C[ E ] = C[ N ] = M.getOffset; - C.color = M.getColor; - C[ G ] = C[ P ] = C[ V ] = C[ D ] = M.getBorderWidth; - C.marginTop = C.marginRight = C.marginBottom = C.marginLeft = M.getMargin; - C.visibility = M.getVisibility; - C.borderColor = C.borderTopColor = C.borderRightColor = C.borderBottomColor = C.borderLeftColor = M.getBorderColor; - B.Dom.IE_COMPUTED = C; - B.Dom.IE_ComputedStyle = M; -})(); -(function() { - var C = "toString", - A = parseInt, - B = RegExp, - D = YAHOO.util; - D.Dom.Color = { - KEYWORDS: { black: "000", silver: "c0c0c0", gray: "808080", white: "fff", maroon: "800000", red: "f00", purple: "800080", fuchsia: "f0f", green: "008000", lime: "0f0", olive: "808000", yellow: "ff0", navy: "000080", blue: "00f", teal: "008080", aqua: "0ff" }, - re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i, re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i, re_hex3: /([0-9A-F])/gi, toRGB: function( E ) { - if ( !D.Dom.Color.re_RGB.test( E ) ) { - E = D.Dom.Color.toHex( E ); - } - if ( D.Dom.Color.re_hex.exec( E ) ) { - E = "rgb(" + [ A( B.$1, 16 ), A( B.$2, 16 ), A( B.$3, 16 ) ].join( ", " ) + ")"; - } - return E; - }, - toHex: function( H ) { - H = D.Dom.Color.KEYWORDS[ H ] || H; - if ( D.Dom.Color.re_RGB.exec( H ) ) { - var G = ( B.$1.length === 1 ) ? "0" + B.$1 : Number( B.$1 ), - F = ( B.$2.length === 1 ) ? "0" + B.$2 : Number( B.$2 ), - E = ( B.$3.length === 1 ) ? "0" + B.$3 : Number( B.$3 ); - H = [ G[ C ]( 16 ), F[ C ]( 16 ), E[ C ]( 16 ) ].join( "" ); - } - if ( H.length < 6 ) { - H = H.replace( D.Dom.Color.re_hex3, "$1$1" ); - } - if ( H !== "transparent" && H.indexOf( "#" ) < 0 ) { - H = "#" + H; - } - return H.toLowerCase(); - } }; -}() ); -YAHOO.register( "dom", YAHOO.util.Dom, { version: "2.7.0", build: "1796" } ); -YAHOO.util.CustomEvent = function( D, C, B, A ) { - this.type = D; - this.scope = C || window; - this.silent = B; - this.signature = A || YAHOO.util.CustomEvent.LIST; - this.subscribers = []; - if ( !this.silent ) {} - var E = "_YUICEOnSubscribe"; - if ( D !== E ) { - this.subscribeEvent = new YAHOO.util.CustomEvent( E, this, true ); - } - this.lastError = null; -}; -YAHOO.util.CustomEvent.LIST = 0; -YAHOO.util.CustomEvent.FLAT = 1; -YAHOO.util.CustomEvent.prototype = { - subscribe: function( A, B, C ) { - if ( !A ) { - throw new Error( "Invalid callback for subscriber to '" + this.type + "'" ); - } - if ( this.subscribeEvent ) { - this.subscribeEvent.fire( A, B, C ); - } - this.subscribers.push( new YAHOO.util.Subscriber( A, B, C ) ); - }, - unsubscribe: function( D, F ) { - if ( !D ) { - return this.unsubscribeAll(); - } - var E = false; - for ( var B = 0, A = this.subscribers.length; B < A; ++B ) { - var C = this.subscribers[ B ]; - if ( C && C.contains( D, F ) ) { - this._delete( B ); - E = true; - } - } - return E; - }, - fire: function() { - this.lastError = null; var K = [], - E = this.subscribers.length; - if ( !E && this.silent ) { - return true; - } - var I = [].slice.call( arguments, 0 ), - G = true, - D, - J = false; - if ( !this.silent ) {} - var C = this.subscribers.slice(), - A = YAHOO.util.Event.throwErrors; - for ( D = 0; D < E; ++D ) { - var M = C[ D ]; - if ( !M ) { - J = true; - } else { - if ( !this.silent ) {} - var L = M.getScope( this.scope ); - if ( this.signature == YAHOO.util.CustomEvent.FLAT ) { - var B = null; - if ( I.length > 0 ) { - B = I[ 0 ]; - } - try { - G = M.fn.call( L, B, M.obj ); - } catch ( F ) { - this.lastError = F; - if ( A ) { - throw F; - } - } - } else { - try { - G = M.fn.call( L, this.type, I, M.obj ); - } catch ( H ) { - this.lastError = H; - if ( A ) { - throw H; - } - } - } - if ( false === G ) { - if ( !this.silent ) {} - break; - } - } - } - return ( G !== false ); - }, - unsubscribeAll: function() { - var A = this.subscribers.length, - B; for ( B = A - 1; B > -1; B-- ) { - this._delete( B ); - } - this.subscribers = []; - return A; - }, - _delete: function( A ) { - var B = this.subscribers[ A ]; - if ( B ) { - delete B.fn; - delete B.obj; - } - this.subscribers.splice( A, 1 ); - }, - toString: function() { - return "CustomEvent: " + "'" + this.type + "', " + "context: " + this.scope; - } }; YAHOO.util.Subscriber = function( A, B, C ) { - this.fn = A; - this.obj = YAHOO.lang.isUndefined( B ) ? null : B; - this.overrideContext = C; -}; -YAHOO.util.Subscriber.prototype.getScope = function( A ) { - if ( this.overrideContext ) { - if ( this.overrideContext === true ) { - return this.obj; - } else { - return this.overrideContext; - } - } - return A; -}; -YAHOO.util.Subscriber.prototype.contains = function( A, B ) { - if ( B ) { - return ( this.fn == A && this.obj == B ); - } else { - return ( this.fn == A ); - } -}; -YAHOO.util.Subscriber.prototype.toString = function() { - return "Subscriber { obj: " + this.obj + ", overrideContext: " + ( this.overrideContext || "no" ) + " }"; -}; -if ( !YAHOO.util.Event ) { - YAHOO.util.Event = function() { - var H = false; - var I = []; - var J = []; - var G = []; - var E = []; - var C = 0; - var F = []; - var B = []; - var A = 0; - var D = { 63232: 38, 63233: 40, 63234: 37, 63235: 39, 63276: 33, 63277: 34, 25: 9 }; var K = YAHOO.env.ua.ie ? "focusin" : "focus"; var L = YAHOO.env.ua.ie ? "focusout" : "blur"; return { - POLL_RETRYS: 2000, POLL_INTERVAL: 20, EL: 0, TYPE: 1, FN: 2, WFN: 3, UNLOAD_OBJ: 3, ADJ_SCOPE: 4, OBJ: 5, OVERRIDE: 6, lastError: null, isSafari: YAHOO.env.ua.webkit, webkit: YAHOO.env.ua.webkit, isIE: YAHOO.env.ua.ie, _interval: null, _dri: null, DOMReady: false, throwErrors: false, startInterval: function() { - if ( !this._interval ) { - var M = this; - var N = function() { - M._tryPreloadAttach(); - }; - this._interval = setInterval( N, this.POLL_INTERVAL ); - } - }, - onAvailable: function( S, O, Q, R, P ) { - var M = ( YAHOO.lang.isString( S ) ) ? [ S ] : S; - for ( var N = 0; N < M.length; N = N + 1 ) { - F.push({ id: M[ N ], fn: O, obj: Q, overrideContext: R, checkReady: P } ); - } - C = this.POLL_RETRYS; - this.startInterval(); - }, - onContentReady: function( P, M, N, O ) { - this.onAvailable( P, M, N, O, true ); - }, - onDOMReady: function( M, N, O ) { - if ( this.DOMReady ) { - setTimeout( function() { - var P = window; - if ( O ) { - if ( O === true ) { - P = N; - } else { - P = O; - } - } - M.call( P, "DOMReady", [], N ); - }, 0 ); - } else { - this.DOMReadyEvent.subscribe( M, N, O ); - } - }, - _addListener: function( O, M, Y, S, W, b ) { - if ( !Y || !Y.call ) { - return false; - } - if ( this._isValidCollection( O ) ) { - var Z = true; - for ( var T = 0, V = O.length; T < V; ++T ) { - Z = this.on( O[ T ], M, Y, S, W ) && Z; - } - return Z; - } else { - if ( YAHOO.lang.isString( O ) ) { - var R = this.getEl( O ); - if ( R ) { - O = R; - } else { - this.onAvailable( O, function() { - YAHOO.util.Event.on( O, M, Y, S, W ); - }); - return true; - } - } - } - if ( !O ) { - return false; - } - if ( "unload" == M && S !== this ) { - J[ J.length ] = [ O, M, Y, S, W ]; - return true; - } - var N = O; - if ( W ) { - if ( W === true ) { - N = S; - } else { - N = W; - } - } - var P = function( c ) { - return Y.call( N, YAHOO.util.Event.getEvent( c, O ), S ); - }; - var a = [ O, M, Y, P, N, S, W ]; - var U = I.length; - I[ U ] = a; - if ( this.useLegacyEvent( O, M ) ) { - var Q = this.getLegacyIndex( O, M ); - if ( Q == -1 || O != G[ Q ][ 0 ] ) { - Q = G.length; - B[ O.id + M ] = Q; - G[ Q ] = [ O, M, O[ "on" + M ] ]; - E[ Q ] = []; - O[ "on" + M ] = function( c ) { - YAHOO.util.Event.fireLegacyEvent( YAHOO.util.Event.getEvent( c ), Q ); - }; - } - E[ Q ].push( a ); - } else { - try { - this._simpleAdd( O, M, P, b ); - } catch ( X ) { - this.lastError = X; - this.removeListener( O, M, Y ); - return false; - } - } - return true; - }, - addListener: function( N, Q, M, O, P ) { - return this._addListener( N, Q, M, O, P, false ); - }, - addFocusListener: function( N, M, O, P ) { - return this._addListener( N, K, M, O, P, true ); - }, - removeFocusListener: function( N, M ) { - return this.removeListener( N, K, M ); - }, - addBlurListener: function( N, M, O, P ) { - return this._addListener( N, L, M, O, P, true ); - }, - removeBlurListener: function( N, M ) { - return this.removeListener( N, L, M ); - }, - fireLegacyEvent: function( R, P ) { - var T = true, - M, V, U, N, S; V = E[ P ].slice(); - for ( var O = 0, Q = V.length; O < Q; ++O ) { - U = V[ O ]; - if ( U && U[ this.WFN ] ) { - N = U[ this.ADJ_SCOPE ]; - S = U[ this.WFN ].call( N, R ); - T = ( T && S ); - } - } - M = G[ P ]; - if ( M && M[ 2 ] ) { - M[ 2 ]( R ); - } - return T; - }, - getLegacyIndex: function( N, O ) { - var M = this.generateId( N ) + O; - if ( typeof B[ M ] == "undefined" ) { - return -1; - } else { - return B[ M ]; - } - }, - useLegacyEvent: function( M, N ) { - return ( this.webkit && this.webkit < 419 && ( "click" == N || "dblclick" == N ) ); - }, - removeListener: function( N, M, V ) { - var Q, T, X; if ( typeof N == "string" ) { - N = this.getEl( N ); - } else { - if ( this._isValidCollection( N ) ) { - var W = true; - for ( Q = N.length - 1; Q > -1; Q-- ) { - W = ( this.removeListener( N[ Q ], M, V ) && W ); - } - return W; - } - } - if ( !V || !V.call ) { - return this.purgeElement( N, false, M ); - } - if ( "unload" == M ) { - for ( Q = J.length - 1; Q > -1; Q-- ) { - X = J[ Q ]; - if ( X && X[ 0 ] == N && X[ 1 ] == M && X[ 2 ] == V ) { - J.splice( Q, 1 ); - return true; - } - } - return false; - } - var R = null; - var S = arguments[ 3 ]; - if ( "undefined" === typeof S ) { - S = this._getCacheIndex( N, M, V ); - } - if ( S >= 0 ) { - R = I[ S ]; - } - if ( !N || !R ) { - return false; - } - if ( this.useLegacyEvent( N, M ) ) { - var P = this.getLegacyIndex( N, M ); - var O = E[ P ]; - if ( O ) { - for ( Q = 0, T = O.length; Q < T; ++Q ) { - X = O[ Q ]; - if ( X && X[ this.EL ] == N && X[ this.TYPE ] == M && X[ this.FN ] == V ) { - O.splice( Q, 1 ); - break; - } - } - } - } else { - try { - this._simpleRemove( N, M, R[ this.WFN ], false ); - } catch ( U ) { - this.lastError = U; - return false; - } - } - delete I[ S ][ this.WFN ]; - delete I[ S ][ this.FN ]; - I.splice( S, 1 ); - return true; - }, - getTarget: function( O, N ) { - var M = O.target || O.srcElement; return this.resolveTextNode( M ); - }, - resolveTextNode: function( N ) { - try { - if ( N && 3 == N.nodeType ) { - return N.parentNode; - } - } catch ( M ) {} - return N; - }, - getPageX: function( N ) { - var M = N.pageX; if ( !M && 0 !== M ) { - M = N.clientX || 0; - if ( this.isIE ) { - M += this._getScrollLeft(); - } - } - return M; - }, - getPageY: function( M ) { - var N = M.pageY; if ( !N && 0 !== N ) { - N = M.clientY || 0; - if ( this.isIE ) { - N += this._getScrollTop(); - } - } - return N; - }, - getXY: function( M ) { - return [ this.getPageX( M ), this.getPageY( M ) ]; - }, - getRelatedTarget: function( N ) { - var M = N.relatedTarget; if ( !M ) { - if ( N.type == "mouseout" ) { - M = N.toElement; - } else { - if ( N.type == "mouseover" ) { - M = N.fromElement; - } - } - } - return this.resolveTextNode( M ); - }, - getTime: function( O ) { - if ( !O.time ) { - var N = new Date().getTime(); - try { - O.time = N; - } catch ( M ) { - this.lastError = M; - return N; - } - } - return O.time; - }, - stopEvent: function( M ) { - this.stopPropagation( M ); - this.preventDefault( M ); - }, - stopPropagation: function( M ) { - if ( M.stopPropagation ) { - M.stopPropagation(); - } else { - M.cancelBubble = true; - } - }, - preventDefault: function( M ) { - if ( M.preventDefault ) { - M.preventDefault(); - } else { - M.returnValue = false; - } - }, - getEvent: function( O, M ) { - var N = O || window.event; if ( !N ) { - var P = this.getEvent.caller; - while ( P ) { - N = P.arguments[ 0 ]; - if ( N && Event == N.constructor ) { - break; - } - P = P.caller; - } - } - return N; - }, - getCharCode: function( N ) { - var M = N.keyCode || N.charCode || 0; if ( YAHOO.env.ua.webkit && ( M in D ) ) { - M = D[ M ]; - } - return M; - }, - _getCacheIndex: function( Q, R, P ) { - for ( var O = 0, N = I.length; O < N; O = O + 1 ) { - var M = I[ O ]; - if ( M && M[ this.FN ] == P && M[ this.EL ] == Q && M[ this.TYPE ] == R ) { - return O; - } - } - return -1; - }, - generateId: function( M ) { - var N = M.id; if ( !N ) { - N = "yuievtautoid-" + A; - ++A; - M.id = N; - } - return N; - }, - _isValidCollection: function( N ) { - try { - return ( N && typeof N !== "string" && N.length && !N.tagName && !N.alert && typeof N[ 0 ] !== "undefined" ); - } catch ( M ) { - return false; - } - }, - elCache: {}, - getEl: function( M ) { - return ( typeof M === "string" ) ? document.getElementById( M ) : M; - }, - clearCache: function() {}, - DOMReadyEvent: new YAHOO.util.CustomEvent( "DOMReady", this ), _load: function( N ) { - if ( !H ) { - H = true; - var M = YAHOO.util.Event; - M._ready(); - M._tryPreloadAttach(); - } - }, - _ready: function( N ) { - var M = YAHOO.util.Event; if ( !M.DOMReady ) { - M.DOMReady = true; - M.DOMReadyEvent.fire(); - M._simpleRemove( document, "DOMContentLoaded", M._ready ); - } - }, - _tryPreloadAttach: function() { - if ( F.length === 0 ) { - C = 0; - if ( this._interval ) { - clearInterval( this._interval ); - this._interval = null; - } - return; - } - if ( this.locked ) { - return; - } - if ( this.isIE ) { - if ( !this.DOMReady ) { - this.startInterval(); - return; - } - } - this.locked = true; - var S = !H; - if ( !S ) { - S = ( C > 0 && F.length > 0 ); - } - var R = []; - var T = function( V, W ) { - var U = V; - if ( W.overrideContext ) { - if ( W.overrideContext === true ) { - U = W.obj; - } else { - U = W.overrideContext; - } - } - W.fn.call( U, W.obj ); - }; - var N, M, Q, P, - O = []; - for ( N = 0, M = F.length; N < M; N = N + 1 ) { - Q = F[ N ]; - if ( Q ) { - P = this.getEl( Q.id ); - if ( P ) { - if ( Q.checkReady ) { - if ( H || P.nextSibling || !S ) { - O.push( Q ); - F[ N ] = null; - } - } else { - T( P, Q ); - F[ N ] = null; - } - } else { - R.push( Q ); - } - } - } - for ( N = 0, M = O.length; N < M; N = N + 1 ) { - Q = O[ N ]; - T( this.getEl( Q.id ), Q ); - } - C--; - if ( S ) { - for ( N = F.length - 1; N > -1; N-- ) { - Q = F[ N ]; - if ( !Q || !Q.id ) { - F.splice( N, 1 ); - } - } - this.startInterval(); - } else { - if ( this._interval ) { - clearInterval( this._interval ); - this._interval = null; - } - } - this.locked = false; - }, - purgeElement: function( Q, R, T ) { - var O = ( YAHOO.lang.isString( Q ) ) ? this.getEl( Q ) : Q; - var S = this.getListeners( O, T ), - P, M; - if ( S ) { - for ( P = S.length - 1; P > -1; P-- ) { - var N = S[ P ]; - this.removeListener( O, N.type, N.fn ); - } - } - if ( R && O && O.childNodes ) { - for ( P = 0, M = O.childNodes.length; P < M; ++P ) { - this.purgeElement( O.childNodes[ P ], R, T ); - } - } - }, - getListeners: function( O, M ) { - var R = [], - N; - if ( !M ) { - N = [ I, J ]; - } else { - if ( M === "unload" ) { - N = [ J ]; - } else { - N = [ I ]; - } - } - var T = ( YAHOO.lang.isString( O ) ) ? this.getEl( O ) : O; - for ( var Q = 0; Q < N.length; Q = Q + 1 ) { - var V = N[ Q ]; - if ( V ) { - for ( var S = 0, U = V.length; S < U; ++S ) { - var P = V[ S ]; - if ( P && P[ this.EL ] === T && ( !M || M === P[ this.TYPE ] ) ) { - R.push({ type: P[ this.TYPE ], fn: P[ this.FN ], obj: P[ this.OBJ ], adjust: P[ this.OVERRIDE ], scope: P[ this.ADJ_SCOPE ], index: S } ); - } - } - } - } - return ( R.length ) ? R : null; - }, - _unload: function( T ) { - var N = YAHOO.util.Event, - Q, P, O, S, R, - U = J.slice(), - M; - for ( Q = 0, S = J.length; Q < S; ++Q ) { - O = U[ Q ]; - if ( O ) { - M = window; - if ( O[ N.ADJ_SCOPE ] ) { - if ( O[ N.ADJ_SCOPE ] === true ) { - M = O[ N.UNLOAD_OBJ ]; - } else { - M = O[ N.ADJ_SCOPE ]; - } - } - O[ N.FN ].call( M, N.getEvent( T, O[ N.EL ] ), O[ N.UNLOAD_OBJ ] ); - U[ Q ] = null; - } - } - O = null; - M = null; - J = null; - if ( I ) { - for ( P = I.length - 1; P > -1; P-- ) { - O = I[ P ]; - if ( O ) { - N.removeListener( O[ N.EL ], O[ N.TYPE ], O[ N.FN ], P ); - } - } - O = null; - } - G = null; - N._simpleRemove( window, "unload", N._unload ); - }, - _getScrollLeft: function() { - return this._getScroll()[ 1 ]; - }, - _getScrollTop: function() { - return this._getScroll()[ 0 ]; - }, - _getScroll: function() { - var M = document.documentElement, - N = document.body; if ( M && ( M.scrollTop || M.scrollLeft ) ) { - return [ M.scrollTop, M.scrollLeft ]; - } else { - if ( N ) { - return [ N.scrollTop, N.scrollLeft ]; - } else { - return [ 0, 0 ]; - } - } - }, - regCE: function() {}, - _simpleAdd: function() { - if ( window.addEventListener ) { - return function( O, P, N, M ) { - O.addEventListener( P, N, ( M ) ); - }; - } else { - if ( window.attachEvent ) { - return function( O, P, N, M ) { - O.attachEvent( "on" + P, N ); - }; - } else { - return function() {}; - } - } - }(), _simpleRemove: function() { - if ( window.removeEventListener ) { - return function( O, P, N, M ) { - O.removeEventListener( P, N, ( M ) ); - }; - } else { - if ( window.detachEvent ) { - return function( N, O, M ) { - N.detachEvent( "on" + O, M ); - }; - } else { - return function() {}; - } - } - }() }; - }(); - (function() { - var EU = YAHOO.util.Event; - EU.on = EU.addListener; - EU.onFocus = EU.addFocusListener; - EU.onBlur = EU.addBlurListener; - /* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */ - if ( EU.isIE ) { - YAHOO.util.Event.onDOMReady( YAHOO.util.Event._tryPreloadAttach, YAHOO.util.Event, true ); - var n = document.createElement( "p" ); - EU._dri = setInterval( function() { - try { - n.doScroll( "left" ); - clearInterval( EU._dri ); - EU._dri = null; - EU._ready(); - n = null; - } catch ( ex ) {} - }, EU.POLL_INTERVAL ); - } else { - if ( EU.webkit && EU.webkit < 525 ) { - EU._dri = setInterval( function() { - var rs = document.readyState; - if ( "loaded" == rs || "complete" == rs ) { - clearInterval( EU._dri ); - EU._dri = null; - EU._ready(); - } - }, EU.POLL_INTERVAL ); - } else { - EU._simpleAdd( document, "DOMContentLoaded", EU._ready ); - } - } - EU._simpleAdd( window, "load", EU._load ); - EU._simpleAdd( window, "unload", EU._unload ); - EU._tryPreloadAttach(); - })(); -} -YAHOO.util.EventProvider = function() {}; -YAHOO.util.EventProvider.prototype = { - __yui_events: null, __yui_subscribers: null, subscribe: function( A, C, F, E ) { - this.__yui_events = this.__yui_events || {}; - var D = this.__yui_events[ A ]; - if ( D ) { - D.subscribe( C, F, E ); - } else { - this.__yui_subscribers = this.__yui_subscribers || {}; - var B = this.__yui_subscribers; - if ( !B[ A ] ) { - B[ A ] = []; - } - B[ A ].push({ fn: C, obj: F, overrideContext: E } ); - } - }, - unsubscribe: function( C, E, G ) { - this.__yui_events = this.__yui_events || {}; - var A = this.__yui_events; - if ( C ) { - var F = A[ C ]; - if ( F ) { - return F.unsubscribe( E, G ); - } - } else { - var B = true; - for ( var D in A ) { - if ( YAHOO.lang.hasOwnProperty( A, D ) ) { - B = B && A[ D ].unsubscribe( E, G ); - } - } - return B; - } - return false; - }, - unsubscribeAll: function( A ) { - return this.unsubscribe( A ); - }, - createEvent: function( G, D ) { - this.__yui_events = this.__yui_events || {}; - var A = D || {}; - var I = this.__yui_events; - if ( I[ G ] ) {} else { - var H = A.scope || this; - var E = ( A.silent ); - var B = new YAHOO.util.CustomEvent( G, H, E, YAHOO.util.CustomEvent.FLAT ); - I[ G ] = B; - if ( A.onSubscribeCallback ) { - B.subscribeEvent.subscribe( A.onSubscribeCallback ); - } - this.__yui_subscribers = this.__yui_subscribers || {}; - var F = this.__yui_subscribers[ G ]; - if ( F ) { - for ( var C = 0; C < F.length; ++C ) { - B.subscribe( F[ C ].fn, F[ C ].obj, F[ C ].overrideContext ); - } - } - } - return I[ G ]; - }, - fireEvent: function( E, D, A, C ) { - this.__yui_events = this.__yui_events || {}; - var G = this.__yui_events[ E ]; - if ( !G ) { - return null; - } - var B = []; - for ( var F = 1; F < arguments.length; ++F ) { - B.push( arguments[ F ] ); - } - return G.fire.apply( G, B ); - }, - hasEvent: function( A ) { - if ( this.__yui_events ) { - if ( this.__yui_events[ A ] ) { - return true; - } - } - return false; - } }; -(function() { - var A = YAHOO.util.Event, - C = YAHOO.lang; - YAHOO.util.KeyListener = function( D, I, E, F ) { - if ( !D ) {} else { - if ( !I ) {} else { - if ( !E ) {} - } - } - if ( !F ) { - F = YAHOO.util.KeyListener.KEYDOWN; - } - var G = new YAHOO.util.CustomEvent( "keyPressed" ); - this.enabledEvent = new YAHOO.util.CustomEvent( "enabled" ); - this.disabledEvent = new YAHOO.util.CustomEvent( "disabled" ); - if ( C.isString( D ) ) { - D = document.getElementById( D ); - } - if ( C.isFunction( E ) ) { - G.subscribe( E ); - } else { - G.subscribe( E.fn, E.scope, E.correctScope ); - } - function H( O, N ) { - if ( !I.shift ) { - I.shift = false; - } - if ( !I.alt ) { - I.alt = false; - } - if ( !I.ctrl ) { - I.ctrl = false; - } - if ( O.shiftKey == I.shift && O.altKey == I.alt && O.ctrlKey == I.ctrl ) { - var J, - M = I.keys, - L; - if ( YAHOO.lang.isArray( M ) ) { - for ( var K = 0; K < M.length; K++ ) { - J = M[ K ]; - L = A.getCharCode( O ); - if ( J == L ) { - G.fire( L, O ); - break; - } - } - } else { - L = A.getCharCode( O ); - if ( M == L ) { - G.fire( L, O ); - } - } - } - } - this.enable = function() { - if ( !this.enabled ) { - A.on( D, F, H ); - this.enabledEvent.fire( I ); - } - this.enabled = true; - }; - this.disable = function() { - if ( this.enabled ) { - A.removeListener( D, F, H ); - this.disabledEvent.fire( I ); - } - this.enabled = false; - }; - this.toString = function() { - return "KeyListener [" + I.keys + "] " + D.tagName + ( D.id ? "[" + D.id + "]" : "" ); - }; - }; - var B = YAHOO.util.KeyListener; - B.KEYDOWN = "keydown"; - B.KEYUP = "keyup"; - B.KEY = { ALT: 18, BACK_SPACE: 8, CAPS_LOCK: 20, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, LEFT: 37, META: 224, NUM_LOCK: 144, PAGE_DOWN: 34, PAGE_UP: 33, PAUSE: 19, PRINTSCREEN: 44, RIGHT: 39, SCROLL_LOCK: 145, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38 }; -})(); -YAHOO.register( "event", YAHOO.util.Event, { version: "2.7.0", build: "1796" } ); -YAHOO.register( "yahoo-dom-event", YAHOO, { version: "2.7.0", build: "1796" } ); -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -if ( !YAHOO.util.DragDropMgr ) { - YAHOO.util.DragDropMgr = function() { - var A = YAHOO.util.Event, - B = YAHOO.util.Dom; - return { - useShim: false, _shimActive: false, _shimState: false, _debugShim: false, _createShim: function() { - var C = document.createElement( "div" ); - C.id = "yui-ddm-shim"; - if ( document.body.firstChild ) { - document.body.insertBefore( C, document.body.firstChild ); - } else { - document.body.appendChild( C ); - } - C.style.display = "none"; - C.style.backgroundColor = "red"; - C.style.position = "absolute"; - C.style.zIndex = "99999"; - B.setStyle( C, "opacity", "0" ); - this._shim = C; - A.on( C, "mouseup", this.handleMouseUp, this, true ); - A.on( C, "mousemove", this.handleMouseMove, this, true ); - A.on( window, "scroll", this._sizeShim, this, true ); - }, - _sizeShim: function() { - if ( this._shimActive ) { - var C = this._shim; - C.style.height = B.getDocumentHeight() + "px"; - C.style.width = B.getDocumentWidth() + "px"; - C.style.top = "0"; - C.style.left = "0"; - } - }, - _activateShim: function() { - if ( this.useShim ) { - if ( !this._shim ) { - this._createShim(); - } - this._shimActive = true; - var C = this._shim, - D = "0"; - if ( this._debugShim ) { - D = ".5"; - } - B.setStyle( C, "opacity", D ); - this._sizeShim(); - C.style.display = "block"; - } - }, - _deactivateShim: function() { - this._shim.style.display = "none"; this._shimActive = false; - }, - _shim: null, ids: {}, - handleIds: {}, - dragCurrent: null, dragOvers: {}, - deltaX: 0, deltaY: 0, preventDefault: true, stopPropagation: true, initialized: false, locked: false, interactionInfo: null, init: function() { - this.initialized = true; - }, - POINT: 0, INTERSECT: 1, STRICT_INTERSECT: 2, mode: 0, _execOnAll: function( E, D ) { - for ( var F in this.ids ) { - for ( var C in this.ids[ F ] ) { - var G = this.ids[ F ][ C ]; - if ( !this.isTypeOfDD( G ) ) { - continue; - } - G[ E ].apply( G, D ); - } - } - }, - _onLoad: function() { - this.init(); - A.on( document, "mouseup", this.handleMouseUp, this, true ); - A.on( document, "mousemove", this.handleMouseMove, this, true ); - A.on( window, "unload", this._onUnload, this, true ); - A.on( window, "resize", this._onResize, this, true ); - }, - _onResize: function( C ) { - this._execOnAll( "resetConstraints", [] ); - }, - lock: function() { - this.locked = true; - }, - unlock: function() { - this.locked = false; - }, - isLocked: function() { - return this.locked; - }, - locationCache: {}, - useCache: true, clickPixelThresh: 3, clickTimeThresh: 1000, dragThreshMet: false, clickTimeout: null, startX: 0, startY: 0, fromTimeout: false, regDragDrop: function( D, C ) { - if ( !this.initialized ) { - this.init(); - } - if ( !this.ids[ C ] ) { - this.ids[ C ] = {}; - } - this.ids[ C ][ D.id ] = D; - }, - removeDDFromGroup: function( E, C ) { - if ( !this.ids[ C ] ) { - this.ids[ C ] = {}; - } - var D = this.ids[ C ]; - if ( D && D[ E.id ] ) { - delete D[ E.id ]; - } - }, - _remove: function( E ) { - for ( var D in E.groups ) { - if ( D ) { - var C = this.ids[ D ]; - if ( C && C[ E.id ] ) { - delete C[ E.id ]; - } - } - } - delete this.handleIds[ E.id ]; - }, - regHandle: function( D, C ) { - if ( !this.handleIds[ D ] ) { - this.handleIds[ D ] = {}; - } - this.handleIds[ D ][ C ] = C; - }, - isDragDrop: function( C ) { - return ( this.getDDById( C ) ) ? true : false; - }, - getRelated: function( H, D ) { - var G = []; - for ( var F in H.groups ) { - for ( var E in this.ids[ F ] ) { - var C = this.ids[ F ][ E ]; - if ( !this.isTypeOfDD( C ) ) { - continue; - } - if ( !D || C.isTarget ) { - G[ G.length ] = C; - } - } - } - return G; - }, - isLegalTarget: function( G, F ) { - var D = this.getRelated( G, true ); - for ( var E = 0, C = D.length; E < C; ++E ) { - if ( D[ E ].id == F.id ) { - return true; - } - } - return false; - }, - isTypeOfDD: function( C ) { - return ( C && C.__ygDragDrop ); - }, - isHandle: function( D, C ) { - return ( this.handleIds[ D ] && this.handleIds[ D ][ C ] ); - }, - getDDById: function( D ) { - for ( var C in this.ids ) { - if ( this.ids[ C ][ D ] ) { - return this.ids[ C ][ D ]; - } - } - return null; - }, - handleMouseDown: function( E, D ) { - this.currentTarget = YAHOO.util.Event.getTarget( E ); - this.dragCurrent = D; - var C = D.getEl(); - this.startX = YAHOO.util.Event.getPageX( E ); - this.startY = YAHOO.util.Event.getPageY( E ); - this.deltaX = this.startX - C.offsetLeft; - this.deltaY = this.startY - C.offsetTop; - this.dragThreshMet = false; - this.clickTimeout = setTimeout( function() { - var F = YAHOO.util.DDM; - F.startDrag( F.startX, F.startY ); - F.fromTimeout = true; - }, this.clickTimeThresh ); - }, - startDrag: function( C, E ) { - if ( this.dragCurrent && this.dragCurrent.useShim ) { - this._shimState = this.useShim; - this.useShim = true; - } - this._activateShim(); - clearTimeout( this.clickTimeout ); - var D = this.dragCurrent; - if ( D && D.events.b4StartDrag ) { - D.b4StartDrag( C, E ); - D.fireEvent( "b4StartDragEvent", { x: C, y: E } ); - } - if ( D && D.events.startDrag ) { - D.startDrag( C, E ); - D.fireEvent( "startDragEvent", { x: C, y: E } ); - } - this.dragThreshMet = true; - }, - handleMouseUp: function( C ) { - if ( this.dragCurrent ) { - clearTimeout( this.clickTimeout ); - if ( this.dragThreshMet ) { - if ( this.fromTimeout ) { - this.fromTimeout = false; - this.handleMouseMove( C ); - } - this.fromTimeout = false; - this.fireEvents( C, true ); - } else {} - this.stopDrag( C ); - this.stopEvent( C ); - } - }, - stopEvent: function( C ) { - if ( this.stopPropagation ) { - YAHOO.util.Event.stopPropagation( C ); - } - if ( this.preventDefault ) { - YAHOO.util.Event.preventDefault( C ); - } - }, - stopDrag: function( E, D ) { - var C = this.dragCurrent; if ( C && !D ) { - if ( this.dragThreshMet ) { - if ( C.events.b4EndDrag ) { - C.b4EndDrag( E ); - C.fireEvent( "b4EndDragEvent", { e: E } ); - } - if ( C.events.endDrag ) { - C.endDrag( E ); - C.fireEvent( "endDragEvent", { e: E } ); - } - } - if ( C.events.mouseUp ) { - C.onMouseUp( E ); - C.fireEvent( "mouseUpEvent", { e: E } ); - } - } - if ( this._shimActive ) { - this._deactivateShim(); - if ( this.dragCurrent && this.dragCurrent.useShim ) { - this.useShim = this._shimState; - this._shimState = false; - } - } - this.dragCurrent = null; - this.dragOvers = {}; - }, - handleMouseMove: function( F ) { - var C = this.dragCurrent; if ( C ) { - if ( YAHOO.util.Event.isIE && !F.button ) { - this.stopEvent( F ); - return this.handleMouseUp( F ); - } else { - if ( F.clientX < 0 || F.clientY < 0 ) {} - } - if ( !this.dragThreshMet ) { - var E = Math.abs( this.startX - YAHOO.util.Event.getPageX( F ) ); - var D = Math.abs( this.startY - YAHOO.util.Event.getPageY( F ) ); - if ( E > this.clickPixelThresh || D > this.clickPixelThresh ) { - this.startDrag( this.startX, this.startY ); - } - } - if ( this.dragThreshMet ) { - if ( C && C.events.b4Drag ) { - C.b4Drag( F ); - C.fireEvent( "b4DragEvent", { e: F } ); - } - if ( C && C.events.drag ) { - C.onDrag( F ); - C.fireEvent( "dragEvent", { e: F } ); - } - if ( C ) { - this.fireEvents( F, false ); - } - } - this.stopEvent( F ); - } - }, - fireEvents: function( V, L ) { - var a = this.dragCurrent; if ( !a || a.isLocked() || a.dragOnly ) { - return; - } - var N = YAHOO.util.Event.getPageX( V ), - M = YAHOO.util.Event.getPageY( V ), - P = new YAHOO.util.Point( N, M ), - K = a.getTargetCoord( P.x, P.y ), - F = a.getDragEl(), - E = [ "out", "over", "drop", "enter" ], - U = new YAHOO.util.Region( K.y, K.x + F.offsetWidth, K.y + F.offsetHeight, K.x ), - I = [], - D = {}, - Q = [], - c = { outEvts: [], overEvts: [], dropEvts: [], enterEvts: [] }; for ( var S in this.dragOvers ) { - var d = this.dragOvers[ S ]; - if ( !this.isTypeOfDD( d ) ) { - continue; - } - if ( !this.isOverTarget( P, d, this.mode, U ) ) { - c.outEvts.push( d ); - } - I[ S ] = true; - delete this.dragOvers[ S ]; - } - for ( var R in a.groups ) { - if ( "string" != typeof R ) { - continue; - } - for ( S in this.ids[ R ] ) { - var G = this.ids[ R ][ S ]; - if ( !this.isTypeOfDD( G ) ) { - continue; - } - if ( G.isTarget && !G.isLocked() && G != a ) { - if ( this.isOverTarget( P, G, this.mode, U ) ) { - D[ R ] = true; - if ( L ) { - c.dropEvts.push( G ); - } else { - if ( !I[ G.id ] ) { - c.enterEvts.push( G ); - } else { - c.overEvts.push( G ); - } - this.dragOvers[ G.id ] = G; - } - } - } - } - } - this.interactionInfo = { out: c.outEvts, enter: c.enterEvts, over: c.overEvts, drop: c.dropEvts, point: P, draggedRegion: U, sourceRegion: this.locationCache[ a.id ], validDrop: L }; for ( var C in D ) { - Q.push( C ); - } - if ( L && !c.dropEvts.length ) { - this.interactionInfo.validDrop = false; - if ( a.events.invalidDrop ) { - a.onInvalidDrop( V ); - a.fireEvent( "invalidDropEvent", { e: V } ); - } - } - for ( S = 0; S < E.length; S++ ) { - var Y = null; - if ( c[ E[ S ] + "Evts" ] ) { - Y = c[ E[ S ] + "Evts" ]; - } - if ( Y && Y.length ) { - var H = E[ S ].charAt( 0 ).toUpperCase() + E[ S ].substr( 1 ), - X = "onDrag" + H, - J = "b4Drag" + H, - O = "drag" + H + "Event", - W = "drag" + H; - if ( this.mode ) { - if ( a.events[ J ] ) { - a[ J ]( V, Y, Q ); - a.fireEvent( J + "Event", { event: V, info: Y, group: Q } ); - } - if ( a.events[ W ] ) { - a[ X ]( V, Y, Q ); - a.fireEvent( O, { event: V, info: Y, group: Q } ); - } - } else { - for ( var Z = 0, T = Y.length; Z < T; ++Z ) { - if ( a.events[ J ] ) { - a[ J ]( V, Y[ Z ].id, Q[ 0 ] ); - a.fireEvent( J + "Event", { event: V, info: Y[ Z ].id, group: Q[ 0 ] } ); - } - if ( a.events[ W ] ) { - a[ X ]( V, Y[ Z ].id, Q[ 0 ] ); - a.fireEvent( O, { event: V, info: Y[ Z ].id, group: Q[ 0 ] } ); - } - } - } - } - } - }, - getBestMatch: function( E ) { - var G = null; var D = E.length; if ( D == 1 ) { - G = E[ 0 ]; - } else { - for ( var F = 0; F < D; ++F ) { - var C = E[ F ]; - if ( this.mode == this.INTERSECT && C.cursorIsOver ) { - G = C; - break; - } else { - if ( !G || !G.overlap || ( C.overlap && G.overlap.getArea() < C.overlap.getArea() ) ) { - G = C; - } - } - } - } - return G; - }, - refreshCache: function( D ) { - var F = D || this.ids; for ( var C in F ) { - if ( "string" != typeof C ) { - continue; - } - for ( var E in this.ids[ C ] ) { - var G = this.ids[ C ][ E ]; - if ( this.isTypeOfDD( G ) ) { - var H = this.getLocation( G ); - if ( H ) { - this.locationCache[ G.id ] = H; - } else { - delete this.locationCache[ G.id ]; - } - } - } - } - }, - verifyEl: function( D ) { - try { - if ( D ) { - var C = D.offsetParent; - if ( C ) { - return true; - } - } - } catch ( E ) {} - return false; - }, - getLocation: function( H ) { - if ( !this.isTypeOfDD( H ) ) { - return null; - } - var F = H.getEl(), - K, E, D, M, L, N, C, J, G; - try { - K = YAHOO.util.Dom.getXY( F ); - } catch ( I ) {} - if ( !K ) { - return null; - } - E = K[ 0 ]; - D = E + F.offsetWidth; - M = K[ 1 ]; - L = M + F.offsetHeight; - N = M - H.padding[ 0 ]; - C = D + H.padding[ 1 ]; - J = L + H.padding[ 2 ]; - G = E - H.padding[ 3 ]; - return new YAHOO.util.Region( N, C, J, G ); - }, - isOverTarget: function( K, C, E, F ) { - var G = this.locationCache[ C.id ]; - if ( !G || !this.useCache ) { - G = this.getLocation( C ); - this.locationCache[ C.id ] = G; - } - if ( !G ) { - return false; - } - C.cursorIsOver = G.contains( K ); - var J = this.dragCurrent; - if ( !J || ( !E && !J.constrainX && !J.constrainY ) ) { - return C.cursorIsOver; - } - C.overlap = null; - if ( !F ) { - var H = J.getTargetCoord( K.x, K.y ); - var D = J.getDragEl(); - F = new YAHOO.util.Region( H.y, H.x + D.offsetWidth, H.y + D.offsetHeight, H.x ); - } - var I = F.intersect( G ); - if ( I ) { - C.overlap = I; - return ( E ) ? true : C.cursorIsOver; - } else { - return false; - } - }, - _onUnload: function( D, C ) { - this.unregAll(); - }, - unregAll: function() { - if ( this.dragCurrent ) { - this.stopDrag(); - this.dragCurrent = null; - } - this._execOnAll( "unreg", [] ); - this.ids = {}; - }, - elementCache: {}, - getElWrapper: function( D ) { - var C = this.elementCache[ D ]; - if ( !C || !C.el ) { - C = this.elementCache[ D ] = new this.ElementWrapper( YAHOO.util.Dom.get( D ) ); - } - return C; - }, - getElement: function( C ) { - return YAHOO.util.Dom.get( C ); - }, - getCss: function( D ) { - var C = YAHOO.util.Dom.get( D ); - return ( C ) ? C.style : null; - }, - ElementWrapper: function( C ) { - this.el = C || null; this.id = this.el && C.id; this.css = this.el && C.style; - }, - getPosX: function( C ) { - return YAHOO.util.Dom.getX( C ); - }, - getPosY: function( C ) { - return YAHOO.util.Dom.getY( C ); - }, - swapNode: function( E, C ) { - if ( E.swapNode ) { - E.swapNode( C ); - } else { - var F = C.parentNode; - var D = C.nextSibling; - if ( D == E ) { - F.insertBefore( E, C ); - } else { - if ( C == E.nextSibling ) { - F.insertBefore( C, E ); - } else { - E.parentNode.replaceChild( C, E ); - F.insertBefore( E, D ); - } - } - } - }, - getScroll: function() { - var E, C, - F = document.documentElement, - D = document.body; if ( F && ( F.scrollTop || F.scrollLeft ) ) { - E = F.scrollTop; - C = F.scrollLeft; - } else { - if ( D ) { - E = D.scrollTop; - C = D.scrollLeft; - } else {} - } - return { top: E, left: C }; - }, - getStyle: function( D, C ) { - return YAHOO.util.Dom.getStyle( D, C ); - }, - getScrollTop: function() { - return this.getScroll().top; - }, - getScrollLeft: function() { - return this.getScroll().left; - }, - moveToEl: function( C, E ) { - var D = YAHOO.util.Dom.getXY( E ); - YAHOO.util.Dom.setXY( C, D ); - }, - getClientHeight: function() { - return YAHOO.util.Dom.getViewportHeight(); - }, - getClientWidth: function() { - return YAHOO.util.Dom.getViewportWidth(); - }, - numericSort: function( D, C ) { - return ( D - C ); - }, - _timeoutCount: 0, _addListeners: function() { - var C = YAHOO.util.DDM; if ( YAHOO.util.Event && document ) { - C._onLoad(); - } else { - if ( C._timeoutCount > 2000 ) {} else { - setTimeout( C._addListeners, 10 ); - if ( document && document.body ) { - C._timeoutCount += 1; - } - } - } - }, - handleWasClicked: function( C, E ) { - if ( this.isHandle( E, C.id ) ) { - return true; - } else { - var D = C.parentNode; - while ( D ) { - if ( this.isHandle( E, D.id ) ) { - return true; - } else { - D = D.parentNode; - } - } - } - return false; - } }; - }(); - YAHOO.util.DDM = YAHOO.util.DragDropMgr; - YAHOO.util.DDM._addListeners(); -}( function() { - var A = YAHOO.util.Event; - var B = YAHOO.util.Dom; - YAHOO.util.DragDrop = function( E, C, D ) { - if ( E ) { - this.init( E, C, D ); - } - }; - YAHOO.util.DragDrop.prototype = { - events: null, on: function() { - this.subscribe.apply( this, arguments ); - }, - id: null, config: null, dragElId: null, handleElId: null, invalidHandleTypes: null, invalidHandleIds: null, invalidHandleClasses: null, startPageX: 0, startPageY: 0, groups: null, locked: false, lock: function() { - this.locked = true; - }, - unlock: function() { - this.locked = false; - }, - isTarget: true, padding: null, dragOnly: false, useShim: false, _domRef: null, __ygDragDrop: true, constrainX: false, constrainY: false, minX: 0, maxX: 0, minY: 0, maxY: 0, deltaX: 0, deltaY: 0, maintainOffset: false, xTicks: null, yTicks: null, primaryButtonOnly: true, available: false, hasOuterHandles: false, cursorIsOver: false, overlap: null, b4StartDrag: function( C, D ) {}, - startDrag: function( C, D ) {}, - b4Drag: function( C ) {}, - onDrag: function( C ) {}, - onDragEnter: function( C, D ) {}, - b4DragOver: function( C ) {}, - onDragOver: function( C, D ) {}, - b4DragOut: function( C ) {}, - onDragOut: function( C, D ) {}, - b4DragDrop: function( C ) {}, - onDragDrop: function( C, D ) {}, - onInvalidDrop: function( C ) {}, - b4EndDrag: function( C ) {}, - endDrag: function( C ) {}, - b4MouseDown: function( C ) {}, - onMouseDown: function( C ) {}, - onMouseUp: function( C ) {}, - onAvailable: function() {}, - getEl: function() { - if ( !this._domRef ) { - this._domRef = B.get( this.id ); - } - return this._domRef; - }, - getDragEl: function() { - return B.get( this.dragElId ); - }, - init: function( F, C, D ) { - this.initTarget( F, C, D ); - A.on( this._domRef || this.id, "mousedown", this.handleMouseDown, this, true ); - for ( var E in this.events ) { - this.createEvent( E + "Event" ); - } - }, - initTarget: function( E, C, D ) { - this.config = D || {}; - this.events = {}; - this.DDM = YAHOO.util.DDM; - this.groups = {}; - if ( typeof E !== "string" ) { - this._domRef = E; - E = B.generateId( E ); - } - this.id = E; - this.addToGroup( ( C ) ? C : "default" ); - this.handleElId = E; - A.onAvailable( E, this.handleOnAvailable, this, true ); - this.setDragElId( E ); - this.invalidHandleTypes = { A: "A" }; this.invalidHandleIds = {}; - this.invalidHandleClasses = []; - this.applyConfig(); - }, - applyConfig: function() { - this.events = { mouseDown: true, b4MouseDown: true, mouseUp: true, b4StartDrag: true, startDrag: true, b4EndDrag: true, endDrag: true, drag: true, b4Drag: true, invalidDrop: true, b4DragOut: true, dragOut: true, dragEnter: true, b4DragOver: true, dragOver: true, b4DragDrop: true, dragDrop: true }; if ( this.config.events ) { - for ( var C in this.config.events ) { - if ( this.config.events[ C ] === false ) { - this.events[ C ] = false; - } - } - } - this.padding = this.config.padding || [ 0, 0, 0, 0 ]; - this.isTarget = ( this.config.isTarget !== false ); - this.maintainOffset = ( this.config.maintainOffset ); - this.primaryButtonOnly = ( this.config.primaryButtonOnly !== false ); - this.dragOnly = ( ( this.config.dragOnly === true ) ? true : false ); - this.useShim = ( ( this.config.useShim === true ) ? true : false ); - }, - handleOnAvailable: function() { - this.available = true; this.resetConstraints(); - this.onAvailable(); - }, - setPadding: function( E, C, F, D ) { - if ( !C && 0 !== C ) { - this.padding = [ E, E, E, E ]; - } else { - if ( !F && 0 !== F ) { - this.padding = [ E, C, E, C ]; - } else { - this.padding = [ E, C, F, D ]; - } - } - }, - setInitPosition: function( F, E ) { - var G = this.getEl(); - if ( !this.DDM.verifyEl( G ) ) { - if ( G && G.style && ( G.style.display == "none" ) ) {} else {} - return; - } - var D = F || 0; - var C = E || 0; - var H = B.getXY( G ); - this.initPageX = H[ 0 ] - D; - this.initPageY = H[ 1 ] - C; - this.lastPageX = H[ 0 ]; - this.lastPageY = H[ 1 ]; - this.setStartPosition( H ); - }, - setStartPosition: function( D ) { - var C = D || B.getXY( this.getEl() ); - this.deltaSetXY = null; - this.startPageX = C[ 0 ]; - this.startPageY = C[ 1 ]; - }, - addToGroup: function( C ) { - this.groups[ C ] = true; - this.DDM.regDragDrop( this, C ); - }, - removeFromGroup: function( C ) { - if ( this.groups[ C ] ) { - delete this.groups[ C ]; - } - this.DDM.removeDDFromGroup( this, C ); - }, - setDragElId: function( C ) { - this.dragElId = C; - }, - setHandleElId: function( C ) { - if ( typeof C !== "string" ) { - C = B.generateId( C ); - } - this.handleElId = C; - this.DDM.regHandle( this.id, C ); - }, - setOuterHandleElId: function( C ) { - if ( typeof C !== "string" ) { - C = B.generateId( C ); - } - A.on( C, "mousedown", this.handleMouseDown, this, true ); - this.setHandleElId( C ); - this.hasOuterHandles = true; - }, - unreg: function() { - A.removeListener( this.id, "mousedown", this.handleMouseDown ); - this._domRef = null; - this.DDM._remove( this ); - }, - isLocked: function() { - return ( this.DDM.isLocked() || this.locked ); - }, - handleMouseDown: function( J, I ) { - var D = J.which || J.button; if ( this.primaryButtonOnly && D > 1 ) { - return; - } - if ( this.isLocked() ) { - return; - } - var C = this.b4MouseDown( J ), - F = true; - if ( this.events.b4MouseDown ) { - F = this.fireEvent( "b4MouseDownEvent", J ); - } - var E = this.onMouseDown( J ), - H = true; - if ( this.events.mouseDown ) { - H = this.fireEvent( "mouseDownEvent", J ); - } - if ( ( C === false ) || ( E === false ) || ( F === false ) || ( H === false ) ) { - return; - } - this.DDM.refreshCache( this.groups ); - var G = new YAHOO.util.Point( A.getPageX( J ), A.getPageY( J ) ); - if ( !this.hasOuterHandles && !this.DDM.isOverTarget( G, this ) ) {} else { - if ( this.clickValidator( J ) ) { - this.setStartPosition(); - this.DDM.handleMouseDown( J, this ); - this.DDM.stopEvent( J ); - } else {} - } - }, - clickValidator: function( D ) { - var C = YAHOO.util.Event.getTarget( D ); - return ( this.isValidHandleChild( C ) && ( this.id == this.handleElId || this.DDM.handleWasClicked( C, this.id ) ) ); - }, - getTargetCoord: function( E, D ) { - var C = E - this.deltaX; var F = D - this.deltaY; if ( this.constrainX ) { - if ( C < this.minX ) { - C = this.minX; - } - if ( C > this.maxX ) { - C = this.maxX; - } - } - if ( this.constrainY ) { - if ( F < this.minY ) { - F = this.minY; - } - if ( F > this.maxY ) { - F = this.maxY; - } - } - C = this.getTick( C, this.xTicks ); - F = this.getTick( F, this.yTicks ); - return { x: C, y: F }; - }, - addInvalidHandleType: function( C ) { - var D = C.toUpperCase(); - this.invalidHandleTypes[ D ] = D; - }, - addInvalidHandleId: function( C ) { - if ( typeof C !== "string" ) { - C = B.generateId( C ); - } - this.invalidHandleIds[ C ] = C; - }, - addInvalidHandleClass: function( C ) { - this.invalidHandleClasses.push( C ); - }, - removeInvalidHandleType: function( C ) { - var D = C.toUpperCase(); - delete this.invalidHandleTypes[ D ]; - }, - removeInvalidHandleId: function( C ) { - if ( typeof C !== "string" ) { - C = B.generateId( C ); - } - delete this.invalidHandleIds[ C ]; - }, - removeInvalidHandleClass: function( D ) { - for ( var E = 0, C = this.invalidHandleClasses.length; E < C; ++E ) { - if ( this.invalidHandleClasses[ E ] == D ) { - delete this.invalidHandleClasses[ E ]; - } - } - }, - isValidHandleChild: function( F ) { - var E = true; var H; try { - H = F.nodeName.toUpperCase(); - } catch ( G ) { - H = F.nodeName; - } - E = E && !this.invalidHandleTypes[ H ]; - E = E && !this.invalidHandleIds[ F.id ]; - for ( var D = 0, C = this.invalidHandleClasses.length; E && D < C; ++D ) { - E = !B.hasClass( F, this.invalidHandleClasses[ D ] ); - } - return E; - }, - setXTicks: function( F, C ) { - this.xTicks = []; - this.xTickSize = C; - var E = {}; - for ( var D = this.initPageX; D >= this.minX; D = D - C ) { - if ( !E[ D ] ) { - this.xTicks[ this.xTicks.length ] = D; - E[ D ] = true; - } - } - for ( D = this.initPageX; D <= this.maxX; D = D + C ) { - if ( !E[ D ] ) { - this.xTicks[ this.xTicks.length ] = D; - E[ D ] = true; - } - } - this.xTicks.sort( this.DDM.numericSort ); - }, - setYTicks: function( F, C ) { - this.yTicks = []; - this.yTickSize = C; - var E = {}; - for ( var D = this.initPageY; D >= this.minY; D = D - C ) { - if ( !E[ D ] ) { - this.yTicks[ this.yTicks.length ] = D; - E[ D ] = true; - } - } - for ( D = this.initPageY; D <= this.maxY; D = D + C ) { - if ( !E[ D ] ) { - this.yTicks[ this.yTicks.length ] = D; - E[ D ] = true; - } - } - this.yTicks.sort( this.DDM.numericSort ); - }, - setXConstraint: function( E, D, C ) { - this.leftConstraint = parseInt( E, 10 ); - this.rightConstraint = parseInt( D, 10 ); - this.minX = this.initPageX - this.leftConstraint; - this.maxX = this.initPageX + this.rightConstraint; - if ( C ) { - this.setXTicks( this.initPageX, C ); - } - this.constrainX = true; - }, - clearConstraints: function() { - this.constrainX = false; this.constrainY = false; this.clearTicks(); - }, - clearTicks: function() { - this.xTicks = null; this.yTicks = null; this.xTickSize = 0; this.yTickSize = 0; - }, - setYConstraint: function( C, E, D ) { - this.topConstraint = parseInt( C, 10 ); - this.bottomConstraint = parseInt( E, 10 ); - this.minY = this.initPageY - this.topConstraint; - this.maxY = this.initPageY + this.bottomConstraint; - if ( D ) { - this.setYTicks( this.initPageY, D ); - } - this.constrainY = true; - }, - resetConstraints: function() { - if ( this.initPageX || this.initPageX === 0 ) { - var D = ( this.maintainOffset ) ? this.lastPageX - this.initPageX : 0; - var C = ( this.maintainOffset ) ? this.lastPageY - this.initPageY : 0; - this.setInitPosition( D, C ); - } else { - this.setInitPosition(); - } - if ( this.constrainX ) { - this.setXConstraint( this.leftConstraint, this.rightConstraint, this.xTickSize ); - } - if ( this.constrainY ) { - this.setYConstraint( this.topConstraint, this.bottomConstraint, this.yTickSize ); - } - }, - getTick: function( I, F ) { - if ( !F ) { - return I; - } else { - if ( F[ 0 ] >= I ) { - return F[ 0 ]; - } else { - for ( var D = 0, C = F.length; D < C; ++D ) { - var E = D + 1; - if ( F[ E ] && F[ E ] >= I ) { - var H = I - F[ D ]; - var G = F[ E ] - I; - return ( G > H ) ? F[ D ] : F[ E ]; - } - } - return F[ F.length - 1 ]; - } - } - }, - toString: function() { - return ( "DragDrop " + this.id ); - } }; YAHOO.augment( YAHOO.util.DragDrop, YAHOO.util.EventProvider ); -})(); -YAHOO.util.DD = function( C, A, B ) { - if ( C ) { - this.init( C, A, B ); - } -}; -YAHOO.extend( YAHOO.util.DD, YAHOO.util.DragDrop, { - scroll: true, autoOffset: function( C, B ) { - var A = C - this.startPageX; var D = B - this.startPageY; this.setDelta( A, D ); - }, - setDelta: function( B, A ) { - this.deltaX = B; this.deltaY = A; - }, - setDragElPos: function( C, B ) { - var A = this.getDragEl(); - this.alignElWithMouse( A, C, B ); - }, - alignElWithMouse: function( C, G, F ) { - var E = this.getTargetCoord( G, F ); - if ( !this.deltaSetXY ) { - var H = [ E.x, E.y ]; - YAHOO.util.Dom.setXY( C, H ); - var D = parseInt( YAHOO.util.Dom.getStyle( C, "left" ), 10 ); - var B = parseInt( YAHOO.util.Dom.getStyle( C, "top" ), 10 ); - this.deltaSetXY = [ D - E.x, B - E.y ]; - } else { - YAHOO.util.Dom.setStyle( C, "left", ( E.x + this.deltaSetXY[ 0 ] ) + "px" ); - YAHOO.util.Dom.setStyle( C, "top", ( E.y + this.deltaSetXY[ 1 ] ) + "px" ); - } - this.cachePosition( E.x, E.y ); - var A = this; - setTimeout( function() { - A.autoScroll.call( A, E.x, E.y, C.offsetHeight, C.offsetWidth ); - }, 0 ); - }, - cachePosition: function( B, A ) { - if ( B ) { - this.lastPageX = B; - this.lastPageY = A; - } else { - var C = YAHOO.util.Dom.getXY( this.getEl() ); - this.lastPageX = C[ 0 ]; - this.lastPageY = C[ 1 ]; - } - }, - autoScroll: function( J, I, E, K ) { - if ( this.scroll ) { - var L = this.DDM.getClientHeight(); - var B = this.DDM.getClientWidth(); - var N = this.DDM.getScrollTop(); - var D = this.DDM.getScrollLeft(); - var H = E + I; - var M = K + J; - var G = ( L + N - I - this.deltaY ); - var F = ( B + D - J - this.deltaX ); - var C = 40; - var A = ( document.all ) ? 80 : 30; - if ( H > L && G < C ) { - window.scrollTo( D, N + A ); - } - if ( I < N && N > 0 && I - N < C ) { - window.scrollTo( D, N - A ); - } - if ( M > B && F < C ) { - window.scrollTo( D + A, N ); - } - if ( J < D && D > 0 && J - D < C ) { - window.scrollTo( D - A, N ); - } - } - }, - applyConfig: function() { - YAHOO.util.DD.superclass.applyConfig.call( this ); - this.scroll = ( this.config.scroll !== false ); - }, - b4MouseDown: function( A ) { - this.setStartPosition(); - this.autoOffset( YAHOO.util.Event.getPageX( A ), YAHOO.util.Event.getPageY( A ) ); - }, - b4Drag: function( A ) { - this.setDragElPos( YAHOO.util.Event.getPageX( A ), YAHOO.util.Event.getPageY( A ) ); - }, - toString: function() { - return ( "DD " + this.id ); - } } ); -YAHOO.util.DDProxy = function( C, A, B ) { - if ( C ) { - this.init( C, A, B ); - this.initFrame(); - } -}; -YAHOO.util.DDProxy.dragElId = "ygddfdiv"; -YAHOO.extend( YAHOO.util.DDProxy, YAHOO.util.DD, { - resizeFrame: true, centerFrame: false, createFrame: function() { - var B = this, - A = document.body; if ( !A || !A.firstChild ) { - setTimeout( function() { - B.createFrame(); - }, 50 ); - return; - } - var F = this.getDragEl(), - E = YAHOO.util.Dom; - if ( !F ) { - F = document.createElement( "div" ); - F.id = this.dragElId; - var D = F.style; - D.position = "absolute"; - D.visibility = "hidden"; - D.cursor = "move"; - D.border = "2px solid #aaa"; - D.zIndex = 999; - D.height = "25px"; - D.width = "25px"; - var C = document.createElement( "div" ); - E.setStyle( C, "height", "100%" ); - E.setStyle( C, "width", "100%" ); - E.setStyle( C, "background-color", "#ccc" ); - E.setStyle( C, "opacity", "0" ); - F.appendChild( C ); - A.insertBefore( F, A.firstChild ); - } - }, - initFrame: function() { - this.createFrame(); - }, - applyConfig: function() { - YAHOO.util.DDProxy.superclass.applyConfig.call( this ); - this.resizeFrame = ( this.config.resizeFrame !== false ); - this.centerFrame = ( this.config.centerFrame ); - this.setDragElId( this.config.dragElId || YAHOO.util.DDProxy.dragElId ); - }, - showFrame: function( E, D ) { - var C = this.getEl(); - var A = this.getDragEl(); - var B = A.style; - this._resizeProxy(); - if ( this.centerFrame ) { - this.setDelta( Math.round( parseInt( B.width, 10 ) / 2 ), Math.round( parseInt( B.height, 10 ) / 2 ) ); - } - this.setDragElPos( E, D ); - YAHOO.util.Dom.setStyle( A, "visibility", "visible" ); - }, - _resizeProxy: function() { - if ( this.resizeFrame ) { - var H = YAHOO.util.Dom; - var B = this.getEl(); - var C = this.getDragEl(); - var G = parseInt( H.getStyle( C, "borderTopWidth" ), 10 ); - var I = parseInt( H.getStyle( C, "borderRightWidth" ), 10 ); - var F = parseInt( H.getStyle( C, "borderBottomWidth" ), 10 ); - var D = parseInt( H.getStyle( C, "borderLeftWidth" ), 10 ); - if ( isNaN( G ) ) { - G = 0; - } - if ( isNaN( I ) ) { - I = 0; - } - if ( isNaN( F ) ) { - F = 0; - } - if ( isNaN( D ) ) { - D = 0; - } - var E = Math.max( 0, B.offsetWidth - I - D ); - var A = Math.max( 0, B.offsetHeight - G - F ); - H.setStyle( C, "width", E + "px" ); - H.setStyle( C, "height", A + "px" ); - } - }, - b4MouseDown: function( B ) { - this.setStartPosition(); - var A = YAHOO.util.Event.getPageX( B ); - var C = YAHOO.util.Event.getPageY( B ); - this.autoOffset( A, C ); - }, - b4StartDrag: function( A, B ) { - this.showFrame( A, B ); - }, - b4EndDrag: function( A ) { - YAHOO.util.Dom.setStyle( this.getDragEl(), "visibility", "hidden" ); - }, - endDrag: function( D ) { - var C = YAHOO.util.Dom; var B = this.getEl(); - var A = this.getDragEl(); - C.setStyle( A, "visibility", "" ); - C.setStyle( B, "visibility", "hidden" ); - YAHOO.util.DDM.moveToEl( B, A ); - C.setStyle( A, "visibility", "hidden" ); - C.setStyle( B, "visibility", "" ); - }, - toString: function() { - return ( "DDProxy " + this.id ); - } } ); -YAHOO.util.DDTarget = function( C, A, B ) { - if ( C ) { - this.initTarget( C, A, B ); - } -}; -YAHOO.extend( YAHOO.util.DDTarget, YAHOO.util.DragDrop, { - toString: function() { - return ( "DDTarget " + this.id ); - } } ); -YAHOO.register( "dragdrop", YAHOO.util.DragDropMgr, { version: "2.7.0", build: "1796" } ); -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ ( function() { - var B = YAHOO.util.Dom.getXY, - A = YAHOO.util.Event, - D = Array.prototype.slice; - - function C( G, E, F, H ) { - C.ANIM_AVAIL = ( !YAHOO.lang.isUndefined( YAHOO.util.Anim ) ); - if ( G ) { - this.init( G, E, true ); - this.initSlider( H ); - this.initThumb( F ); - } - } - YAHOO.lang.augmentObject( C, { - getHorizSlider: function( F, G, I, H, E ) { - return new C( F, F, new YAHOO.widget.SliderThumb( G, F, I, H, 0, 0, E ), "horiz" ); - }, - getVertSlider: function( G, H, E, I, F ) { - return new C( G, G, new YAHOO.widget.SliderThumb( H, G, 0, 0, E, I, F ), "vert" ); - }, - getSliderRegion: function( G, H, J, I, E, K, F ) { - return new C( G, G, new YAHOO.widget.SliderThumb( H, G, J, I, E, K, F ), "region" ); - }, - SOURCE_UI_EVENT: 1, SOURCE_SET_VALUE: 2, SOURCE_KEY_EVENT: 3, ANIM_AVAIL: false }, true ); - YAHOO.extend( C, YAHOO.util.DragDrop, { - _mouseDown: false, dragOnly: true, initSlider: function( E ) { - this.type = E; this.createEvent( "change", this ); - this.createEvent( "slideStart", this ); - this.createEvent( "slideEnd", this ); - this.isTarget = false; - this.animate = C.ANIM_AVAIL; - this.backgroundEnabled = true; - this.tickPause = 40; - this.enableKeys = true; - this.keyIncrement = 20; - this.moveComplete = true; - this.animationDuration = 0.2; - this.SOURCE_UI_EVENT = 1; - this.SOURCE_SET_VALUE = 2; - this.valueChangeSource = 0; - this._silent = false; - this.lastOffset = [ 0, 0 ]; - }, - initThumb: function( F ) { - var E = this; this.thumb = F; F.cacheBetweenDrags = true; if ( F._isHoriz && F.xTicks && F.xTicks.length ) { - this.tickPause = Math.round( 360 / F.xTicks.length ); - } else { - if ( F.yTicks && F.yTicks.length ) { - this.tickPause = Math.round( 360 / F.yTicks.length ); - } - } - F.onAvailable = function() { - return E.setStartSliderState(); - }; - F.onMouseDown = function() { - E._mouseDown = true; - return E.focus(); - }; - F.startDrag = function() { - E._slideStart(); - }; - F.onDrag = function() { - E.fireEvents( true ); - }; - F.onMouseUp = function() { - E.thumbMouseUp(); - }; - }, - onAvailable: function() { - this._bindKeyEvents(); - }, - _bindKeyEvents: function() { - A.on( this.id, "keydown", this.handleKeyDown, this, true ); - A.on( this.id, "keypress", this.handleKeyPress, this, true ); - }, - handleKeyPress: function( F ) { - if ( this.enableKeys ) { - var E = A.getCharCode( F ); - switch ( E ) { - case 37: - case 38: - case 39: - case 40: - case 36: - case 35: - A.preventDefault( F ); - break;default: - } - } - }, - handleKeyDown: function( J ) { - if ( this.enableKeys ) { - var G = A.getCharCode( J ), - F = this.thumb, - H = this.getXValue(), - E = this.getYValue(), - I = true; - switch ( G ) { - case 37: - H -= this.keyIncrement; - break;case 38: - E -= this.keyIncrement; - break;case 39: - H += this.keyIncrement; - break;case 40: - E += this.keyIncrement; - break;case 36: - H = F.leftConstraint; - E = F.topConstraint; - break;case 35: - H = F.rightConstraint; - E = F.bottomConstraint; - break;default: - I = false; - } - if ( I ) { - if ( F._isRegion ) { - this._setRegionValue( C.SOURCE_KEY_EVENT, H, E, true ); - } else { - this._setValue( C.SOURCE_KEY_EVENT, ( F._isHoriz ? H : E ), true ); - } - A.stopEvent( J ); - } - } - }, - setStartSliderState: function() { - this.setThumbCenterPoint(); - this.baselinePos = B( this.getEl() ); - this.thumb.startOffset = this.thumb.getOffsetFromParent( this.baselinePos ); - if ( this.thumb._isRegion ) { - if ( this.deferredSetRegionValue ) { - this._setRegionValue.apply( this, this.deferredSetRegionValue ); - this.deferredSetRegionValue = null; - } else { - this.setRegionValue( 0, 0, true, true, true ); - } - } else { - if ( this.deferredSetValue ) { - this._setValue.apply( this, this.deferredSetValue ); - this.deferredSetValue = null; - } else { - this.setValue( 0, true, true, true ); - } - } - }, - setThumbCenterPoint: function() { - var E = this.thumb.getEl(); - if ( E ) { - this.thumbCenterPoint = { x: parseInt( E.offsetWidth / 2, 10 ), y: parseInt( E.offsetHeight / 2, 10 ) }; - } - }, - lock: function() { - this.thumb.lock(); - this.locked = true; - }, - unlock: function() { - this.thumb.unlock(); - this.locked = false; - }, - thumbMouseUp: function() { - this._mouseDown = false; if ( !this.isLocked() && !this.moveComplete ) { - this.endMove(); - } - }, - onMouseUp: function() { - this._mouseDown = false; if ( this.backgroundEnabled && !this.isLocked() && !this.moveComplete ) { - this.endMove(); - } - }, - getThumb: function() { - return this.thumb; - }, - focus: function() { - this.valueChangeSource = C.SOURCE_UI_EVENT; var E = this.getEl(); - if ( E.focus ) { - try { - E.focus(); - } catch ( F ) {} - } - this.verifyOffset(); - return !this.isLocked(); - }, - onChange: function( E, F ) {}, - onSlideStart: function() {}, - onSlideEnd: function() {}, - getValue: function() { - return this.thumb.getValue(); - }, - getXValue: function() { - return this.thumb.getXValue(); - }, - getYValue: function() { - return this.thumb.getYValue(); - }, - setValue: function() { - var E = D.call( arguments ); - E.unshift( C.SOURCE_SET_VALUE ); - return this._setValue.apply( this, E ); - }, - _setValue: function( I, L, G, H, E ) { - var F = this.thumb, - K, J; if ( !F.available ) { - this.deferredSetValue = arguments; - return false; - } - if ( this.isLocked() && !H ) { - return false; - } - if ( isNaN( L ) ) { - return false; - } - if ( F._isRegion ) { - return false; - } - this._silent = E; - this.valueChangeSource = I || C.SOURCE_SET_VALUE; - F.lastOffset = [ L, L ]; - this.verifyOffset( true ); - this._slideStart(); - if ( F._isHoriz ) { - K = F.initPageX + L + this.thumbCenterPoint.x; - this.moveThumb( K, F.initPageY, G ); - } else { - J = F.initPageY + L + this.thumbCenterPoint.y; - this.moveThumb( F.initPageX, J, G ); - } - return true; - }, - setRegionValue: function() { - var E = D.call( arguments ); - E.unshift( C.SOURCE_SET_VALUE ); - return this._setRegionValue.apply( this, E ); - }, - _setRegionValue: function( F, J, H, I, G, K ) { - var L = this.thumb, - E, M; if ( !L.available ) { - this.deferredSetRegionValue = arguments; - return false; - } - if ( this.isLocked() && !G ) { - return false; - } - if ( isNaN( J ) ) { - return false; - } - if ( !L._isRegion ) { - return false; - } - this._silent = K; - this.valueChangeSource = F || C.SOURCE_SET_VALUE; - L.lastOffset = [ J, H ]; - this.verifyOffset( true ); - this._slideStart(); - E = L.initPageX + J + this.thumbCenterPoint.x; - M = L.initPageY + H + this.thumbCenterPoint.y; - this.moveThumb( E, M, I ); - return true; - }, - verifyOffset: function( F ) { - var G = B( this.getEl() ), - E = this.thumb; - if ( !this.thumbCenterPoint || !this.thumbCenterPoint.x ) { - this.setThumbCenterPoint(); - } - if ( G ) { - if ( G[ 0 ] != this.baselinePos[ 0 ] || G[ 1 ] != this.baselinePos[ 1 ] ) { - this.setInitPosition(); - this.baselinePos = G; - E.initPageX = this.initPageX + E.startOffset[ 0 ]; - E.initPageY = this.initPageY + E.startOffset[ 1 ]; - E.deltaSetXY = null; - this.resetThumbConstraints(); - return false; - } - } - return true; - }, - moveThumb: function( K, J, I, G ) { - var L = this.thumb, - M = this, - F, E, H; if ( !L.available ) { - return; - } - L.setDelta( this.thumbCenterPoint.x, this.thumbCenterPoint.y ); - E = L.getTargetCoord( K, J ); - F = [ Math.round( E.x ), Math.round( E.y ) ]; - if ( this.animate && L._graduated && !I ) { - this.lock(); - this.curCoord = B( this.thumb.getEl() ); - this.curCoord = [ Math.round( this.curCoord[ 0 ] ), Math.round( this.curCoord[ 1 ] ) ]; - setTimeout( function() { - M.moveOneTick( F ); - }, this.tickPause ); - } else { - if ( this.animate && C.ANIM_AVAIL && !I ) { - this.lock(); - H = new YAHOO.util.Motion( L.id, { - points: { to: F } }, this.animationDuration, YAHOO.util.Easing.easeOut ); - H.onComplete.subscribe( function() { - M.unlock(); - if ( !M._mouseDown ) { - M.endMove(); - } - }); - H.animate(); - } else { - L.setDragElPos( K, J ); - if ( !G && !this._mouseDown ) { - this.endMove(); - } - } - } - }, - _slideStart: function() { - if ( !this._sliding ) { - if ( !this._silent ) { - this.onSlideStart(); - this.fireEvent( "slideStart" ); - } - this._sliding = true; - } - }, - _slideEnd: function() { - if ( this._sliding && this.moveComplete ) { - var E = this._silent; - this._sliding = false; - this._silent = false; - this.moveComplete = false; - if ( !E ) { - this.onSlideEnd(); - this.fireEvent( "slideEnd" ); - } - } - }, - moveOneTick: function( F ) { - var H = this.thumb, - G = this, - I = null, - E, J; if ( H._isRegion ) { - I = this._getNextX( this.curCoord, F ); - E = ( I !== null ) ? I[ 0 ] : this.curCoord[ 0 ]; - I = this._getNextY( this.curCoord, F ); - J = ( I !== null ) ? I[ 1 ] : this.curCoord[ 1 ]; - I = E !== this.curCoord[ 0 ] || J !== this.curCoord[ 1 ] ? [ E, J ] : null; - } else { - if ( H._isHoriz ) { - I = this._getNextX( this.curCoord, F ); - } else { - I = this._getNextY( this.curCoord, F ); - } - } - if ( I ) { - this.curCoord = I; - this.thumb.alignElWithMouse( H.getEl(), I[ 0 ] + this.thumbCenterPoint.x, I[ 1 ] + this.thumbCenterPoint.y ); - if ( !( I[ 0 ] == F[ 0 ] && I[ 1 ] == F[ 1 ] ) ) { - setTimeout( function() { - G.moveOneTick( F ); - }, this.tickPause ); - } else { - this.unlock(); - if ( !this._mouseDown ) { - this.endMove(); - } - } - } else { - this.unlock(); - if ( !this._mouseDown ) { - this.endMove(); - } - } - }, - _getNextX: function( E, F ) { - var H = this.thumb, - J, - G = [], - I = null; - if ( E[ 0 ] > F[ 0 ] ) { - J = H.tickSize - this.thumbCenterPoint.x; - G = H.getTargetCoord( E[ 0 ] - J, E[ 1 ] ); - I = [ G.x, G.y ]; - } else { - if ( E[ 0 ] < F[ 0 ] ) { - J = H.tickSize + this.thumbCenterPoint.x; - G = H.getTargetCoord( E[ 0 ] + J, E[ 1 ] ); - I = [ G.x, G.y ]; - } else {} - } - return I; - }, - _getNextY: function( E, F ) { - var H = this.thumb, - J, - G = [], - I = null; - if ( E[ 1 ] > F[ 1 ] ) { - J = H.tickSize - this.thumbCenterPoint.y; - G = H.getTargetCoord( E[ 0 ], E[ 1 ] - J ); - I = [ G.x, G.y ]; - } else { - if ( E[ 1 ] < F[ 1 ] ) { - J = H.tickSize + this.thumbCenterPoint.y; - G = H.getTargetCoord( E[ 0 ], E[ 1 ] + J ); - I = [ G.x, G.y ]; - } else {} - } - return I; - }, - b4MouseDown: function( E ) { - if ( !this.backgroundEnabled ) { - return false; - } - this.thumb.autoOffset(); - this.resetThumbConstraints(); - }, - onMouseDown: function( F ) { - if ( !this.backgroundEnabled || this.isLocked() ) { - return false; - } - this._mouseDown = true; - var E = A.getPageX( F ), - G = A.getPageY( F ); - this.focus(); - this._slideStart(); - this.moveThumb( E, G ); - }, - onDrag: function( F ) { - if ( this.backgroundEnabled && !this.isLocked() ) { - var E = A.getPageX( F ), - G = A.getPageY( F ); - this.moveThumb( E, G, true, true ); - this.fireEvents(); - } - }, - endMove: function() { - this.unlock(); - this.fireEvents(); - this.moveComplete = true; - this._slideEnd(); - }, - resetThumbConstraints: function() { - var E = this.thumb; E.setXConstraint( E.leftConstraint, E.rightConstraint, E.xTickSize ); - E.setYConstraint( E.topConstraint, E.bottomConstraint, E.xTickSize ); - }, - fireEvents: function( G ) { - var F = this.thumb, - I, H, E; if ( !G ) { - F.cachePosition(); - } - if ( !this.isLocked() ) { - if ( F._isRegion ) { - I = F.getXValue(); - H = F.getYValue(); - if ( I != this.previousX || H != this.previousY ) { - if ( !this._silent ) { - this.onChange( I, H ); - this.fireEvent( "change", { x: I, y: H } ); - } - } - this.previousX = I; - this.previousY = H; - } else { - E = F.getValue(); - if ( E != this.previousVal ) { - if ( !this._silent ) { - this.onChange( E ); - this.fireEvent( "change", E ); - } - } - this.previousVal = E; - } - } - }, - toString: function() { - return ( "Slider (" + this.type + ") " + this.id ); - } } ); - YAHOO.lang.augmentProto( C, YAHOO.util.EventProvider ); - YAHOO.widget.Slider = C; -})(); -YAHOO.widget.SliderThumb = function( G, B, E, D, A, F, C ) { - if ( G ) { - YAHOO.widget.SliderThumb.superclass.constructor.call( this, G, B ); - this.parentElId = B; - } - this.isTarget = false; - this.tickSize = C; - this.maintainOffset = true; - this.initSlider( E, D, A, F, C ); - this.scroll = false; -}; -YAHOO.extend( YAHOO.widget.SliderThumb, YAHOO.util.DD, { - startOffset: null, dragOnly: true, _isHoriz: false, _prevVal: 0, _graduated: false, getOffsetFromParent0: function( C ) { - var A = YAHOO.util.Dom.getXY( this.getEl() ), - B = C || YAHOO.util.Dom.getXY( this.parentElId ); - return [ ( A[ 0 ] - B[ 0 ] ), ( A[ 1 ] - B[ 1 ] ) ]; - }, - getOffsetFromParent: function( H ) { - var A = this.getEl(), - E, I, F, B, K, D, C, J, G; - if ( !this.deltaOffset ) { - I = YAHOO.util.Dom.getXY( A ); - F = H || YAHOO.util.Dom.getXY( this.parentElId ); - E = [ ( I[ 0 ] - F[ 0 ] ), ( I[ 1 ] - F[ 1 ] ) ]; - B = parseInt( YAHOO.util.Dom.getStyle( A, "left" ), 10 ); - K = parseInt( YAHOO.util.Dom.getStyle( A, "top" ), 10 ); - D = B - E[ 0 ]; - C = K - E[ 1 ]; - if ( isNaN( D ) || isNaN( C ) ) {} else { - this.deltaOffset = [ D, C ]; - } - } else { - J = parseInt( YAHOO.util.Dom.getStyle( A, "left" ), 10 ); - G = parseInt( YAHOO.util.Dom.getStyle( A, "top" ), 10 ); - E = [ J + this.deltaOffset[ 0 ], G + this.deltaOffset[ 1 ] ]; - } - return E; - }, - initSlider: function( D, C, A, E, B ) { - this.initLeft = D; this.initRight = C; this.initUp = A; this.initDown = E; this.setXConstraint( D, C, B ); - this.setYConstraint( A, E, B ); - if ( B && B > 1 ) { - this._graduated = true; - } - this._isHoriz = ( D || C ); - this._isVert = ( A || E ); - this._isRegion = ( this._isHoriz && this._isVert ); - }, - clearTicks: function() { - YAHOO.widget.SliderThumb.superclass.clearTicks.call( this ); - this.tickSize = 0; - this._graduated = false; - }, - getValue: function() { - return ( this._isHoriz ) ? this.getXValue() : this.getYValue(); - }, - getXValue: function() { - if ( !this.available ) { - return 0; - } - var A = this.getOffsetFromParent(); - if ( YAHOO.lang.isNumber( A[ 0 ] ) ) { - this.lastOffset = A; - return ( A[ 0 ] - this.startOffset[ 0 ] ); - } else { - return ( this.lastOffset[ 0 ] - this.startOffset[ 0 ] ); - } - }, - getYValue: function() { - if ( !this.available ) { - return 0; - } - var A = this.getOffsetFromParent(); - if ( YAHOO.lang.isNumber( A[ 1 ] ) ) { - this.lastOffset = A; - return ( A[ 1 ] - this.startOffset[ 1 ] ); - } else { - return ( this.lastOffset[ 1 ] - this.startOffset[ 1 ] ); - } - }, - toString: function() { - return "SliderThumb " + this.id; - }, - onChange: function( A, B ) {} } ); -(function() { - var A = YAHOO.util.Event, - B = YAHOO.widget; - - function C( I, F, H, D ) { - var G = this, - J = { min: false, max: false }, - E, K; this.minSlider = I; this.maxSlider = F; this.activeSlider = I; this.isHoriz = I.thumb._isHoriz; E = this.minSlider.thumb.onMouseDown; K = this.maxSlider.thumb.onMouseDown; this.minSlider.thumb.onMouseDown = function() { - G.activeSlider = G.minSlider; - E.apply( this, arguments ); - }; - this.maxSlider.thumb.onMouseDown = function() { - G.activeSlider = G.maxSlider; - K.apply( this, arguments ); - }; - this.minSlider.thumb.onAvailable = function() { - I.setStartSliderState(); - J.min = true; - if ( J.max ) { - G.fireEvent( "ready", G ); - } - }; - this.maxSlider.thumb.onAvailable = function() { - F.setStartSliderState(); - J.max = true; - if ( J.min ) { - G.fireEvent( "ready", G ); - } - }; - I.onMouseDown = F.onMouseDown = function( L ) { - return this.backgroundEnabled && G._handleMouseDown( L ); - }; - I.onDrag = F.onDrag = function( L ) { - G._handleDrag( L ); - }; - I.onMouseUp = F.onMouseUp = function( L ) { - G._handleMouseUp( L ); - }; - I._bindKeyEvents = function() { - G._bindKeyEvents( this ); - }; - F._bindKeyEvents = function() {}; - I.subscribe( "change", this._handleMinChange, I, this ); - I.subscribe( "slideStart", this._handleSlideStart, I, this ); - I.subscribe( "slideEnd", this._handleSlideEnd, I, this ); - F.subscribe( "change", this._handleMaxChange, F, this ); - F.subscribe( "slideStart", this._handleSlideStart, F, this ); - F.subscribe( "slideEnd", this._handleSlideEnd, F, this ); - this.createEvent( "ready", this ); - this.createEvent( "change", this ); - this.createEvent( "slideStart", this ); - this.createEvent( "slideEnd", this ); - D = YAHOO.lang.isArray( D ) ? D : [ 0, H ]; - D[ 0 ] = Math.min( Math.max( parseInt( D[ 0 ], 10 ) | 0, 0 ), H ); - D[ 1 ] = Math.max( Math.min( parseInt( D[ 1 ], 10 ) | 0, H ), 0 ); - if ( D[ 0 ] > D[ 1 ] ) { - D.splice( 0, 2, D[ 1 ], D[ 0 ] ); - } - this.minVal = D[ 0 ]; - this.maxVal = D[ 1 ]; - this.minSlider.setValue( this.minVal, true, true, true ); - this.maxSlider.setValue( this.maxVal, true, true, true ); - } - C.prototype = { - minVal: -1, maxVal: -1, minRange: 0, _handleSlideStart: function( E, D ) { - this.fireEvent( "slideStart", D ); - }, - _handleSlideEnd: function( E, D ) { - this.fireEvent( "slideEnd", D ); - }, - _handleDrag: function( D ) { - B.Slider.prototype.onDrag.call( this.activeSlider, D ); - }, - _handleMinChange: function() { - this.activeSlider = this.minSlider; this.updateValue(); - }, - _handleMaxChange: function() { - this.activeSlider = this.maxSlider; this.updateValue(); - }, - _bindKeyEvents: function( D ) { - A.on( D.id, "keydown", this._handleKeyDown, this, true ); - A.on( D.id, "keypress", this._handleKeyPress, this, true ); - }, - _handleKeyDown: function( D ) { - this.activeSlider.handleKeyDown.apply( this.activeSlider, arguments ); - }, - _handleKeyPress: function( D ) { - this.activeSlider.handleKeyPress.apply( this.activeSlider, arguments ); - }, - setValues: function( H, K, I, E, J ) { - var F = this.minSlider, - M = this.maxSlider, - D = F.thumb, - L = M.thumb, - N = this, - G = { min: false, max: false }; if ( D._isHoriz ) { - D.setXConstraint( D.leftConstraint, L.rightConstraint, D.tickSize ); - L.setXConstraint( D.leftConstraint, L.rightConstraint, L.tickSize ); - } else { - D.setYConstraint( D.topConstraint, L.bottomConstraint, D.tickSize ); - L.setYConstraint( D.topConstraint, L.bottomConstraint, L.tickSize ); - } - this._oneTimeCallback( F, "slideEnd", function() { - G.min = true; - if ( G.max ) { - N.updateValue( J ); - setTimeout( function() { - N._cleanEvent( F, "slideEnd" ); - N._cleanEvent( M, "slideEnd" ); - }, 0 ); - } - }); - this._oneTimeCallback( M, "slideEnd", function() { - G.max = true; - if ( G.min ) { - N.updateValue( J ); - setTimeout( function() { - N._cleanEvent( F, "slideEnd" ); - N._cleanEvent( M, "slideEnd" ); - }, 0 ); - } - }); - F.setValue( H, I, E, false ); - M.setValue( K, I, E, false ); - }, - setMinValue: function( F, H, I, E ) { - var G = this.minSlider, - D = this; this.activeSlider = G; D = this; this._oneTimeCallback( G, "slideEnd", function() { - D.updateValue( E ); - setTimeout( function() { - D._cleanEvent( G, "slideEnd" ); - }, 0 ); - }); - G.setValue( F, H, I ); - }, - setMaxValue: function( D, H, I, F ) { - var G = this.maxSlider, - E = this; this.activeSlider = G; this._oneTimeCallback( G, "slideEnd", function() { - E.updateValue( F ); - setTimeout( function() { - E._cleanEvent( G, "slideEnd" ); - }, 0 ); - }); - G.setValue( D, H, I ); - }, - updateValue: function( J ) { - var E = this.minSlider.getValue(), - K = this.maxSlider.getValue(), - F = false, - D, M, H, I, L, G; - if ( E != this.minVal || K != this.maxVal ) { - F = true; - D = this.minSlider.thumb; - M = this.maxSlider.thumb; - H = this.isHoriz ? "x" : "y"; - G = this.minSlider.thumbCenterPoint[ H ] + this.maxSlider.thumbCenterPoint[ H ]; - I = Math.max( K - G - this.minRange, 0 ); - L = Math.min( -E - G - this.minRange, 0 ); - if ( this.isHoriz ) { - I = Math.min( I, M.rightConstraint ); - D.setXConstraint( D.leftConstraint, I, D.tickSize ); - M.setXConstraint( L, M.rightConstraint, M.tickSize ); - } else { - I = Math.min( I, M.bottomConstraint ); - D.setYConstraint( D.leftConstraint, I, D.tickSize ); - M.setYConstraint( L, M.bottomConstraint, M.tickSize ); - } - } - this.minVal = E; - this.maxVal = K; - if ( F && !J ) { - this.fireEvent( "change", this ); - } - }, - selectActiveSlider: function( H ) { - var E = this.minSlider, - D = this.maxSlider, - J = E.isLocked() || !E.backgroundEnabled, - G = D.isLocked() || !E.backgroundEnabled, - F = YAHOO.util.Event, - I; - if ( J || G ) { - this.activeSlider = J ? D : E; - } else { - if ( this.isHoriz ) { - I = F.getPageX( H ) - E.thumb.initPageX - E.thumbCenterPoint.x; - } else { - I = F.getPageY( H ) - E.thumb.initPageY - E.thumbCenterPoint.y; - } - this.activeSlider = I * 2 > D.getValue() + E.getValue() ? D : E; - } - }, - _handleMouseDown: function( D ) { - if ( !D._handled ) { - D._handled = true; - this.selectActiveSlider( D ); - return B.Slider.prototype.onMouseDown.call( this.activeSlider, D ); - } else { - return false; - } - }, - _handleMouseUp: function( D ) { - B.Slider.prototype.onMouseUp.apply( this.activeSlider, arguments ); - }, - _oneTimeCallback: function( F, D, E ) { - F.subscribe( D, function() { - F.unsubscribe( D, arguments.callee ); - E.apply( {}, [].slice.apply( arguments ) ); - }); - }, - _cleanEvent: function( K, E ) { - var J, I, D, G, H, F; if ( K.__yui_events && K.events[ E ] ) { - for ( I = K.__yui_events.length; I >= 0; --I ) { - if ( K.__yui_events[ I ].type === E ) { - J = K.__yui_events[ I ]; - break; - } - } - if ( J ) { - H = J.subscribers; - F = []; - G = 0; - for ( I = 0, D = H.length; I < D; ++I ) { - if ( H[ I ] ) { - F[ G++ ] = H[ I ]; - } - } - J.subscribers = F; - } - } - } }; YAHOO.lang.augmentProto( C, YAHOO.util.EventProvider ); - B.Slider.getHorizDualSlider = function( H, J, K, G, F, D ) { - var I = new B.SliderThumb( J, H, 0, G, 0, 0, F ), - E = new B.SliderThumb( K, H, 0, G, 0, 0, F ); - return new C( new B.Slider( H, H, I, "horiz" ), new B.Slider( H, H, E, "horiz" ), G, D ); - }; - B.Slider.getVertDualSlider = function( H, J, K, G, F, D ) { - var I = new B.SliderThumb( J, H, 0, 0, 0, G, F ), - E = new B.SliderThumb( K, H, 0, 0, 0, G, F ); - return new B.DualSlider( new B.Slider( H, H, I, "vert" ), new B.Slider( H, H, E, "vert" ), G, D ); - }; - YAHOO.widget.DualSlider = C; -})(); -YAHOO.register( "slider", YAHOO.widget.Slider, { version: "2.7.0", build: "1796" } ); -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -YAHOO.util.Attribute = function( B, A ) { - if ( A ) { - this.owner = A; - this.configure( B, true ); - } -}; -YAHOO.util.Attribute.prototype = { - name: undefined, value: null, owner: null, readOnly: false, writeOnce: false, _initialConfig: null, _written: false, method: null, setter: null, getter: null, validator: null, getValue: function() { - var A = this.value; if ( this.getter ) { - A = this.getter.call( this.owner, this.name ); - } - return A; - }, - setValue: function( F, B ) { - var E, - A = this.owner, - C = this.name; var D = { type: C, prevValue: this.getValue(), newValue: F }; if ( this.readOnly || ( this.writeOnce && this._written ) ) { - return false; - } - if ( this.validator && !this.validator.call( A, F ) ) { - return false; - } - if ( !B ) { - E = A.fireBeforeChangeEvent( D ); - if ( E === false ) { - return false; - } - } - if ( this.setter ) { - F = this.setter.call( A, F, this.name ); - if ( F === undefined ) {} - } - if ( this.method ) { - this.method.call( A, F, this.name ); - } - this.value = F; - this._written = true; - D.type = C; - if ( !B ) { - this.owner.fireChangeEvent( D ); - } - return true; - }, - configure: function( B, C ) { - B = B || {}; - if ( C ) { - this._written = false; - } - this._initialConfig = this._initialConfig || {}; - for ( var A in B ) { - if ( B.hasOwnProperty( A ) ) { - this[ A ] = B[ A ]; - if ( C ) { - this._initialConfig[ A ] = B[ A ]; - } - } - } - }, - resetValue: function() { - return this.setValue( this._initialConfig.value ); - }, - resetConfig: function() { - this.configure( this._initialConfig, true ); - }, - refresh: function( A ) { - this.setValue( this.value, A ); - } }; -(function() { - var A = YAHOO.util.Lang; - YAHOO.util.AttributeProvider = function() {}; - YAHOO.util.AttributeProvider.prototype = { - _configs: null, get: function( C ) { - this._configs = this._configs || {}; - var B = this._configs[ C ]; - if ( !B || !this._configs.hasOwnProperty( C ) ) { - return null; - } - return B.getValue(); - }, - set: function( D, E, B ) { - this._configs = this._configs || {}; - var C = this._configs[ D ]; - if ( !C ) { - return false; - } - return C.setValue( E, B ); - }, - getAttributeKeys: function() { - this._configs = this._configs; var C = [], - B; - for ( B in this._configs ) { - if ( A.hasOwnProperty( this._configs, B ) && !A.isUndefined( this._configs[ B ] ) ) { - C[ C.length ] = B; - } - } - return C; - }, - setAttributes: function( D, B ) { - for ( var C in D ) { - if ( A.hasOwnProperty( D, C ) ) { - this.set( C, D[ C ], B ); - } - } - }, - resetValue: function( C, B ) { - this._configs = this._configs || {}; - if ( this._configs[ C ] ) { - this.set( C, this._configs[ C ]._initialConfig.value, B ); - return true; - } - return false; - }, - refresh: function( E, C ) { - this._configs = this._configs || {}; - var F = this._configs; - E = ( ( A.isString( E ) ) ? [ E ] : E ) || this.getAttributeKeys(); - for ( var D = 0, B = E.length; D < B; ++D ) { - if ( F.hasOwnProperty( E[ D ] ) ) { - this._configs[ E[ D ] ].refresh( C ); - } - } - }, - register: function( B, C ) { - this.setAttributeConfig( B, C ); - }, - getAttributeConfig: function( C ) { - this._configs = this._configs || {}; - var B = this._configs[ C ] || {}; - var D = {}; - for ( C in B ) { - if ( A.hasOwnProperty( B, C ) ) { - D[ C ] = B[ C ]; - } - } - return D; - }, - setAttributeConfig: function( B, C, D ) { - this._configs = this._configs || {}; - C = C || {}; - if ( !this._configs[ B ] ) { - C.name = B; - this._configs[ B ] = this.createAttribute( C ); - } else { - this._configs[ B ].configure( C, D ); - } - }, - configureAttribute: function( B, C, D ) { - this.setAttributeConfig( B, C, D ); - }, - resetAttributeConfig: function( B ) { - this._configs = this._configs || {}; - this._configs[ B ].resetConfig(); - }, - subscribe: function( B, C ) { - this._events = this._events || {}; - if ( !( B in this._events ) ) { - this._events[ B ] = this.createEvent( B ); - } - YAHOO.util.EventProvider.prototype.subscribe.apply( this, arguments ); - }, - on: function() { - this.subscribe.apply( this, arguments ); - }, - addListener: function() { - this.subscribe.apply( this, arguments ); - }, - fireBeforeChangeEvent: function( C ) { - var B = "before"; B += C.type.charAt( 0 ).toUpperCase() + C.type.substr( 1 ) + "Change"; - C.type = B; - return this.fireEvent( C.type, C ); - }, - fireChangeEvent: function( B ) { - B.type += "Change"; return this.fireEvent( B.type, B ); - }, - createAttribute: function( B ) { - return new YAHOO.util.Attribute( B, this ); - } }; YAHOO.augment( YAHOO.util.AttributeProvider, YAHOO.util.EventProvider ); -})(); -(function() { - var B = YAHOO.util.Dom, - C = YAHOO.util.AttributeProvider; - var A = function( D, E ) { - this.init.apply( this, arguments ); - }; - A.DOM_EVENTS = { "click": true, "dblclick": true, "keydown": true, "keypress": true, "keyup": true, "mousedown": true, "mousemove": true, "mouseout": true, "mouseover": true, "mouseup": true, "focus": true, "blur": true, "submit": true, "change": true }; A.prototype = { - DOM_EVENTS: null, DEFAULT_HTML_SETTER: function( F, D ) { - var E = this.get( "element" ); - if ( E ) { - E[ D ] = F; - } - }, - DEFAULT_HTML_GETTER: function( D ) { - var E = this.get( "element" ), - F; - if ( E ) { - F = E[ D ]; - } - return F; - }, - appendChild: function( D ) { - D = D.get ? D.get( "element" ) : D; - return this.get( "element" ).appendChild( D ); - }, - getElementsByTagName: function( D ) { - return this.get( "element" ).getElementsByTagName( D ); - }, - hasChildNodes: function() { - return this.get( "element" ).hasChildNodes(); - }, - insertBefore: function( D, E ) { - D = D.get ? D.get( "element" ) : D; - E = ( E && E.get ) ? E.get( "element" ) : E; - return this.get( "element" ).insertBefore( D, E ); - }, - removeChild: function( D ) { - D = D.get ? D.get( "element" ) : D; - return this.get( "element" ).removeChild( D ); - }, - replaceChild: function( D, E ) { - D = D.get ? D.get( "element" ) : D; - E = E.get ? E.get( "element" ) : E; - return this.get( "element" ).replaceChild( D, E ); - }, - initAttributes: function( D ) {}, - addListener: function( H, G, I, F ) { - var E = this.get( "element" ) || this.get( "id" ); - F = F || this; - var D = this; - if ( !this._events[ H ] ) { - if ( E && this.DOM_EVENTS[ H ] ) { - YAHOO.util.Event.addListener( E, H, function( J ) { - if ( J.srcElement && !J.target ) { - J.target = J.srcElement; - } - D.fireEvent( H, J ); - }, I, F ); - } - this.createEvent( H, this ); - } - return YAHOO.util.EventProvider.prototype.subscribe.apply( this, arguments ); - }, - on: function() { - return this.addListener.apply( this, arguments ); - }, - subscribe: function() { - return this.addListener.apply( this, arguments ); - }, - removeListener: function( E, D ) { - return this.unsubscribe.apply( this, arguments ); - }, - addClass: function( D ) { - B.addClass( this.get( "element" ), D ); - }, - getElementsByClassName: function( E, D ) { - return B.getElementsByClassName( E, D, this.get( "element" ) ); - }, - hasClass: function( D ) { - return B.hasClass( this.get( "element" ), D ); - }, - removeClass: function( D ) { - return B.removeClass( this.get( "element" ), D ); - }, - replaceClass: function( E, D ) { - return B.replaceClass( this.get( "element" ), E, D ); - }, - setStyle: function( E, D ) { - return B.setStyle( this.get( "element" ), E, D ); - }, - getStyle: function( D ) { - return B.getStyle( this.get( "element" ), D ); - }, - fireQueue: function() { - var E = this._queue; for ( var F = 0, D = E.length; F < D; ++F ) { - this[ E[ F ][ 0 ] ].apply( this, E[ F ][ 1 ] ); - } - }, - appendTo: function( E, F ) { - E = ( E.get ) ? E.get( "element" ) : B.get( E ); - this.fireEvent( "beforeAppendTo", { type: "beforeAppendTo", target: E } ); - F = ( F && F.get ) ? F.get( "element" ) : B.get( F ); - var D = this.get( "element" ); - if ( !D ) { - return false; - } - if ( !E ) { - return false; - } - if ( D.parent != E ) { - if ( F ) { - E.insertBefore( D, F ); - } else { - E.appendChild( D ); - } - } - this.fireEvent( "appendTo", { type: "appendTo", target: E } ); - return D; - }, - get: function( D ) { - var F = this._configs || {}, - E = F.element; - if ( E && !F[ D ] && !YAHOO.lang.isUndefined( E.value[ D ] ) ) { - this._setHTMLAttrConfig( D ); - } - return C.prototype.get.call( this, D ); - }, - setAttributes: function( J, G ) { - var E = {}, - H = this._configOrder; - for ( var I = 0, D = H.length; I < D; ++I ) { - if ( J[ H[ I ] ] !== undefined ) { - E[ H[ I ] ] = true; - this.set( H[ I ], J[ H[ I ] ], G ); - } - } - for ( var F in J ) { - if ( J.hasOwnProperty( F ) && !E[ F ] ) { - this.set( F, J[ F ], G ); - } - } - }, - set: function( E, G, D ) { - var F = this.get( "element" ); - if ( !F ) { - this._queue[ this._queue.length ] = [ "set", arguments ]; - if ( this._configs[ E ] ) { - this._configs[ E ].value = G; - } - return; - } - if ( !this._configs[ E ] && !YAHOO.lang.isUndefined( F[ E ] ) ) { - this._setHTMLAttrConfig( E ); - } - return C.prototype.set.apply( this, arguments ); - }, - setAttributeConfig: function( D, E, F ) { - this._configOrder.push( D ); - C.prototype.setAttributeConfig.apply( this, arguments ); - }, - createEvent: function( E, D ) { - this._events[ E ] = true; - return C.prototype.createEvent.apply( this, arguments ); - }, - init: function( E, D ) { - this._initElement( E, D ); - }, - destroy: function() { - var D = this.get( "element" ); - YAHOO.util.Event.purgeElement( D, true ); - this.unsubscribeAll(); - if ( D && D.parentNode ) { - D.parentNode.removeChild( D ); - } - this._queue = []; - this._events = {}; - this._configs = {}; - this._configOrder = []; - }, - _initElement: function( F, E ) { - this._queue = this._queue || []; - this._events = this._events || {}; - this._configs = this._configs || {}; - this._configOrder = []; - E = E || {}; - E.element = E.element || F || null; - var H = false; - var D = A.DOM_EVENTS; - this.DOM_EVENTS = this.DOM_EVENTS || {}; - for ( var G in D ) { - if ( D.hasOwnProperty( G ) ) { - this.DOM_EVENTS[ G ] = D[ G ]; - } - } - if ( typeof E.element === "string" ) { - this._setHTMLAttrConfig( "id", { value: E.element } ); - } - if ( B.get( E.element ) ) { - H = true; - this._initHTMLElement( E ); - this._initContent( E ); - } - YAHOO.util.Event.onAvailable( E.element, function() { - if ( !H ) { - this._initHTMLElement( E ); - } - this.fireEvent( "available", { type: "available", target: B.get( E.element ) } ); - }, this, true ); - YAHOO.util.Event.onContentReady( E.element, function() { - if ( !H ) { - this._initContent( E ); - } - this.fireEvent( "contentReady", { type: "contentReady", target: B.get( E.element ) } ); - }, this, true ); - }, - _initHTMLElement: function( D ) { - this.setAttributeConfig( "element", { value: B.get( D.element ), readOnly: true } ); - }, - _initContent: function( D ) { - this.initAttributes( D ); - this.setAttributes( D, true ); - this.fireQueue(); - }, - _setHTMLAttrConfig: function( D, F ) { - var E = this.get( "element" ); - F = F || {}; - F.name = D; - F.setter = F.setter || this.DEFAULT_HTML_SETTER; - F.getter = F.getter || this.DEFAULT_HTML_GETTER; - F.value = F.value || E[ D ]; - this._configs[ D ] = new YAHOO.util.Attribute( F, this ); - } }; YAHOO.augment( A, C ); - YAHOO.util.Element = A; -})(); -YAHOO.register( "element", YAHOO.util.Element, { version: "2.7.0", build: "1796" } ); -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -YAHOO.util.Color = function() { - var A = "0", - B = YAHOO.lang.isArray, - C = YAHOO.lang.isNumber; - return { - real2dec: function( D ) { - return Math.min( 255, Math.round( D * 256 ) ); - }, - hsv2rgb: function( H, O, M ) { - if ( B( H ) ) { - return this.hsv2rgb.call( this, H[ 0 ], H[ 1 ], H[ 2 ] ); - } - var D, I, L, - G = Math.floor( ( H / 60 ) % 6 ), - J = ( H / 60 ) - G, - F = M * ( 1 - O ), - E = M * ( 1 - J * O ), - N = M * ( 1 - ( 1 - J ) * O ), - K; - switch ( G ) { - case 0: - D = M; - I = N; - L = F; - break;case 1: - D = E; - I = M; - L = F; - break;case 2: - D = F; - I = M; - L = N; - break;case 3: - D = F; - I = E; - L = M; - break;case 4: - D = N; - I = F; - L = M; - break;case 5: - D = M; - I = F; - L = E; - break; - } - K = this.real2dec; - return [ K( D ), K( I ), K( L ) ]; - }, - rgb2hsv: function( D, H, I ) { - if ( B( D ) ) { - return this.rgb2hsv.apply( this, D ); - } - D /= 255; - H /= 255; - I /= 255; - var G, L, - E = Math.min( Math.min( D, H ), I ), - J = Math.max( Math.max( D, H ), I ), - K = J - E, - F; - switch ( J ) { - case E: - G = 0; - break;case D: - G = 60 * ( H - I ) / K; - if ( H < I ) { - G += 360; - } - break;case H: - G = ( 60 * ( I - D ) / K ) + 120; - break;case I: - G = ( 60 * ( D - H ) / K ) + 240; - break; - } - L = ( J === 0 ) ? 0 : 1 - ( E / J ); - F = [ Math.round( G ), L, J ]; - return F; - }, - rgb2hex: function( F, E, D ) { - if ( B( F ) ) { - return this.rgb2hex.apply( this, F ); - } - var G = this.dec2hex; - return G( F ) + G( E ) + G( D ); - }, - dec2hex: function( D ) { - D = parseInt( D, 10 ) | 0; - D = ( D > 255 || D < 0 ) ? 0 : D; - return ( A + D.toString( 16 ) ).slice( -2 ).toUpperCase(); - }, - hex2dec: function( D ) { - return parseInt( D, 16 ); - }, - hex2rgb: function( D ) { - var E = this.hex2dec; return [ E( D.slice( 0, 2 ) ), E( D.slice( 2, 4 ) ), E( D.slice( 4, 6 ) ) ]; - }, - websafe: function( F, E, D ) { - if ( B( F ) ) { - return this.websafe.apply( this, F ); - } - var G = function( H ) { - if ( C( H ) ) { - H = Math.min( Math.max( 0, H ), 255 ); - var I, J; - for ( I = 0; I < 256; I = I + 51 ) { - J = I + 51; - if ( H >= I && H <= J ) { - return ( H - I > 25 ) ? J : I; - } - } - } - return H; - }; - return [ G( F ), G( E ), G( D ) ]; - } }; -}(); -(function() { - var J = 0, - F = YAHOO.util, - C = YAHOO.lang, - D = YAHOO.widget.Slider, - B = F.Color, - E = F.Dom, - I = F.Event, - A = C.substitute, - H = "yui-picker"; - - function G( L, K ) { - J = J + 1; - K = K || {}; - if ( arguments.length === 1 && !YAHOO.lang.isString( L ) && !L.nodeName ) { - K = L; - L = K.element || null; - } - if ( !L && !K.element ) { - L = this._createHostElement( K ); - } - G.superclass.constructor.call( this, L, K ); - this.initPicker(); - } - YAHOO.extend( G, YAHOO.util.Element, { - ID: { R: H + "-r", R_HEX: H + "-rhex", G: H + "-g", G_HEX: H + "-ghex", B: H + "-b", B_HEX: H + "-bhex", H: H + "-h", S: H + "-s", V: H + "-v", PICKER_BG: H + "-bg", PICKER_THUMB: H + "-thumb", HUE_BG: H + "-hue-bg", HUE_THUMB: H + "-hue-thumb", HEX: H + "-hex", SWATCH: H + "-swatch", WEBSAFE_SWATCH: H + "-websafe-swatch", CONTROLS: H + "-controls", RGB_CONTROLS: H + "-rgb-controls", HSV_CONTROLS: H + "-hsv-controls", HEX_CONTROLS: H + "-hex-controls", HEX_SUMMARY: H + "-hex-summary", CONTROLS_LABEL: H + "-controls-label" }, - TXT: { ILLEGAL_HEX: "Illegal hex value entered", SHOW_CONTROLS: "Show color details", HIDE_CONTROLS: "Hide color details", CURRENT_COLOR: "Currently selected color: {rgb}", CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.", R: "R", G: "G", B: "B", H: "H", S: "S", V: "V", HEX: "#", DEG: "\u00B0", PERCENT: "%" }, - IMAGE: { PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png", HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png" }, - DEFAULT: { PICKER_SIZE: 180 }, - OPT: { HUE: "hue", SATURATION: "saturation", VALUE: "value", RED: "red", GREEN: "green", BLUE: "blue", HSV: "hsv", RGB: "rgb", WEBSAFE: "websafe", HEX: "hex", PICKER_SIZE: "pickersize", SHOW_CONTROLS: "showcontrols", SHOW_RGB_CONTROLS: "showrgbcontrols", SHOW_HSV_CONTROLS: "showhsvcontrols", SHOW_HEX_CONTROLS: "showhexcontrols", SHOW_HEX_SUMMARY: "showhexsummary", SHOW_WEBSAFE: "showwebsafe", CONTAINER: "container", IDS: "ids", ELEMENTS: "elements", TXT: "txt", IMAGES: "images", ANIMATE: "animate" }, - skipAnim: true, _createHostElement: function() { - var K = document.createElement( "div" ); - if ( this.CSS.BASE ) { - K.className = this.CSS.BASE; - } - return K; - }, - _updateHueSlider: function() { - var K = this.get( this.OPT.PICKER_SIZE ), - L = this.get( this.OPT.HUE ); - L = K - Math.round( L / 360 * K ); - if ( L === K ) { - L = 0; - } - this.hueSlider.setValue( L, this.skipAnim ); - }, - _updatePickerSlider: function() { - var L = this.get( this.OPT.PICKER_SIZE ), - M = this.get( this.OPT.SATURATION ), - K = this.get( this.OPT.VALUE ); - M = Math.round( M * L / 100 ); - K = Math.round( L - ( K * L / 100 ) ); - this.pickerSlider.setRegionValue( M, K, this.skipAnim ); - }, - _updateSliders: function() { - this._updateHueSlider(); - this._updatePickerSlider(); - }, - setValue: function( L, K ) { - K = ( K ) || false; - this.set( this.OPT.RGB, L, K ); - this._updateSliders(); - }, - hueSlider: null, pickerSlider: null, _getH: function() { - var K = this.get( this.OPT.PICKER_SIZE ), - L = ( K - this.hueSlider.getValue() ) / K; - L = Math.round( L * 360 ); - return ( L === 360 ) ? 0 : L; - }, - _getS: function() { - return this.pickerSlider.getXValue() / this.get( this.OPT.PICKER_SIZE ); - }, - _getV: function() { - var K = this.get( this.OPT.PICKER_SIZE ); - return ( K - this.pickerSlider.getYValue() ) / K; - }, - _updateSwatch: function() { - var M = this.get( this.OPT.RGB ), - O = this.get( this.OPT.WEBSAFE ), - N = this.getElement( this.ID.SWATCH ), - L = M.join( "," ), - K = this.get( this.OPT.TXT ); - E.setStyle( N, "background-color", "rgb(" + L + ")" ); - N.title = A( K.CURRENT_COLOR, { "rgb": "#" + this.get( this.OPT.HEX ) } ); - N = this.getElement( this.ID.WEBSAFE_SWATCH ); - L = O.join( "," ); - E.setStyle( N, "background-color", "rgb(" + L + ")" ); - N.title = A( K.CLOSEST_WEBSAFE, { "rgb": "#" + B.rgb2hex( O ) } ); - }, - _getValuesFromSliders: function() { - this.set( this.OPT.RGB, B.hsv2rgb( this._getH(), this._getS(), this._getV() ) ); - }, - _updateFormFields: function() { - this.getElement( this.ID.H ).value = this.get( this.OPT.HUE ); - this.getElement( this.ID.S ).value = this.get( this.OPT.SATURATION ); - this.getElement( this.ID.V ).value = this.get( this.OPT.VALUE ); - this.getElement( this.ID.R ).value = this.get( this.OPT.RED ); - this.getElement( this.ID.R_HEX ).innerHTML = B.dec2hex( this.get( this.OPT.RED ) ); - this.getElement( this.ID.G ).value = this.get( this.OPT.GREEN ); - this.getElement( this.ID.G_HEX ).innerHTML = B.dec2hex( this.get( this.OPT.GREEN ) ); - this.getElement( this.ID.B ).value = this.get( this.OPT.BLUE ); - this.getElement( this.ID.B_HEX ).innerHTML = B.dec2hex( this.get( this.OPT.BLUE ) ); - this.getElement( this.ID.HEX ).value = this.get( this.OPT.HEX ); - }, - _onHueSliderChange: function( N ) { - var L = this._getH(), - K = B.hsv2rgb( L, 1, 1 ), - M = "rgb(" + K.join( "," ) + ")"; - this.set( this.OPT.HUE, L, true ); - E.setStyle( this.getElement( this.ID.PICKER_BG ), "background-color", M ); - if ( this.hueSlider.valueChangeSource !== D.SOURCE_SET_VALUE ) { - this._getValuesFromSliders(); - } - this._updateFormFields(); - this._updateSwatch(); - }, - _onPickerSliderChange: function( M ) { - var L = this._getS(), - K = this._getV(); - this.set( this.OPT.SATURATION, Math.round( L * 100 ), true ); - this.set( this.OPT.VALUE, Math.round( K * 100 ), true ); - if ( this.pickerSlider.valueChangeSource !== D.SOURCE_SET_VALUE ) { - this._getValuesFromSliders(); - } - this._updateFormFields(); - this._updateSwatch(); - }, - _getCommand: function( K ) { - var L = I.getCharCode( K ); - if ( L === 38 ) { - return 3; - } else { - if ( L === 13 ) { - return 6; - } else { - if ( L === 40 ) { - return 4; - } else { - if ( L >= 48 && L <= 57 ) { - return 1; - } else { - if ( L >= 97 && L <= 102 ) { - return 2; - } else { - if ( L >= 65 && L <= 70 ) { - return 2; - } else { - if ( "8, 9, 13, 27, 37, 39".indexOf( L ) > -1 || K.ctrlKey || K.metaKey ) { - return 5; - } else { - return 0; - } - } - } - } - } - } - } - }, - _useFieldValue: function( L, K, N ) { - var M = K.value; if ( N !== this.OPT.HEX ) { - M = parseInt( M, 10 ); - } - if ( M !== this.get( N ) ) { - this.set( N, M ); - } - }, - _rgbFieldKeypress: function( M, K, O ) { - var N = this._getCommand( M ), - L = ( M.shiftKey ) ? 10 : 1; - switch ( N ) { - case 6: - this._useFieldValue.apply( this, arguments ); - break;case 3: - this.set( O, Math.min( this.get( O ) + L, 255 ) ); - this._updateFormFields(); - break;case 4: - this.set( O, Math.max( this.get( O ) - L, 0 ) ); - this._updateFormFields(); - break;default: - } - }, - _hexFieldKeypress: function( L, K, N ) { - var M = this._getCommand( L ); - if ( M === 6 ) { - this._useFieldValue.apply( this, arguments ); - } - }, - _hexOnly: function( L, K ) { - var M = this._getCommand( L ); - switch ( M ) { - case 6: - case 5: - case 1: - break;case 2: - if ( K !== true ) { - break; - }default: - I.stopEvent( L ); - return false; - } - }, - _numbersOnly: function( K ) { - return this._hexOnly( K, true ); - }, - getElement: function( K ) { - return this.get( this.OPT.ELEMENTS )[ this.get( this.OPT.IDS )[ K ] ]; - }, - _createElements: function() { - var N, M, P, O, L, - K = this.get( this.OPT.IDS ), - Q = this.get( this.OPT.TXT ), - S = this.get( this.OPT.IMAGES ), - R = function( U, V ) { - var W = document.createElement( U ); - if ( V ) { - C.augmentObject( W, V, true ); - } - return W; - }, - T = function( U, V ) { - var W = C.merge({ autocomplete: "off", value: "0", size: 3, maxlength: 3 }, V ); - W.name = W.id; - return new R( U, W ); - }; - L = this.get( "element" ); - N = new R( "div", { id: K[ this.ID.PICKER_BG ], className: "yui-picker-bg", tabIndex: -1, hideFocus: true } ); - M = new R( "div", { id: K[ this.ID.PICKER_THUMB ], className: "yui-picker-thumb" } ); - P = new R( "img", { src: S.PICKER_THUMB } ); - M.appendChild( P ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "div", { id: K[ this.ID.HUE_BG ], className: "yui-picker-hue-bg", tabIndex: -1, hideFocus: true } ); - M = new R( "div", { id: K[ this.ID.HUE_THUMB ], className: "yui-picker-hue-thumb" } ); - P = new R( "img", { src: S.HUE_THUMB } ); - M.appendChild( P ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "div", { id: K[ this.ID.CONTROLS ], className: "yui-picker-controls" } ); - L.appendChild( N ); - L = N; - N = new R( "div", { className: "hd" } ); - M = new R( "a", { id: K[ this.ID.CONTROLS_LABEL ], href: "#" } ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "div", { className: "bd" } ); - L.appendChild( N ); - L = N; - N = new R( "ul", { id: K[ this.ID.RGB_CONTROLS ], className: "yui-picker-rgb-controls" } ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.R + " " ) ); - O = new T( "input", { id: K[ this.ID.R ], className: "yui-picker-r" } ); - M.appendChild( O ); - N.appendChild( M ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.G + " " ) ); - O = new T( "input", { id: K[ this.ID.G ], className: "yui-picker-g" } ); - M.appendChild( O ); - N.appendChild( M ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.B + " " ) ); - O = new T( "input", { id: K[ this.ID.B ], className: "yui-picker-b" } ); - M.appendChild( O ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "ul", { id: K[ this.ID.HSV_CONTROLS ], className: "yui-picker-hsv-controls" } ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.H + " " ) ); - O = new T( "input", { id: K[ this.ID.H ], className: "yui-picker-h" } ); - M.appendChild( O ); - M.appendChild( document.createTextNode( " " + Q.DEG ) ); - N.appendChild( M ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.S + " " ) ); - O = new T( "input", { id: K[ this.ID.S ], className: "yui-picker-s" } ); - M.appendChild( O ); - M.appendChild( document.createTextNode( " " + Q.PERCENT ) ); - N.appendChild( M ); - M = new R( "li" ); - M.appendChild( document.createTextNode( Q.V + " " ) ); - O = new T( "input", { id: K[ this.ID.V ], className: "yui-picker-v" } ); - M.appendChild( O ); - M.appendChild( document.createTextNode( " " + Q.PERCENT ) ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "ul", { id: K[ this.ID.HEX_SUMMARY ], className: "yui-picker-hex_summary" } ); - M = new R( "li", { id: K[ this.ID.R_HEX ] } ); - N.appendChild( M ); - M = new R( "li", { id: K[ this.ID.G_HEX ] } ); - N.appendChild( M ); - M = new R( "li", { id: K[ this.ID.B_HEX ] } ); - N.appendChild( M ); - L.appendChild( N ); - N = new R( "div", { id: K[ this.ID.HEX_CONTROLS ], className: "yui-picker-hex-controls" } ); - N.appendChild( document.createTextNode( Q.HEX + " " ) ); - M = new T( "input", { id: K[ this.ID.HEX ], className: "yui-picker-hex", size: 6, maxlength: 6 } ); - N.appendChild( M ); - L.appendChild( N ); - L = this.get( "element" ); - N = new R( "div", { id: K[ this.ID.SWATCH ], className: "yui-picker-swatch" } ); - L.appendChild( N ); - N = new R( "div", { id: K[ this.ID.WEBSAFE_SWATCH ], className: "yui-picker-websafe-swatch" } ); - L.appendChild( N ); - }, - _attachRGBHSV: function( L, K ) { - I.on( this.getElement( L ), "keydown", function( N, M ) { - M._rgbFieldKeypress( N, this, K ); - }, this ); - I.on( this.getElement( L ), "keypress", this._numbersOnly, this, true ); - I.on( this.getElement( L ), "blur", function( N, M ) { - M._useFieldValue( N, this, K ); - }, this ); - }, - _updateRGB: function() { - var K = [ this.get( this.OPT.RED ), this.get( this.OPT.GREEN ), this.get( this.OPT.BLUE ) ]; - this.set( this.OPT.RGB, K ); - this._updateSliders(); - }, - _initElements: function() { - var O = this.OPT, - N = this.get( O.IDS ), - L = this.get( O.ELEMENTS ), - K, M, P; - for ( K in this.ID ) { - if ( C.hasOwnProperty( this.ID, K ) ) { - N[ this.ID[ K ] ] = N[ K ]; - } - } - M = E.get( N[ this.ID.PICKER_BG ] ); - if ( !M ) { - this._createElements(); - } else {} - for ( K in N ) { - if ( C.hasOwnProperty( N, K ) ) { - M = E.get( N[ K ] ); - P = E.generateId( M ); - N[ K ] = P; - N[ N[ K ] ] = P; - L[ P ] = M; - } - } - }, - initPicker: function() { - this._initSliders(); - this._bindUI(); - this.syncUI( true ); - }, - _initSliders: function() { - var K = this.ID, - L = this.get( this.OPT.PICKER_SIZE ); - this.hueSlider = D.getVertSlider( this.getElement( K.HUE_BG ), this.getElement( K.HUE_THUMB ), 0, L ); - this.pickerSlider = D.getSliderRegion( this.getElement( K.PICKER_BG ), this.getElement( K.PICKER_THUMB ), 0, L, 0, L ); - this.set( this.OPT.ANIMATE, this.get( this.OPT.ANIMATE ) ); - }, - _bindUI: function() { - var K = this.ID, - L = this.OPT; this.hueSlider.subscribe( "change", this._onHueSliderChange, this, true ); - this.pickerSlider.subscribe( "change", this._onPickerSliderChange, this, true ); - I.on( this.getElement( K.WEBSAFE_SWATCH ), "click", function( M ) { - this.setValue( this.get( L.WEBSAFE ) ); - }, this, true ); - I.on( this.getElement( K.CONTROLS_LABEL ), "click", function( M ) { - this.set( L.SHOW_CONTROLS, !this.get( L.SHOW_CONTROLS ) ); - I.preventDefault( M ); - }, this, true ); - this._attachRGBHSV( K.R, L.RED ); - this._attachRGBHSV( K.G, L.GREEN ); - this._attachRGBHSV( K.B, L.BLUE ); - this._attachRGBHSV( K.H, L.HUE ); - this._attachRGBHSV( K.S, L.SATURATION ); - this._attachRGBHSV( K.V, L.VALUE ); - I.on( this.getElement( K.HEX ), "keydown", function( N, M ) { - M._hexFieldKeypress( N, this, L.HEX ); - }, this ); - I.on( this.getElement( this.ID.HEX ), "keypress", this._hexOnly, this, true ); - I.on( this.getElement( this.ID.HEX ), "blur", function( N, M ) { - M._useFieldValue( N, this, L.HEX ); - }, this ); - }, - syncUI: function( K ) { - this.skipAnim = K; this._updateRGB(); - this.skipAnim = false; - }, - _updateRGBFromHSV: function() { - var L = [ this.get( this.OPT.HUE ), this.get( this.OPT.SATURATION ) / 100, this.get( this.OPT.VALUE ) / 100 ], - K = B.hsv2rgb( L ); - this.set( this.OPT.RGB, K ); - this._updateSliders(); - }, - _updateHex: function() { - var N = this.get( this.OPT.HEX ), - K = N.length, - O, M, L; - if ( K === 3 ) { - O = N.split( "" ); - for ( M = 0; M < K; M = M + 1 ) { - O[ M ] = O[ M ] + O[ M ]; - } - N = O.join( "" ); - } - if ( N.length !== 6 ) { - return false; - } - L = B.hex2rgb( N ); - this.setValue( L ); - }, - _hideShowEl: function( M, K ) { - var L = ( C.isString( M ) ? this.getElement( M ) : M ); - E.setStyle( L, "display", ( K ) ? "" : "none" ); - }, - initAttributes: function( K ) { - K = K || {}; - G.superclass.initAttributes.call( this, K ); - this.setAttributeConfig( this.OPT.PICKER_SIZE, { value: K.size || this.DEFAULT.PICKER_SIZE } ); - this.setAttributeConfig( this.OPT.HUE, { value: K.hue || 0, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.SATURATION, { value: K.saturation || 0, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.VALUE, { value: C.isNumber( K.value ) ? K.value : 100, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.RED, { value: C.isNumber( K.red ) ? K.red : 255, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.GREEN, { value: C.isNumber( K.green ) ? K.green : 255, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.BLUE, { value: C.isNumber( K.blue ) ? K.blue : 255, validator: C.isNumber } ); - this.setAttributeConfig( this.OPT.HEX, { value: K.hex || "FFFFFF", validator: C.isString } ); - this.setAttributeConfig( this.OPT.RGB, { - value: K.rgb || [ 255, 255, 255 ], method: function( O ) { - this.set( this.OPT.RED, O[ 0 ], true ); - this.set( this.OPT.GREEN, O[ 1 ], true ); - this.set( this.OPT.BLUE, O[ 2 ], true ); - var Q = B.websafe( O ), - P = B.rgb2hex( O ), - N = B.rgb2hsv( O ); - this.set( this.OPT.WEBSAFE, Q, true ); - this.set( this.OPT.HEX, P, true ); - if ( N[ 1 ] ) { - this.set( this.OPT.HUE, N[ 0 ], true ); - } - this.set( this.OPT.SATURATION, Math.round( N[ 1 ] * 100 ), true ); - this.set( this.OPT.VALUE, Math.round( N[ 2 ] * 100 ), true ); - }, - readonly: true } ); - this.setAttributeConfig( this.OPT.CONTAINER, { - value: null, method: function( N ) { - if ( N ) { - N.showEvent.subscribe( function() { - this.pickerSlider.focus(); - }, this, true ); - } - } } ); - this.setAttributeConfig( this.OPT.WEBSAFE, { value: K.websafe || [ 255, 255, 255 ] } ); - var M = K.ids || C.merge( {}, this.ID ), - L; - if ( !K.ids && J > 1 ) { - for ( L in M ) { - if ( C.hasOwnProperty( M, L ) ) { - M[ L ] = M[ L ] + J; - } - } - } - this.setAttributeConfig( this.OPT.IDS, { value: M, writeonce: true } ); - this.setAttributeConfig( this.OPT.TXT, { value: K.txt || this.TXT, writeonce: true } ); - this.setAttributeConfig( this.OPT.IMAGES, { value: K.images || this.IMAGE, writeonce: true } ); - this.setAttributeConfig( this.OPT.ELEMENTS, { - value: {}, - readonly: true } ); - this.setAttributeConfig( this.OPT.SHOW_CONTROLS, { - value: C.isBoolean( K.showcontrols ) ? K.showcontrols : true, method: function( N ) { - var O = E.getElementsByClassName( "bd", "div", this.getElement( this.ID.CONTROLS ) )[ 0 ]; - this._hideShowEl( O, N ); - this.getElement( this.ID.CONTROLS_LABEL ).innerHTML = ( N ) ? this.get( this.OPT.TXT ).HIDE_CONTROLS : this.get( this.OPT.TXT ).SHOW_CONTROLS; - } } ); - this.setAttributeConfig( this.OPT.SHOW_RGB_CONTROLS, { - value: C.isBoolean( K.showrgbcontrols ) ? K.showrgbcontrols : true, method: function( N ) { - this._hideShowEl( this.ID.RGB_CONTROLS, N ); - } } ); - this.setAttributeConfig( this.OPT.SHOW_HSV_CONTROLS, { - value: C.isBoolean( K.showhsvcontrols ) ? K.showhsvcontrols : false, method: function( N ) { - this._hideShowEl( this.ID.HSV_CONTROLS, N ); - if ( N && this.get( this.OPT.SHOW_HEX_SUMMARY ) ) { - this.set( this.OPT.SHOW_HEX_SUMMARY, false ); - } - } } ); - this.setAttributeConfig( this.OPT.SHOW_HEX_CONTROLS, { - value: C.isBoolean( K.showhexcontrols ) ? K.showhexcontrols : false, method: function( N ) { - this._hideShowEl( this.ID.HEX_CONTROLS, N ); - } } ); - this.setAttributeConfig( this.OPT.SHOW_WEBSAFE, { - value: C.isBoolean( K.showwebsafe ) ? K.showwebsafe : true, method: function( N ) { - this._hideShowEl( this.ID.WEBSAFE_SWATCH, N ); - } } ); - this.setAttributeConfig( this.OPT.SHOW_HEX_SUMMARY, { - value: C.isBoolean( K.showhexsummary ) ? K.showhexsummary : true, method: function( N ) { - this._hideShowEl( this.ID.HEX_SUMMARY, N ); - if ( N && this.get( this.OPT.SHOW_HSV_CONTROLS ) ) { - this.set( this.OPT.SHOW_HSV_CONTROLS, false ); - } - } } ); - this.setAttributeConfig( this.OPT.ANIMATE, { - value: C.isBoolean( K.animate ) ? K.animate : true, method: function( N ) { - if ( this.pickerSlider ) { - this.pickerSlider.animate = N; - this.hueSlider.animate = N; - } - } } ); - this.on( this.OPT.HUE + "Change", this._updateRGBFromHSV, this, true ); - this.on( this.OPT.SATURATION + "Change", this._updateRGBFromHSV, this, true ); - this.on( this.OPT.VALUE + "Change", this._updateRGBFromHSV, this, true ); - this.on( this.OPT.RED + "Change", this._updateRGB, this, true ); - this.on( this.OPT.GREEN + "Change", this._updateRGB, this, true ); - this.on( this.OPT.BLUE + "Change", this._updateRGB, this, true ); - this.on( this.OPT.HEX + "Change", this._updateHex, this, true ); - this._initElements(); - } } ); - YAHOO.widget.ColorPicker = G; -})(); -YAHOO.register( "colorpicker", YAHOO.widget.ColorPicker, { version: "2.7.0", build: "1796" } ); - -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ ( function() { - var B = YAHOO.util; - var A = function( D, C, E, F ) { - if ( !D ) {} - this.init( D, C, E, F ); - }; - A.NAME = "Anim"; - A.prototype = { - toString: function() { - var C = this.getEl() || {}; - var D = C.id || C.tagName; - return ( this.constructor.NAME + ": " + D ); - }, - patterns: { noNegatives: /width|height|opacity|padding/i, offsetAttribute: /^((width|height)|(top|left))$/, defaultUnit: /width|height|top$|bottom$|left$|right$/i, offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i }, - doMethod: function( C, E, D ) { - return this.method( this.currentFrame, E, D - E, this.totalFrames ); - }, - setAttribute: function( C, F, E ) { - var D = this.getEl(); - if ( this.patterns.noNegatives.test( C ) ) { - F = ( F > 0 ) ? F : 0; - } - if ( "style" in D ) { - B.Dom.setStyle( D, C, F + E ); - } else { - if ( C in D ) { - D[ C ] = F; - } - } - }, - getAttribute: function( C ) { - var E = this.getEl(); - var G = B.Dom.getStyle( E, C ); - if ( G !== "auto" && !this.patterns.offsetUnit.test( G ) ) { - return parseFloat( G ); - } - var D = this.patterns.offsetAttribute.exec( C ) || []; - var H = !!( D[ 3 ] ); - var F = !!( D[ 2 ] ); - if ( "style" in E ) { - if ( F || ( B.Dom.getStyle( E, "position" ) == "absolute" && H ) ) { - G = E[ "offset" + D[ 0 ].charAt( 0 ).toUpperCase() + D[ 0 ].substr( 1 ) ]; - } else { - G = 0; - } - } else { - if ( C in E ) { - G = E[ C ]; - } - } - return G; - }, - getDefaultUnit: function( C ) { - if ( this.patterns.defaultUnit.test( C ) ) { - return "px"; - } - return ""; - }, - setRuntimeAttribute: function( D ) { - var I; var E; var F = this.attributes; this.runtimeAttributes[ D ] = {}; - var H = function( J ) { - return ( typeof J !== "undefined" ); - }; - if ( !H( F[ D ][ "to" ] ) && !H( F[ D ][ "by" ] ) ) { - return false; - } - I = ( H( F[ D ][ "from" ] ) ) ? F[ D ][ "from" ] : this.getAttribute( D ); - if ( H( F[ D ][ "to" ] ) ) { - E = F[ D ][ "to" ]; - } else { - if ( H( F[ D ][ "by" ] ) ) { - if ( I.constructor == Array ) { - E = []; - for ( var G = 0, C = I.length; G < C; ++G ) { - E[ G ] = I[ G ] + F[ D ][ "by" ][ G ] * 1; - } - } else { - E = I + F[ D ][ "by" ] * 1; - } - } - } - this.runtimeAttributes[ D ].start = I; - this.runtimeAttributes[ D ].end = E; - this.runtimeAttributes[ D ].unit = ( H( F[ D ].unit ) ) ? F[ D ][ "unit" ] : this.getDefaultUnit( D ); - return true; - }, - init: function( E, J, I, C ) { - var D = false; var F = null; var H = 0; E = B.Dom.get( E ); - this.attributes = J || {}; - this.duration = !YAHOO.lang.isUndefined( I ) ? I : 1; - this.method = C || B.Easing.easeNone; - this.useSeconds = true; - this.currentFrame = 0; - this.totalFrames = B.AnimMgr.fps; - this.setEl = function( M ) { - E = B.Dom.get( M ); - }; - this.getEl = function() { - return E; - }; - this.isAnimated = function() { - return D; - }; - this.getStartTime = function() { - return F; - }; - this.runtimeAttributes = {}; - this.animate = function() { - if ( this.isAnimated() ) { - return false; - } - this.currentFrame = 0; - this.totalFrames = ( this.useSeconds ) ? Math.ceil( B.AnimMgr.fps * this.duration ) : this.duration; - if ( this.duration === 0 && this.useSeconds ) { - this.totalFrames = 1; - } - B.AnimMgr.registerElement( this ); - return true; - }; - this.stop = function( M ) { - if ( !this.isAnimated() ) { - return false; - } - if ( M ) { - this.currentFrame = this.totalFrames; - this._onTween.fire(); - } - B.AnimMgr.stop( this ); - }; - var L = function() { - this.onStart.fire(); - this.runtimeAttributes = {}; - for ( var M in this.attributes ) { - this.setRuntimeAttribute( M ); - } - D = true; - H = 0; - F = new Date(); - }; - var K = function() { - var O = { duration: new Date() - this.getStartTime(), currentFrame: this.currentFrame }; O.toString = function() { - return ( "duration: " + O.duration + ", currentFrame: " + O.currentFrame ); - }; - this.onTween.fire( O ); - var N = this.runtimeAttributes; - for ( var M in N ) { - this.setAttribute( M, this.doMethod( M, N[ M ].start, N[ M ].end ), N[ M ].unit ); - } - H += 1; - }; - var G = function() { - var M = ( new Date() - F ) / 1000; - var N = { duration: M, frames: H, fps: H / M }; N.toString = function() { - return ( "duration: " + N.duration + ", frames: " + N.frames + ", fps: " + N.fps ); - }; - D = false; - H = 0; - this.onComplete.fire( N ); - }; - this._onStart = new B.CustomEvent( "_start", this, true ); - this.onStart = new B.CustomEvent( "start", this ); - this.onTween = new B.CustomEvent( "tween", this ); - this._onTween = new B.CustomEvent( "_tween", this, true ); - this.onComplete = new B.CustomEvent( "complete", this ); - this._onComplete = new B.CustomEvent( "_complete", this, true ); - this._onStart.subscribe( L ); - this._onTween.subscribe( K ); - this._onComplete.subscribe( G ); - } }; B.Anim = A; -})(); -YAHOO.util.AnimMgr = new function() { - var C = null; - var B = []; - var A = 0; - this.fps = 1000; - this.delay = 1; - this.registerElement = function( F ) { - B[ B.length ] = F; - A += 1; - F._onStart.fire(); - this.start(); - }; - this.unRegister = function( G, F ) { - F = F || E( G ); - if ( !G.isAnimated() || F == -1 ) { - return false; - } - G._onComplete.fire(); - B.splice( F, 1 ); - A -= 1; - if ( A <= 0 ) { - this.stop(); - } - return true; - }; - this.start = function() { - if ( C === null ) { - C = setInterval( this.run, this.delay ); - } - }; - this.stop = function( H ) { - if ( !H ) { - clearInterval( C ); - for ( var G = 0, F = B.length; G < F; ++G ) { - this.unRegister( B[ 0 ], 0 ); - } - B = []; - C = null; - A = 0; - } else { - this.unRegister( H ); - } - }; - this.run = function() { - for ( var H = 0, F = B.length; H < F; ++H ) { - var G = B[ H ]; - if ( !G || !G.isAnimated() ) { - continue; - } - if ( G.currentFrame < G.totalFrames || G.totalFrames === null ) { - G.currentFrame += 1; - if ( G.useSeconds ) { - D( G ); - } - G._onTween.fire(); - } else { - YAHOO.util.AnimMgr.stop( G, H ); - } - } - }; - var E = function( H ) { - for ( var G = 0, F = B.length; G < F; ++G ) { - if ( B[ G ] == H ) { - return G; - } - } - return -1; - }; - var D = function( G ) { - var J = G.totalFrames; - var I = G.currentFrame; - var H = ( G.currentFrame * G.duration * 1000 / G.totalFrames ); - var F = ( new Date() - G.getStartTime() ); - var K = 0; - if ( F < G.duration * 1000 ) { - K = Math.round( ( F / H - 1 ) * G.currentFrame ); - } else { - K = J - ( I + 1 ); - } - if ( K > 0 && isFinite( K ) ) { - if ( G.currentFrame + K >= J ) { - K = J - ( I + 1 ); - } - G.currentFrame += K; - } - }; -}; -YAHOO.util.Bezier = new function() { - this.getPosition = function( E, D ) { - var F = E.length; - var C = []; - for ( var B = 0; B < F; ++B ) { - C[ B ] = [ E[ B ][ 0 ], E[ B ][ 1 ] ]; - } - for ( var A = 1; A < F; ++A ) { - for ( B = 0; B < F - A; ++B ) { - C[ B ][ 0 ] = ( 1 - D ) * C[ B ][ 0 ] + D * C[ parseInt( B + 1, 10 ) ][ 0 ]; - C[ B ][ 1 ] = ( 1 - D ) * C[ B ][ 1 ] + D * C[ parseInt( B + 1, 10 ) ][ 1 ]; - } - } - return [ C[ 0 ][ 0 ], C[ 0 ][ 1 ] ]; - }; -}; -(function() { - var A = function( F, E, G, H ) { - A.superclass.constructor.call( this, F, E, G, H ); - }; - A.NAME = "ColorAnim"; - A.DEFAULT_BGCOLOR = "#fff"; - var C = YAHOO.util; - YAHOO.extend( A, C.Anim ); - var D = A.superclass; - var B = A.prototype; - B.patterns.color = /color$/i; - B.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i; - B.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i; - B.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i; - B.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; - B.parseColor = function( E ) { - if ( E.length == 3 ) { - return E; - } - var F = this.patterns.hex.exec( E ); - if ( F && F.length == 4 ) { - return [ parseInt( F[ 1 ], 16 ), parseInt( F[ 2 ], 16 ), parseInt( F[ 3 ], 16 ) ]; - } - F = this.patterns.rgb.exec( E ); - if ( F && F.length == 4 ) { - return [ parseInt( F[ 1 ], 10 ), parseInt( F[ 2 ], 10 ), parseInt( F[ 3 ], 10 ) ]; - } - F = this.patterns.hex3.exec( E ); - if ( F && F.length == 4 ) { - return [ parseInt( F[ 1 ] + F[ 1 ], 16 ), parseInt( F[ 2 ] + F[ 2 ], 16 ), parseInt( F[ 3 ] + F[ 3 ], 16 ) ]; - } - return null; - }; - B.getAttribute = function( E ) { - var G = this.getEl(); - if ( this.patterns.color.test( E ) ) { - var I = YAHOO.util.Dom.getStyle( G, E ); - var H = this; - if ( this.patterns.transparent.test( I ) ) { - var F = YAHOO.util.Dom.getAncestorBy( G, function( J ) { - return !H.patterns.transparent.test( I ); - }); - if ( F ) { - I = C.Dom.getStyle( F, E ); - } else { - I = A.DEFAULT_BGCOLOR; - } - } - } else { - I = D.getAttribute.call( this, E ); - } - return I; - }; - B.doMethod = function( F, J, G ) { - var I; - if ( this.patterns.color.test( F ) ) { - I = []; - for ( var H = 0, E = J.length; H < E; ++H ) { - I[ H ] = D.doMethod.call( this, F, J[ H ], G[ H ] ); - } - I = "rgb(" + Math.floor( I[ 0 ] ) + "," + Math.floor( I[ 1 ] ) + "," + Math.floor( I[ 2 ] ) + ")"; - } else { - I = D.doMethod.call( this, F, J, G ); - } - return I; - }; - B.setRuntimeAttribute = function( F ) { - D.setRuntimeAttribute.call( this, F ); - if ( this.patterns.color.test( F ) ) { - var H = this.attributes; - var J = this.parseColor( this.runtimeAttributes[ F ].start ); - var G = this.parseColor( this.runtimeAttributes[ F ].end ); - if ( typeof H[ F ][ "to" ] === "undefined" && typeof H[ F ][ "by" ] !== "undefined" ) { - G = this.parseColor( H[ F ].by ); - for ( var I = 0, E = J.length; I < E; ++I ) { - G[ I ] = J[ I ] + G[ I ]; - } - } - this.runtimeAttributes[ F ].start = J; - this.runtimeAttributes[ F ].end = G; - } - }; - C.ColorAnim = A; -})(); -/* -TERMS OF USE - EASING EQUATIONS -Open source under the BSD License. -Copyright 2001 Robert Penner All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -YAHOO.util.Easing = { - easeNone: function( B, A, D, C ) { - return D * B / C + A; - }, - easeIn: function( B, A, D, C ) { - return D * ( B /= C ) * B + A; - }, - easeOut: function( B, A, D, C ) { - return -D * ( B /= C ) * ( B - 2 ) + A; - }, - easeBoth: function( B, A, D, C ) { - if ( ( B /= C / 2 ) < 1 ) { - return D / 2 * B * B + A; - } - return -D / 2 * ( ( --B ) * ( B - 2 ) - 1 ) + A; - }, - easeInStrong: function( B, A, D, C ) { - return D * ( B /= C ) * B * B * B + A; - }, - easeOutStrong: function( B, A, D, C ) { - return -D * ( ( B = B / C - 1 ) * B * B * B - 1 ) + A; - }, - easeBothStrong: function( B, A, D, C ) { - if ( ( B /= C / 2 ) < 1 ) { - return D / 2 * B * B * B * B + A; - } - return -D / 2 * ( ( B -= 2 ) * B * B * B - 2 ) + A; - }, - elasticIn: function( C, A, G, F, B, E ) { - if ( C == 0 ) { - return A; - } - if ( ( C /= F ) == 1 ) { - return A + G; - } - if ( !E ) { - E = F * 0.3; - } - if ( !B || B < Math.abs( G ) ) { - B = G; - var D = E / 4; - } else { - var D = E / ( 2 * Math.PI ) * Math.asin( G / B ); - } - return -( B * Math.pow( 2, 10 * ( C -= 1 ) ) * Math.sin( ( C * F - D ) * ( 2 * Math.PI ) / E ) ) + A; - }, - elasticOut: function( C, A, G, F, B, E ) { - if ( C == 0 ) { - return A; - } - if ( ( C /= F ) == 1 ) { - return A + G; - } - if ( !E ) { - E = F * 0.3; - } - if ( !B || B < Math.abs( G ) ) { - B = G; - var D = E / 4; - } else { - var D = E / ( 2 * Math.PI ) * Math.asin( G / B ); - } - return B * Math.pow( 2, -10 * C ) * Math.sin( ( C * F - D ) * ( 2 * Math.PI ) / E ) + G + A; - }, - elasticBoth: function( C, A, G, F, B, E ) { - if ( C == 0 ) { - return A; - } - if ( ( C /= F / 2 ) == 2 ) { - return A + G; - } - if ( !E ) { - E = F * ( 0.3 * 1.5 ); - } - if ( !B || B < Math.abs( G ) ) { - B = G; - var D = E / 4; - } else { - var D = E / ( 2 * Math.PI ) * Math.asin( G / B ); - } - if ( C < 1 ) { - return -0.5 * ( B * Math.pow( 2, 10 * ( C -= 1 ) ) * Math.sin( ( C * F - D ) * ( 2 * Math.PI ) / E ) ) + A; - } - return B * Math.pow( 2, -10 * ( C -= 1 ) ) * Math.sin( ( C * F - D ) * ( 2 * Math.PI ) / E ) * 0.5 + G + A; - }, - backIn: function( B, A, E, D, C ) { - if ( typeof C == "undefined" ) { - C = 1.70158; - } - return E * ( B /= D ) * B * ( ( C + 1 ) * B - C ) + A; - }, - backOut: function( B, A, E, D, C ) { - if ( typeof C == "undefined" ) { - C = 1.70158; - } - return E * ( ( B = B / D - 1 ) * B * ( ( C + 1 ) * B + C ) + 1 ) + A; - }, - backBoth: function( B, A, E, D, C ) { - if ( typeof C == "undefined" ) { - C = 1.70158; - } - if ( ( B /= D / 2 ) < 1 ) { - return E / 2 * ( B * B * ( ( ( C *= ( 1.525 ) ) + 1 ) * B - C ) ) + A; - } - return E / 2 * ( ( B -= 2 ) * B * ( ( ( C *= ( 1.525 ) ) + 1 ) * B + C ) + 2 ) + A; - }, - bounceIn: function( B, A, D, C ) { - return D - YAHOO.util.Easing.bounceOut( C - B, 0, D, C ) + A; - }, - bounceOut: function( B, A, D, C ) { - if ( ( B /= C ) < ( 1 / 2.75 ) ) { - return D * ( 7.5625 * B * B ) + A; - } else { - if ( B < ( 2 / 2.75 ) ) { - return D * ( 7.5625 * ( B -= ( 1.5 / 2.75 ) ) * B + 0.75 ) + A; - } else { - if ( B < ( 2.5 / 2.75 ) ) { - return D * ( 7.5625 * ( B -= ( 2.25 / 2.75 ) ) * B + 0.9375 ) + A; - } - } - } - return D * ( 7.5625 * ( B -= ( 2.625 / 2.75 ) ) * B + 0.984375 ) + A; - }, - bounceBoth: function( B, A, D, C ) { - if ( B < C / 2 ) { - return YAHOO.util.Easing.bounceIn( B * 2, 0, D, C ) * 0.5 + A; - } - return YAHOO.util.Easing.bounceOut( B * 2 - C, 0, D, C ) * 0.5 + D * 0.5 + A; - } }; -(function() { - var A = function( H, G, I, J ) { - if ( H ) { - A.superclass.constructor.call( this, H, G, I, J ); - } - }; - A.NAME = "Motion"; - var E = YAHOO.util; - YAHOO.extend( A, E.ColorAnim ); - var F = A.superclass; - var C = A.prototype; - C.patterns.points = /^points$/i; - C.setAttribute = function( G, I, H ) { - if ( this.patterns.points.test( G ) ) { - H = H || "px"; - F.setAttribute.call( this, "left", I[ 0 ], H ); - F.setAttribute.call( this, "top", I[ 1 ], H ); - } else { - F.setAttribute.call( this, G, I, H ); - } - }; - C.getAttribute = function( G ) { - if ( this.patterns.points.test( G ) ) { - var H = [ F.getAttribute.call( this, "left" ), F.getAttribute.call( this, "top" ) ]; - } else { - H = F.getAttribute.call( this, G ); - } - return H; - }; - C.doMethod = function( G, K, H ) { - var J = null; - if ( this.patterns.points.test( G ) ) { - var I = this.method( this.currentFrame, 0, 100, this.totalFrames ) / 100; - J = E.Bezier.getPosition( this.runtimeAttributes[ G ], I ); - } else { - J = F.doMethod.call( this, G, K, H ); - } - return J; - }; - C.setRuntimeAttribute = function( P ) { - if ( this.patterns.points.test( P ) ) { - var H = this.getEl(); - var J = this.attributes; - var G; - var L = J[ "points" ][ "control" ] || []; - var I; - var M, O; - if ( L.length > 0 && !( L[ 0 ] instanceof Array ) ) { - L = [ L ]; - } else { - var K = []; - for ( M = 0, O = L.length; M < O; ++M ) { - K[ M ] = L[ M ]; - } - L = K; - } - if ( E.Dom.getStyle( H, "position" ) == "static" ) { - E.Dom.setStyle( H, "position", "relative" ); - } - if ( D( J[ "points" ][ "from" ] ) ) { - E.Dom.setXY( H, J[ "points" ][ "from" ] ); - } else { - E.Dom.setXY( H, E.Dom.getXY( H ) ); - } - G = this.getAttribute( "points" ); - if ( D( J[ "points" ][ "to" ] ) ) { - I = B.call( this, J[ "points" ][ "to" ], G ); - var N = E.Dom.getXY( this.getEl() ); - for ( M = 0, O = L.length; M < O; ++M ) { - L[ M ] = B.call( this, L[ M ], G ); - } - } else { - if ( D( J[ "points" ][ "by" ] ) ) { - I = [ G[ 0 ] + J[ "points" ][ "by" ][ 0 ], G[ 1 ] + J[ "points" ][ "by" ][ 1 ] ]; - for ( M = 0, O = L.length; M < O; ++M ) { - L[ M ] = [ G[ 0 ] + L[ M ][ 0 ], G[ 1 ] + L[ M ][ 1 ] ]; - } - } - } - this.runtimeAttributes[ P ] = [ G ]; - if ( L.length > 0 ) { - this.runtimeAttributes[ P ] = this.runtimeAttributes[ P ].concat( L ); - } - this.runtimeAttributes[ P ][ this.runtimeAttributes[ P ].length ] = I; - } else { - F.setRuntimeAttribute.call( this, P ); - } - }; - var B = function( G, I ) { - var H = E.Dom.getXY( this.getEl() ); - G = [ G[ 0 ] - H[ 0 ] + I[ 0 ], G[ 1 ] - H[ 1 ] + I[ 1 ] ]; - return G; - }; - var D = function( G ) { - return ( typeof G !== "undefined" ); - }; - E.Motion = A; -})(); -(function() { - var D = function( F, E, G, H ) { - if ( F ) { - D.superclass.constructor.call( this, F, E, G, H ); - } - }; - D.NAME = "Scroll"; - var B = YAHOO.util; - YAHOO.extend( D, B.ColorAnim ); - var C = D.superclass; - var A = D.prototype; - A.doMethod = function( E, H, F ) { - var G = null; - if ( E == "scroll" ) { - G = [ this.method( this.currentFrame, H[ 0 ], F[ 0 ] - H[ 0 ], this.totalFrames ), this.method( this.currentFrame, H[ 1 ], F[ 1 ] - H[ 1 ], this.totalFrames ) ]; - } else { - G = C.doMethod.call( this, E, H, F ); - } - return G; - }; - A.getAttribute = function( E ) { - var G = null; - var F = this.getEl(); - if ( E == "scroll" ) { - G = [ F.scrollLeft, F.scrollTop ]; - } else { - G = C.getAttribute.call( this, E ); - } - return G; - }; - A.setAttribute = function( E, H, G ) { - var F = this.getEl(); - if ( E == "scroll" ) { - F.scrollLeft = H[ 0 ]; - F.scrollTop = H[ 1 ]; - } else { - C.setAttribute.call( this, E, H, G ); - } - }; - B.Scroll = D; -})(); -YAHOO.register( "animation", YAHOO.util.Anim, { version: "2.7.0", build: "1799" } ); diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo-rtl.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo-rtl.png Binary files differdeleted file mode 100644 index 206d38ab9d2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo.png Binary files differdeleted file mode 100644 index a7883643adb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/redo.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo-rtl.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo-rtl.png Binary files differdeleted file mode 100644 index a7883643adb..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo.png Binary files differdeleted file mode 100644 index 206d38ab9d2..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/hidpi/undo.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/redo-rtl.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/redo-rtl.png Binary files differdeleted file mode 100644 index dd12c68202f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/redo-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/redo.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/redo.png Binary files differdeleted file mode 100644 index 75a18720008..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/redo.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/undo-rtl.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/undo-rtl.png Binary files differdeleted file mode 100644 index 75a18720008..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/undo-rtl.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/icons/undo.png b/addons/website/static/lib/ckeditor/plugins/undo/icons/undo.png Binary files differdeleted file mode 100644 index f81b3b39be7..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/icons/undo.png +++ /dev/null diff --git a/addons/website/static/lib/ckeditor/plugins/undo/lang/en.js b/addons/website/static/lib/ckeditor/plugins/undo/lang/en.js deleted file mode 100644 index 68a58007d5d..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/lang/en.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.md or http://ckeditor.com/license -*/ -CKEDITOR.plugins.setLang( 'undo', 'en', { - redo: 'Redo', - undo: 'Undo' -}); diff --git a/addons/website/static/lib/ckeditor/plugins/undo/plugin.js b/addons/website/static/lib/ckeditor/plugins/undo/plugin.js deleted file mode 100644 index 97a00c82bf3..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/undo/plugin.js +++ /dev/null @@ -1,713 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Undo/Redo system for saving a shapshot for document modification - * and other recordable changes. - */ - -(function() { - CKEDITOR.plugins.add( 'undo', { - lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% - icons: 'redo,redo-rtl,undo,undo-rtl', // %REMOVE_LINE_CORE% - hidpi: true, // %REMOVE_LINE_CORE% - init: function( editor ) { - var undoManager = editor.undoManager = new UndoManager( editor ); - - var undoCommand = editor.addCommand( 'undo', { - exec: function() { - if ( undoManager.undo() ) { - editor.selectionChange(); - this.fire( 'afterUndo' ); - } - }, - startDisabled: true, - canUndo: false - } ); - - var redoCommand = editor.addCommand( 'redo', { - exec: function() { - if ( undoManager.redo() ) { - editor.selectionChange(); - this.fire( 'afterRedo' ); - } - }, - startDisabled: true, - canUndo: false - } ); - - editor.setKeystroke( [ - [ CKEDITOR.CTRL + 90 /*Z*/, 'undo' ], - [ CKEDITOR.CTRL + 89 /*Y*/, 'redo' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'redo' ] - ] ); - - undoManager.onChange = function() { - undoCommand.setState( undoManager.undoable() ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - redoCommand.setState( undoManager.redoable() ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); - }; - - function recordCommand( event ) { - // If the command hasn't been marked to not support undo. - if ( undoManager.enabled && event.data.command.canUndo !== false ) - undoManager.save(); - } - - // We'll save snapshots before and after executing a command. - editor.on( 'beforeCommandExec', recordCommand ); - editor.on( 'afterCommandExec', recordCommand ); - - // Save snapshots before doing custom changes. - editor.on( 'saveSnapshot', function( evt ) { - undoManager.save( evt.data && evt.data.contentOnly ); - } ); - - // Registering keydown on every document recreation.(#3844) - editor.on( 'contentDom', function() { - editor.editable().on( 'keydown', function( event ) { - var keystroke = event.data.getKey(); - - if ( keystroke == 8 /*Backspace*/ || keystroke == 46 /*Delete*/ ) - undoManager.type( keystroke, 0 ); - } ); - - editor.editable().on( 'keypress', function( event ) { - undoManager.type( event.data.getKey(), 1 ); - } ); - } ); - - // Always save an undo snapshot - the previous mode might have - // changed editor contents. - editor.on( 'beforeModeUnload', function() { - editor.mode == 'wysiwyg' && undoManager.save( true ); - } ); - - function toggleUndoManager() { - undoManager.enabled = editor.readOnly ? false : editor.mode == 'wysiwyg'; - undoManager.onChange(); - } - - // Make the undo manager available only in wysiwyg mode. - editor.on( 'mode', toggleUndoManager ); - - // Disable undo manager when in read-only mode. - editor.on( 'readOnly', toggleUndoManager ); - - if ( editor.ui.addButton ) { - editor.ui.addButton( 'Undo', { - label: editor.lang.undo.undo, - command: 'undo', - toolbar: 'undo,10' - } ); - - editor.ui.addButton( 'Redo', { - label: editor.lang.undo.redo, - command: 'redo', - toolbar: 'undo,20' - } ); - } - - /** - * Resets the undo stack. - * - * @member CKEDITOR.editor - */ - editor.resetUndo = function() { - // Reset the undo stack. - undoManager.reset(); - - // Create the first image. - editor.fire( 'saveSnapshot' ); - }; - - /** - * Amends the top of the undo stack (last undo image) with the current DOM changes. - * - * function() { - * editor.fire( 'saveSnapshot' ); - * editor.document.body.append(...); - * // Makes new changes following the last undo snapshot a part of it. - * editor.fire( 'updateSnapshot' ); - * .. - * } - * - * @event updateSnapshot - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ - editor.on( 'updateSnapshot', function() { - if ( undoManager.currentImage ) - undoManager.update(); - } ); - - /** - * Locks the undo manager to prevent any save/update operations. - * - * It is convenient to lock the undo manager before performing DOM operations - * that should not be recored (e.g. auto paragraphing). - * - * See {@link CKEDITOR.plugins.undo.UndoManager#lock} for more details. - * - * **Note:** In order to unlock the undo manager, {@link #unlockSnapshot} has to be fired - * the same number of times that `lockSnapshot` has been fired. - * - * @since 4.0 - * @event lockSnapshot - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ - editor.on( 'lockSnapshot', undoManager.lock, undoManager ); - - /** - * Unlocks the undo manager and updates the latest snapshot. - * - * @since 4.0 - * @event unlockSnapshot - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ - editor.on( 'unlockSnapshot', undoManager.unlock, undoManager ); - } - } ); - - CKEDITOR.plugins.undo = {}; - - /** - * Undoes the snapshot which represents the current document status. - * - * @private - * @class CKEDITOR.plugins.undo.Image - * @constructor Creates an Image class instance. - * @param {CKEDITOR.editor} editor The editor instance on which the image is created. - */ - var Image = CKEDITOR.plugins.undo.Image = function( editor ) { - this.editor = editor; - - editor.fire( 'beforeUndoImage' ); - - var contents = editor.getSnapshot(), - selection = contents && editor.getSelection(); - - // In IE, we need to remove the expando attributes. - CKEDITOR.env.ie && contents && ( contents = contents.replace( /\s+data-cke-expando=".*?"/g, '' ) ); - - this.contents = contents; - this.bookmarks = selection && selection.createBookmarks2( true ); - - editor.fire( 'afterUndoImage' ); - }; - - // Attributes that browser may changing them when setting via innerHTML. - var protectedAttrs = /\b(?:href|src|name)="[^"]*?"/gi; - - Image.prototype = { - equalsContent: function( otherImage ) { - var thisContents = this.contents, - otherContents = otherImage.contents; - - // For IE6/7 : Comparing only the protected attribute values but not the original ones.(#4522) - if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) ) { - thisContents = thisContents.replace( protectedAttrs, '' ); - otherContents = otherContents.replace( protectedAttrs, '' ); - } - - if ( thisContents != otherContents ) - return false; - - return true; - }, - - equalsSelection: function( otherImage ) { - var bookmarksA = this.bookmarks, - bookmarksB = otherImage.bookmarks; - - if ( bookmarksA || bookmarksB ) { - if ( !bookmarksA || !bookmarksB || bookmarksA.length != bookmarksB.length ) - return false; - - for ( var i = 0; i < bookmarksA.length; i++ ) { - var bookmarkA = bookmarksA[ i ], - bookmarkB = bookmarksB[ i ]; - - if ( bookmarkA.startOffset != bookmarkB.startOffset || bookmarkA.endOffset != bookmarkB.endOffset || !CKEDITOR.tools.arrayCompare( bookmarkA.start, bookmarkB.start ) || !CKEDITOR.tools.arrayCompare( bookmarkA.end, bookmarkB.end ) ) - return false; - } - } - - return true; - } - }; - - /** - * Main logic for the Redo/Undo feature. - * - * **Note:** This class is not accessible from the global scope. - * - * @private - * @class CKEDITOR.plugins.undo.UndoManager - * @constructor Creates an UndoManager class instance. - * @param {CKEDITOR.editor} editor - */ - function UndoManager( editor ) { - this.editor = editor; - - // Reset the undo stack. - this.reset(); - } - - UndoManager.prototype = { - /** - * When `locked` property is not `null`, the undo manager is locked, so - * operations like `save` or `update` are forbidden. - * - * The manager can be locked/unlocked by the {@link #lock} and {@link #unlock} methods. - * - * @private - * @property {Object} [locked=null] - */ - - /** - * Handles keystroke support for the undo manager. It is called whenever a keystroke that - * can change the editor contents is pressed. - * - * @param {Number} keystroke The key code. - * @param {Boolean} isCharacter If `true`, it is a character ('a', '1', '&', ...). Otherwise it is the remove key (*Delete* or *Backspace*). - */ - type: function( keystroke, isCharacter ) { - // Create undo snap for every different modifier key. - var modifierSnapshot = ( !isCharacter && keystroke != this.lastKeystroke ); - - // Create undo snap on the following cases: - // 1. Just start to type . - // 2. Typing some content after a modifier. - // 3. Typing some content after make a visible selection. - var startedTyping = !this.typing || ( isCharacter && !this.wasCharacter ); - - var editor = this.editor; - - if ( startedTyping || modifierSnapshot ) { - var beforeTypeImage = new Image( editor ), - beforeTypeCount = this.snapshots.length; - - // Use setTimeout, so we give the necessary time to the - // browser to insert the character into the DOM. - CKEDITOR.tools.setTimeout( function() { - var currentSnapshot = editor.getSnapshot(); - - // In IE, we need to remove the expando attributes. - if ( CKEDITOR.env.ie ) - currentSnapshot = currentSnapshot.replace( /\s+data-cke-expando=".*?"/g, '' ); - - // If changes have taken place, while not been captured yet (#8459), - // compensate the snapshot. - if ( beforeTypeImage.contents != currentSnapshot && beforeTypeCount == this.snapshots.length ) { - // It's safe to now indicate typing state. - this.typing = true; - - // This's a special save, with specified snapshot - // and without auto 'fireChange'. - if ( !this.save( false, beforeTypeImage, false ) ) - // Drop future snapshots. - this.snapshots.splice( this.index + 1, this.snapshots.length - this.index - 1 ); - - this.hasUndo = true; - this.hasRedo = false; - - this.typesCount = 1; - this.modifiersCount = 1; - - this.onChange(); - } - }, 0, this ); - } - - this.lastKeystroke = keystroke; - this.wasCharacter = isCharacter; - - // Create undo snap after typed too much (over 25 times). - if ( !isCharacter ) { - this.typesCount = 0; - this.modifiersCount++; - - if ( this.modifiersCount > 25 ) { - this.save( false, null, false ); - this.modifiersCount = 1; - } else { - setTimeout(function() { - editor.fire( 'change' ); - }, 0 ); - } - } else { - this.modifiersCount = 0; - this.typesCount++; - - if ( this.typesCount > 25 ) { - this.save( false, null, false ); - this.typesCount = 1; - } else { - setTimeout(function() { - editor.fire( 'change' ); - }, 0 ); - } - } - - }, - - /** - * Resets the undo stack. - */ - reset: function() { - // Remember last pressed key. - this.lastKeystroke = 0; - - // Stack for all the undo and redo snapshots, they're always created/removed - // in consistency. - this.snapshots = []; - - // Current snapshot history index. - this.index = -1; - - this.limit = this.editor.config.undoStackSize || 20; - - this.currentImage = null; - - this.hasUndo = false; - this.hasRedo = false; - this.locked = null; - - this.resetType(); - }, - - /** - * Resets all typing variables. - * - * @see #type - */ - resetType: function() { - this.typing = false; - delete this.lastKeystroke; - this.typesCount = 0; - this.modifiersCount = 0; - }, - - fireChange: function() { - this.hasUndo = !!this.getNextImage( true ); - this.hasRedo = !!this.getNextImage( false ); - // Reset typing - this.resetType(); - this.onChange(); - }, - - /** - * Saves a snapshot of the document image for later retrieval. - */ - save: function( onContentOnly, image, autoFireChange ) { - // Do not change snapshots stack when locked. - if ( this.locked ) - return false; - - var snapshots = this.snapshots; - - // Get a content image. - if ( !image ) - image = new Image( this.editor ); - - // Do nothing if it was not possible to retrieve an image. - if ( image.contents === false ) - return false; - - // Check if this is a duplicate. In such case, do nothing. - if ( this.currentImage ) { - if ( image.equalsContent( this.currentImage ) ) { - if ( onContentOnly ) - return false; - - if ( image.equalsSelection( this.currentImage ) ) - return false; - } else { - this.editor.fire( 'change' ); - } - } - - // Drop future snapshots. - snapshots.splice( this.index + 1, snapshots.length - this.index - 1 ); - - // If we have reached the limit, remove the oldest one. - if ( snapshots.length == this.limit ) - snapshots.shift(); - - // Add the new image, updating the current index. - this.index = snapshots.push( image ) - 1; - - this.currentImage = image; - - if ( autoFireChange !== false ) - this.fireChange(); - return true; - }, - - restoreImage: function( image ) { - // Bring editor focused to restore selection. - var editor = this.editor, - sel; - - if ( image.bookmarks ) { - editor.focus(); - // Retrieve the selection beforehand. (#8324) - sel = editor.getSelection(); - } - - // Start transaction - do not allow any mutations to the - // snapshots stack done when selecting bookmarks (much probably - // by selectionChange listener). - this.locked = 1; - - this.editor.loadSnapshot( image.contents ); - - if ( image.bookmarks ) - sel.selectBookmarks( image.bookmarks ); - else if ( CKEDITOR.env.ie ) { - // IE BUG: If I don't set the selection to *somewhere* after setting - // document contents, then IE would create an empty paragraph at the bottom - // the next time the document is modified. - var $range = this.editor.document.getBody().$.createTextRange(); - $range.collapse( true ); - $range.select(); - } - - this.locked = 0; - - this.index = image.index; - this.currentImage = this.snapshots[ this.index ]; - - // Update current image with the actual editor - // content, since actualy content may differ from - // the original snapshot due to dom change. (#4622) - this.update(); - this.fireChange(); - - editor.fire( 'change' ); - }, - - // Get the closest available image. - getNextImage: function( isUndo ) { - var snapshots = this.snapshots, - currentImage = this.currentImage, - image, i; - - if ( currentImage ) { - if ( isUndo ) { - for ( i = this.index - 1; i >= 0; i-- ) { - image = snapshots[ i ]; - if ( !currentImage.equalsContent( image ) ) { - image.index = i; - return image; - } - } - } else { - for ( i = this.index + 1; i < snapshots.length; i++ ) { - image = snapshots[ i ]; - if ( !currentImage.equalsContent( image ) ) { - image.index = i; - return image; - } - } - } - } - - return null; - }, - - /** - * Checks the current redo state. - * - * @returns {Boolean} Whether the document has a previous state to retrieve. - */ - redoable: function() { - return this.enabled && this.hasRedo; - }, - - /** - * Checks the current undo state. - * - * @returns {Boolean} Whether the document has a future state to restore. - */ - undoable: function() { - return this.enabled && this.hasUndo; - }, - - /** - * Performs undo on current index. - */ - undo: function() { - if ( this.undoable() ) { - this.save( true ); - - var image = this.getNextImage( true ); - if ( image ) - return this.restoreImage( image ), true; - } - - return false; - }, - - /** - * Performs redo on current index. - */ - redo: function() { - if ( this.redoable() ) { - // Try to save. If no changes have been made, the redo stack - // will not change, so it will still be redoable. - this.save( true ); - - // If instead we had changes, we can't redo anymore. - if ( this.redoable() ) { - var image = this.getNextImage( false ); - if ( image ) - return this.restoreImage( image ), true; - } - } - - return false; - }, - - /** - * Updates the last snapshot of the undo stack with the current editor content. - * - * @param {CKEDITOR.plugins.undo.Image} [newImage] The image which will replace the current one. - * If not set defaults to image taken from editor. - */ - update: function( newImage ) { - // Do not change snapshots stack is locked. - if ( this.locked ) - return; - - if ( !newImage ) - newImage = new Image( this.editor ); - - var i = this.index, - snapshots = this.snapshots; - - // Find all previous snapshots made for the same content (which differ - // only by selection) and replace all of them with the current image. - while ( i > 0 && this.currentImage.equalsContent( snapshots[ i - 1 ] ) ) - i -= 1; - - snapshots.splice( i, this.index - i + 1, newImage ); - this.index = i; - this.currentImage = newImage; - }, - - /** - * Locks the snapshot stack to prevent any save/update operations and when necessary, - * updates the tip of the snapshot stack with the DOM changes introduced during the - * locked period, after the {@link #unlock} method is called. - * - * It is mainly used to ensure any DOM operations that should not be recorded - * (e.g. auto paragraphing) are not added to the stack. - * - * **Note:** For every `lock` call you must call {@link #unlock} once to unlock the undo manager. - * - * @since 4.0 - */ - lock: function() { - if ( !this.locked ) { - var imageBefore = new Image( this.editor ); - - // If current editor content matches the tip of snapshot stack, - // the stack tip must be updated by unlock, to include any changes made - // during this period. - var matchedTip = this.currentImage && this.currentImage.equalsContent( imageBefore ); - - this.locked = { update: matchedTip ? imageBefore : null, level: 1 }; - } - // Increase the level of lock. - else - this.locked.level++; - }, - - /** - * Unlocks the snapshot stack and checks to amend the last snapshot. - * - * See {@link #lock} for more details. - * - * @since 4.0 - */ - unlock: function() { - if ( this.locked ) { - // Decrease level of lock and check if equals 0, what means that undoM is completely unlocked. - if ( !--this.locked.level ) { - var updateImage = this.locked.update, - newImage = new Image( this.editor ); - - this.locked = null; - - if ( updateImage && !updateImage.equalsContent( newImage ) ) - this.update( newImage ); - } - } - } - }; -})(); - -/** - * The number of undo steps to be saved. The higher value is set, the more - * memory is used for it. - * - * config.undoStackSize = 50; - * - * @cfg {Number} [undoStackSize=20] - * @member CKEDITOR.config - */ - -/** - * Fired when the editor is about to save an undo snapshot. This event can be - * fired by plugins and customizations to make the editor save undo snapshots. - * - * @event saveSnapshot - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ - -/** - * Fired before an undo image is to be taken. An undo image represents the - * editor state at some point. It is saved into the undo store, so the editor is - * able to recover the editor state on undo and redo operations. - * - * @since 3.5.3 - * @event beforeUndoImage - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @see CKEDITOR.editor#afterUndoImage - */ - -/** - * Fired after an undo image is taken. An undo image represents the - * editor state at some point. It is saved into the undo store, so the editor is - * able to recover the editor state on undo and redo operations. - * - * @since 3.5.3 - * @event afterUndoImage - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @see CKEDITOR.editor#beforeUndoImage - */ - -/** - * Fired when the content of the editor is changed. - * - * Due to performance reasons, it is not verified if the content really changed. - * The editor instead watches several editing actions that usually result in - * changes. This event may thus in some cases be fired when no changes happen - * or may even get fired twice. - * - * If it is important not to get the change event too often, you should compare the - * previous and the current editor content inside the event listener. - * - * @since 4.2 - * @event change - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/widget/dev/console.js b/addons/website/static/lib/ckeditor/plugins/widget/dev/console.js deleted file mode 100644 index 1fa5a3a3131..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/widget/dev/console.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -'use strict'; - -(function() { - - CKCONSOLE.add( 'widget', { - panels: [ - { - type: 'box', - content: '<ul class="ckconsole_list ckconsole_value" data-value="instances"></ul>', - - refresh: function( editor ) { - var instances = obj2Array( editor.widgets.instances ); - - return { - header: 'Instances (' + instances.length + ')', - instances: generateInstancesList( instances ) - }; - }, - - refreshOn: function( editor, refresh ) { - editor.widgets.on( 'instanceCreated', function( evt ) { - refresh(); - - evt.data.on( 'data', refresh ); - } ); - - editor.widgets.on( 'instanceDestroyed', refresh ); - } - }, - - { - type: 'box', - content: - '<ul class="ckconsole_list">' + - '<li>focused: <span class="ckconsole_value" data-value="focused"></span></li>' + - '<li>selected: <span class="ckconsole_value" data-value="selected"></span></li>' + - '</ul>', - - refresh: function( editor ) { - var focused = editor.widgets.focused, - selected = editor.widgets.selected, - selectedIds = []; - - for ( var i = 0; i < selected.length; ++i ) - selectedIds.push( selected[ i ].id ); - - return { - header: 'Focus & selection', - focused: focused ? 'id: ' + focused.id : '-', - selected: selectedIds.length ? 'id: ' + selectedIds.join( ', id: ' ) : '-' - }; - }, - - refreshOn: function( editor, refresh ) { - editor.on( 'selectionCheck', refresh, null, null, 999 ); - } - }, - - { - type: 'log', - - on: function( editor, log, logFn ) { - // Add all listeners with high priorities to log - // messages in the correct order when one event depends on another. - // E.g. selectionChange triggers widget selection - if this listener - // for selectionChange will be executed later than that one, then order - // will be incorrect. - - editor.on( 'selectionChange', function( evt ) { - var msg = 'selection change', - sel = evt.data.selection, - el = sel.getSelectedElement(), - widget; - - if ( el && ( widget = editor.widgets.getByElement( el, true ) ) ) - msg += ' (id: ' + widget.id + ')'; - - log( msg ); - }, null, null, 1 ); - - editor.widgets.on( 'instanceDestroyed', function( evt ) { - log( 'instance destroyed (id: ' + evt.data.id + ')' ); - }, null, null, 1 ); - - editor.widgets.on( 'instanceCreated', function( evt ) { - log( 'instance created (id: ' + evt.data.id + ')' ); - }, null, null, 1 ); - - editor.widgets.on( 'widgetFocused', function( evt ) { - log( 'widget focused (id: ' + evt.data.widget.id + ')' ); - }, null, null, 1 ); - - editor.widgets.on( 'widgetBlurred', function( evt ) { - log( 'widget blurred (id: ' + evt.data.widget.id + ')' ); - }, null, null, 1 ); - - editor.widgets.on( 'checkWidgets', logFn( 'checking widgets' ), null, null, 1 ); - editor.widgets.on( 'checkSelection', logFn( 'checking selection' ), null, null, 1 ); - } - } - ] - } ); - - function generateInstancesList( instances ) { - var html = '', - instance; - - for ( var i = 0; i < instances.length; ++i ) { - instance = instances[ i ]; - html += itemTpl.output( { id: instance.id, name: instance.name, data: JSON.stringify( instance.data ) } ); - } - return html; - } - - function obj2Array( obj ) { - var arr = []; - for ( var id in obj ) - arr.push( obj[ id ] ); - - return arr; - } - - var itemTpl = new CKEDITOR.template( '<li>id: <code>{id}</code>, name: <code>{name}</code>, data: <code>{data}</code></li>' ); -})();
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/widget/plugin.js b/addons/website/static/lib/ckeditor/plugins/widget/plugin.js deleted file mode 100644 index 8763f663783..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/widget/plugin.js +++ /dev/null @@ -1,2180 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -'use strict'; - -(function() { - - var DRAG_HANDLER_SIZE = 14; - - CKEDITOR.plugins.add( 'widget', { - onLoad: function() { - CKEDITOR.addCss( - '.cke_widget_wrapper{' + - 'position:relative;' + - 'outline:none' + - '}' + - '.cke_widget_inline{' + - 'display:inline-block' + - '}' + - '.cke_widget_wrapper:hover>.cke_widget_element{' + - 'outline:2px solid yellow;' + - 'cursor:default' + - '}' + - '.cke_widget_wrapper:hover .cke_widget_editable{' + - 'outline:2px solid yellow' + - '}' + - '.cke_widget_wrapper.cke_widget_focused>.cke_widget_element,' + - // We need higher specificity than hover style. - '.cke_widget_wrapper .cke_widget_editable.cke_widget_editable_focused{' + - 'outline:2px solid #ace' + - '}' + - '.cke_widget_editable{' + - 'cursor:text' + - '}' + - '.cke_widget_drag_handler_container{' + - 'position:absolute;' + - 'width:' + DRAG_HANDLER_SIZE + 'px;' + - 'height:0;' + - 'opacity:0.75;' + - 'transition:height 0s 0.2s' + // Delay hiding drag handler. - '}' + - '.cke_widget_wrapper:hover>.cke_widget_drag_handler_container{' + - 'height:' + DRAG_HANDLER_SIZE + 'px;' + - 'transition:none' + - '}' + - '.cke_widget_drag_handler_container:hover{' + - 'opacity:1' + - '}'+ - 'img.cke_widget_drag_handler{' + - 'cursor:move' + - '}' + - '.cke_widget_mask{' + - 'position:absolute;' + - 'top:0;' + - 'left:0;' + - 'width:100%;' + - 'height:100%' + - '}' - ); - }, - - beforeInit: function( editor ) { - editor.widgets = new Repository( editor ); - }, - - afterInit: function( editor ) { - addWidgetButtons( editor ); - setupContextMenu( editor ); - } - } ); - - /** - * @class CKEDITOR.plugins.widget.repository - * @mixins CKEDITOR.event - */ - function Repository( editor ) { - this.editor = editor; - this.registered = {}; - this.instances = {}; - this.selected = []; - this.focused = null; - this.widgetHoldingFocusedEditable = null; - this._ = { - nextId: 0, - upcasts: [], - filters: {} - }; - - setupDataProcessing( this ); - setupWidgetsObserver( this ); - setupSelectionObserver( this ); - setupMouseObserver( this ); - setupKeyboardObserver( this ); - setupDragAndDrop( this ); - } - - Repository.prototype = { - /** - * Minimum interval between selection checks. - * - * @private - */ - MIN_SELECTION_CHECK_INTERVAL: 500, - - /** - * Minimum interval between widgets checks. - * - * @private - */ - MIN_WIDGETS_CHECK_INTERVAL: 1000, - - /** - * Adds widget definition to the repository. - * - * @param {String} name - * @param {CKEDITOR.plugins.widget.definition} widgetDef - * @returns {CKEDITOR.plugins.widget.registeredDefinition} - */ - add: function( name, widgetDef ) { - // Create prototyped copy of original widget defintion, so we won't modify it. - widgetDef = CKEDITOR.tools.prototypedCopy( widgetDef ); - widgetDef.name = name; - widgetDef.repository = this; - widgetDef.definition = widgetDef; - - widgetDef._ = widgetDef._ || {}; - - this.editor.fire( 'widgetDefinition', widgetDef ); - - if ( widgetDef.template ) - widgetDef.template = new CKEDITOR.template( widgetDef.template ); - - addWidgetCommand( this.editor, widgetDef ); - addWidgetProcessors( this, widgetDef ); - - // Register widget automatically if it does not have a button. - if ( !widgetDef.button ) - this.editor.addFeature( widgetDef ); - - this.registered[ name ] = widgetDef; - - return widgetDef; - }, - - /** - * Checks selection to update widgets states (select and focus). - * - * This method is triggered by {@link #event-checkSelection} event. - */ - checkSelection: function() { - var sel = this.editor.getSelection(), - selectedElement = sel.getSelectedElement(), - updater = stateUpdater( this ), - widget; - - // Widget is focused so commit and finish checking. - if ( selectedElement && ( widget = this.getByElement( selectedElement, true ) ) ) - return updater.focus( widget ).select( widget ).commit(); - - var range = sel.getRanges()[ 0 ]; - - // No ranges or collapsed range mean that nothing is selected, so commit and finish checking. - if ( !range || range.collapsed ) - return updater.commit(); - - // Range is not empty, so create walker checking for wrappers. - var walker = new CKEDITOR.dom.walker( range ), - wrapper; - - walker.evaluator = isWidgetWrapper2; - - while ( ( wrapper = walker.next() ) ) - updater.select( this.getByElement( wrapper ) ); - - updater.commit(); - }, - - /** - * Checks if all widgets instances are still present in DOM. - * Destroys those which are not. - * - * This method is triggered by {@link #event-checkWidigets} event. - */ - checkWidgets: function() { - if ( this.editor.mode != 'wysiwyg' ) - return; - - var toBeDestroyed = [], - editable = this.editor.editable(), - instances = this.instances, - id; - - if ( !editable ) - return; - - for ( id in instances ) { - if ( !editable.contains( instances[ id ].wrapper ) ) - this.destroy( instances[ id ], true ); - } - }, - - del: function( widget ) { - if ( this.focused === widget ) { - var editor = widget.editor, - range = editor.createRange(), - found; - - // If haven't found place for caret on the default side, - // try to find it on the other side. - if ( !( found = range.moveToClosestEditablePosition( widget.wrapper, true ) ) ) - found = range.moveToClosestEditablePosition( widget.wrapper, false ); - - if ( found ) - editor.getSelection().selectRanges( [ range ] ); - } - - widget.wrapper.remove(); - this.destroy( widget, true ); - }, - - /** - * Removes and destroys widget instance. - * - * @param {CKEDITOR.plugins.widget} widget - * @param {Boolean} [offline] Whether widget is offline (detached from DOM tree) - - * in this case DOM (attributes, classes, etc.) will not be cleaned up. - */ - destroy: function( widget, offline ) { - if ( this.widgetHoldingFocusedEditable === widget ) - setFocusedEditable( this, widget, null, offline ); - - widget.destroy( offline ); - delete this.instances[ widget.id ]; - this.fire( 'instanceDestroyed', widget ); - }, - - /** - * Removes and destroys all widgets instances. - * - * @param {Boolean} [offline] Whether widgets are offline (detached from DOM tree) - - * in this case DOM (attributes, classes, etc.) will not be cleaned up. - */ - destroyAll: function( offline ) { - var instances = this.instances, - widget; - - for ( var id in instances ) { - widget = instances[ id ]; - this.destroy( widget, offline ); - } - }, - - /** - * Gets widget instance by element which may be - * widget's wrapper or any of its children. - * - * @param {CKEDITOR.dom.element} element - * @param {Boolean} [checkWrapperOnly] Check only if `element` equals wrapper. - * @returns {CKEDITOR.plugins.widget} Widget instance or `null`. - */ - getByElement: function( element, checkWrapperOnly ) { - if ( !element ) - return null; - - var wrapper; - - for ( var id in this.instances ) { - wrapper = this.instances[ id ].wrapper; - if ( wrapper.equals( element ) || ( !checkWrapperOnly && wrapper.contains( element ) ) ) - return this.instances[ id ]; - } - - return null; - }, - - /** - * Initializes widget on given element if widget hasn't - * been initialzed on it yet. - * - * @param {CKEDITOR.dom.element} element - * @param {String/CKEDITOR.plugins.widget.definition} widgetDef Name of a widget type or a widget definition. - * Widget definition should be previously registered by {@link CKEDITOR.plugins.widget.repository#add}. - * @param startupData Widget's startup data (has precedence over defaults one). - * @returns {CKEDITOR.plugins.widget} The widget instance or null if there's no widget for given element. - */ - initOn: function( element, widgetDef, startupData ) { - if ( !widgetDef ) - widgetDef = this.registered[ element.data( 'widget' ) ]; - else if ( typeof widgetDef == 'string' ) - widgetDef = this.registered[ widgetDef ]; - - if ( !widgetDef ) - return null; - - // Wrap element if still wasn't wrapped (was added during runtime by method that skips dataProcessor). - var wrapper = this.wrapElement( element, widgetDef.name ); - - if ( wrapper ) { - // Check if widget wrapper is new (widget hasn't been initialzed on it yet). - // This class will be removed by widget constructor to avoid locking snapshot twice. - if ( wrapper.hasClass( 'cke_widget_new' ) ) { - var widget = new Widget( this, this._.nextId++, element, widgetDef, startupData ); - - // Widget could be destroyed when initializing it. - if ( widget.isInited() ) { - this.instances[ widget.id ] = widget; - - return widget; - } else - return null; - } - - // Widget already has been initialized, so try to widget by element - return this.getByElement( element ); - } - - // No wrapper means that there's no widget for this element. - return null; - }, - - /** - * Initializes widgets on all elements which were wrapped by {@link #wrapElement} and - * haven't been initialized yet. - * - * @param {CKEDITOR.dom.element} [container=editor.editable()] Container which will be checked for not - * initialized widgets. Defaults to editor's editable element. - * @returns {CKEDITOR.plugins.widget[]} Array of widget instances which have been initialized. - */ - initOnAll: function( container ) { - var newWidgets = ( container || this.editor.editable() ).find( '.cke_widget_new' ), - newInstances = [], - instance; - - for ( var i = newWidgets.count(); i--; ) { - instance = this.initOn( newWidgets.getItem( i ).getFirst( isWidgetElement2 ) ); - if ( instance ) - newInstances.push( instance ); - } - - return newInstances; - }, - - /** - * Wraps element with a widget container. - * - * If this method is called on {@link CKEDITOR.htmlParser.element}, then it will - * also take care of fixing DOM after wrapping (wrapper may not be allowed in element's parent). - * - * @param {CKEDITOR.dom.element/CKEDITOR.htmlParser.element} The widget element to be wrapperd. - * @param {String} [widgetName] - * @returns {CKEDITOR.dom.element/CKEDITOR.htmlParser.element} The wrapper element or `null` if - * widget of this type is not registered. - */ - wrapElement: function( element, widgetName ) { - var wrapper = null, - widgetDef, - isInline; - - if ( element instanceof CKEDITOR.dom.element ) { - widgetDef = this.registered[ widgetName || element.data( 'widget' ) ]; - if ( !widgetDef ) - return null; - - // Do not wrap already wrapped element. - wrapper = element.getParent(); - if ( wrapper && wrapper.type == CKEDITOR.NODE_ELEMENT && wrapper.data( 'cke-widget-wrapper' ) ) - return wrapper; - - // If attribute isn't already set (e.g. for pasted widget), set it. - if ( !element.hasAttribute( 'data-cke-widget-keep-attr' ) ) - element.data( 'cke-widget-keep-attr', element.data( 'widget' ) ? 1 : 0 ); - if ( widgetName ) - element.data( 'widget', widgetName ); - - isInline = isWidgetInline( widgetDef, element.getName() ); - - wrapper = new CKEDITOR.dom.element( isInline ? 'span' : 'div' ); - wrapper.setAttributes( getWrapperAttributes( isInline ) ); - - // Replace element unless it is a detached one. - if ( element.getParent( true ) ) - wrapper.replace( element ); - element.appendTo( wrapper ); - } - else if ( element instanceof CKEDITOR.htmlParser.element ) { - widgetDef = this.registered[ widgetName || element.attributes[ 'data-widget' ] ]; - if ( !widgetDef ) - return null; - - wrapper = element.parent; - if ( wrapper && wrapper.type == CKEDITOR.NODE_ELEMENT && wrapper.attributes[ 'data-cke-widget-wrapper' ] ) - return wrapper; - - // If attribute isn't already set (e.g. for pasted widget), set it. - if ( !( 'data-cke-widget-keep-attr' in element.attributes ) ) - element.attributes[ 'data-cke-widget-keep-attr' ] = element.attributes[ 'data-widget' ] ? 1 : 0; - if ( widgetName ) - element.attributes[ 'data-widget' ] = widgetName; - - isInline = isWidgetInline( widgetDef, element.name ); - - wrapper = new CKEDITOR.htmlParser.element( isInline ? 'span' : 'div', getWrapperAttributes( isInline ) ); - - var parent = element.parent, - index; - - // Don't detach already detached element. - if ( parent ) { - index = element.getIndex(); - element.remove(); - } - - wrapper.add( element ); - - // Insert wrapper fixing DOM (splitting parents if wrapper is not allowed inside them). - parent && insertElement( parent, index, wrapper ); - } - - return wrapper; - } - - // %REMOVE_START% - // Expose for tests. - , - getNestedEditable: getNestedEditable, - - createEditableFilter: createEditableFilter - - // %REMOVE_END% - }; - - CKEDITOR.event.implementOn( Repository.prototype ); - - - /** - * @class CKEDITOR.plugins.widget - * @mixins CKEDITOR.event - */ - function Widget( widgetsRepo, id, element, widgetDef, startupData ) { - var editor = widgetsRepo.editor; - - // Extend this widget with widgetDef-specific methods and properties. - CKEDITOR.tools.extend( this, widgetDef, { - /** - * The editor instance. - * - * @readonly - * @property {CKEDITOR.editor} - */ - editor: editor, - - /** - * This widget's unique (per editor instance) id. - * - * @readonly - * @property {Number} - */ - id: id, - - inline: element.getParent().getName() == 'span', - - /** - * Widget's main element. - * - * @readonly - * @property {CKEDITOR.dom.element} - */ - element: element, - - /** - * Widget's data object. - * - * Data can only be set by {@link #setData} method. - * - * @readonly - */ - data: CKEDITOR.tools.extend( {}, typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults ), - - /** - * Is data ready. Set to `true` when data from all sources - * ({@link CKEDITOR.plugins.widget.definition#defaults}, set - * in {@link #init} method and loaded from widget's element) - * are finally loaded. This is immediately followed by first {@link #event-data}. - * - * @readonly - */ - dataReady: false, - - // Revert what widgetDef could override (automatic #edit listener). - edit: Widget.prototype.edit, - - /** - * Contains nested editable which currently holds focus. - * - * @readonly - * @property {CKEDITOR.dom.element} - */ - focusedEditable: null, - - // WAAARNING: Overwrite widgetDef's priv object, because otherwise violent unicorn's gonna visit you. - _: { - downcastFn: ( widgetDef.downcast && typeof widgetDef.downcast == 'string' ) ? - widgetDef.downcasts[ widgetDef.downcast ] : widgetDef.downcast - } - }, true ); - - /** - * Object of widget's component elements. - * - * For every `partName => selector` pair in {@link CKEDITOR.plugins.widget.definition#parts} - * one `partName => element` pair is added to this object during - * widget initialization. - * - * @property {Object} parts - */ - - widgetsRepo.fire( 'instanceCreated', this ); - - setupWidget( this, widgetDef ); - - this.init && this.init(); - - // Finally mark widget as inited. - this.inited = true; - - setupWidgetData( this, startupData ); - - // If at some point (e.g. in #data listener) widget hasn't been destroyed - // and widget is already attached to document then fire #ready. - if ( this.isInited() && editor.editable().contains( this.wrapper ) ) { - this.ready = true; - this.fire( 'ready' ); - } - } - - Widget.prototype = { - /** - * Destroys this widget instance. - * - * Use {@link CKEDITOR.plugins.widget.repository#destroy} when possible instead of this method. - * - * This method fires {#event-destroy} event. - * - * @param {Boolean} [offline] Whether widget is offline (detached from DOM tree) - - * in this case DOM (attributes, classes, etc.) will not be cleaned up. - */ - destroy: function( offline ) { - var editor = this.editor; - - this.fire( 'destroy' ); - - if ( this.editables ) { - for ( var name in this.editables ) - this.destroyEditable( name, offline ); - } - - if ( !offline ) { - if ( this.element.data( 'cke-widget-keep-attr' ) == '0' ) - this.element.removeAttribute( 'data-widget' ); - this.element.removeAttributes( [ 'data-cke-widget-data', 'data-cke-widget-keep-attr' ] ); - this.element.removeClass( 'cke_widget_element' ); - this.element.replace( this.wrapper ); - } - - this.wrapper = null; - }, - - /** - * Destroys nested editable. - * - * @param {String} editableName Nested editable name. - * @param {Boolean} [offline] See {@link #method-destroy} method. - */ - destroyEditable: function( editableName, offline ) { - var editable = this.editables[ editableName ]; - - editable.removeListener( 'focus', onEditableFocus ); - editable.removeListener( 'blur', onEditableBlur ); - this.editor.focusManager.remove( editable ); - - if ( !offline ) { - editable.removeClass( 'cke_widget_editable' ); - editable.removeClass( 'cke_widget_editable_focused' ); - editable.removeAttributes( [ 'contenteditable', 'data-cke-widget-editable' ] ); - } - - delete this.editables[ editableName ]; - }, - - /** - * Starts widget editing. - * - * This method fires {@link CKEDITOR.plugins.widget#event-edit} event - * which may be cancelled in order to prevent from opening dialog. - * - * Dialog name is obtained from event's data `dialog` property or - * from {@link CKEDITOR.plugins.widget.definition#dialog}. - */ - edit: function() { - var evtData = { dialog: this.dialog }, - that = this; - - // Edit event was blocked, but there's no dialog to be automatically opened. - if ( !this.fire( 'edit', evtData ) || !evtData.dialog ) - return; - - this.editor.openDialog( evtData.dialog, function( dialog ) { - var showListener, - okListener; - - // Allow to add a custom dialog handler. - if ( !that.fire( 'dialog', dialog ) ) - return; - - // Make widget accessible beyond setup and commit. - dialog._.widget = that; - - showListener = dialog.on( 'show', function() { - dialog.setupContent( that ); - } ); - - okListener = dialog.on( 'ok', function() { - // Commit dialog's fields, but prevent from - // firing data event for every field. Fire only one, - // bulk event at the end. - var dataChanged, - dataListener = that.on( 'data', function( evt ) { - dataChanged = 1; - evt.cancel(); - }, null, null, 0 ); - - // Create snapshot preceeding snapshot with changed widget... - // TODO it should not be required, but it is and I found similar - // code in dialog#ok listener in dialog/plugin.js. - that.editor.fire( 'saveSnapshot' ); - dialog.commitContent( that ); - - dataListener.removeListener(); - if ( dataChanged ) { - that.fire( 'data', that.data ); - that.editor.fire( 'saveSnapshot' ); - } - } ); - - dialog.once( 'hide', function() { - showListener.removeListener(); - okListener.removeListener(); - } ); - } ); - }, - - /** - * Initializes nested editable. - * - * **Note**: only elements from {@link CKEDITOR.dtd#$editable} may become editables. - * - * @param {String} editableName The nested editable name. - * @param {CKEDITOR.plugins.widget.nestedEditableDefinition} definition The definition of nested editable. - * @returns {Boolean} Whether an editable was successfully initialized. - */ - initEditable: function( editableName, definition ) { - var editable = this.wrapper.findOne( definition.selector ); - - if ( editable && editable.is( CKEDITOR.dtd.$editable ) ) { - editable = new NestedEditable( this.editor, editable, { - filter: createEditableFilter.call( this.repository, this.name, editableName, definition ) - } ); - this.editables[ editableName ] = editable; - - editable.setAttributes( { - contenteditable: 'true', - 'data-cke-widget-editable': editableName - } ); - editable.addClass( 'cke_widget_editable' ); - // This class may be left when d&ding widget which - // had focused editable. Clean this class here, not in - // cleanUpWidgetElement for performance and code size reasons. - editable.removeClass( 'cke_widget_editable_focused' ); - - this.editor.focusManager.add( editable ); - editable.on( 'focus', onEditableFocus, this ); - CKEDITOR.env.ie && editable.on( 'blur', onEditableBlur, this ); - - // Finally, process editable's data. This data wasn't processed when loading - // editor's data, becuase they need to be processed separately, with its own filters and settings. - editable.setData( editable.getHtml() ); - - return true; - } - - return false; - }, - - /** - * Checks if widget has already been initialized. This means, for example, - * that widget has mask, element styles have been transferred to wrapper etc. - * - * @returns {Boolean} - */ - isInited: function() { - return !!( this.wrapper && this.inited ); - }, - - /** - * TODO - * - * @returns {Boolean} - */ - isReady: function() { - return this.isInited() && this.ready; - }, - - /** - * Focuses widget by selecting it. - */ - focus: function() { - var sel = this.editor.getSelection(); - - if ( sel ) - sel.fake( this.wrapper ); - - // Always focus editor (not only when focusManger.hasFocus is false) (because of #10483). - this.editor.focus(); - }, - - /** - * Sets widget value(s) in {@link #propeorty-data} object. - * If given value(s) modifies current ones {@link #event-data} event is fired. - * - * this.setData( 'align', 'left' ); - * this.data.align; // -> 'left' - * - * this.setData( { align: 'right', opened: false } ); - * this.data.align; // -> 'right' - * this.data.opened; // -> false - * - * Set values are stored in {@link #element}'s attribute (`data-cke-widget-data`), - * in JSON string, so therefore {@link #property-data} should contain - * only serializable data. - * - * @param {String/Object} keyOrData - * @param {Object} value - * @chainable - */ - setData: function( key, value ) { - var data = this.data, - modified = 0; - - if ( typeof key == 'string' ) { - if ( data[ key ] !== value ) { - data[ key ] = value; - modified = 1; - } - } - else { - var newData = key; - - for ( key in newData ) { - if ( data[ key ] !== newData[ key ] ) { - modified = 1; - data[ key ] = newData[ key ]; - } - } - } - - // Block firing data event and overwriting data element before setupWidgetData is executed. - if ( modified && this.dataReady ) { - writeDataToElement( this ); - this.fire( 'data', data ); - } - - return this; - }, - - /** - * Changes widget's focus state. Usually executed automatically after - * widget has been focused by {@link #focus} method or selection was moved - * out of widget. - * - * @param {Boolean} selected Whether to select or deselect this widget. - * @chainable - */ - setFocused: function( focused ) { - this.wrapper[ focused ? 'addClass' : 'removeClass' ]( 'cke_widget_focused' ); - this.fire( focused ? 'focus' : 'blur' ); - return this; - }, - - /** - * Changes widget's select state. Usually executed automatically after - * widget has been selected by {@link #focus} method or selection was moved - * out of widget. - * - * @param {Boolean} selected Whether to select or deselect this widget. - * @chainable - */ - setSelected: function( selected ) { - this.wrapper[ selected ? 'addClass' : 'removeClass' ]( 'cke_widget_selected' ); - this.fire( selected ? 'select' : 'deselect' ); - return this; - } - }; - - CKEDITOR.event.implementOn( Widget.prototype ); - - - /** - * Wrapper class for editable elements inside widgets. - * - * Don't use directly. Use {@link CKEDITOR.plugins.widget.definition#editables} or - * {@link CKEDITOR.plugins.widget#initEditable}. - * - * @class CKEDITOR.plugins.widget.nestedEditable - * @extends CKEDITOR.dom.element - * @constructor - * @param {CKEDITOR.editor} editor - * @param {CKEDITOR.dom.element} element - * @param config - * @param {CKEDITOR.filter} [config.filter] - */ - function NestedEditable( editor, element, config ) { - // Call the base constructor. - CKEDITOR.dom.element.call( this, element.$ ); - this.editor = editor; - this.filter = config.filter; - } - - NestedEditable.prototype = CKEDITOR.tools.extend( CKEDITOR.tools.prototypedCopy( CKEDITOR.dom.element.prototype ), { - setData: function( data ) { - data = this.editor.dataProcessor.toHtml( data, { - context: this.getName(), - filter: this.filter, - enterMode: this.filter ? this.filter.getAllowedEnterMode() : this.editor.enterMode - } ); - this.setHtml( data ); - }, - - getData: function() { - return this.editor.dataProcessor.toDataFormat( this.getHtml(), { - context: this.getName(), - filter: this.filter, - enterMode: this.filter ? this.filter.getAllowedEnterMode() : this.editor.enterMode - } ); - } - } ); - - - // - // REPOSITORY helpers ----------------------------------------------------- - // - - function addWidgetButtons( editor ) { - var widgets = editor.widgets.registered, - widget, - widgetName, - widgetButton; - - for ( widgetName in widgets ) { - widget = widgets[ widgetName ]; - - // Create button if defined. - widgetButton = widget.button; - if ( widgetButton && editor.ui.addButton ) { - editor.ui.addButton( CKEDITOR.tools.capitalize( widget.name, true ), { - label: widgetButton, - command: widget.name, - toolbar: 'insert,10' - } ); - } - } - } - - // Create a command creating and editing widget. - // - // @param editor - // @param {CKEDITOR.plugins.widget.registeredDefinition} widgetDef - function addWidgetCommand( editor, widgetDef ) { - editor.addCommand( widgetDef.name, { - exec: function() { - var focused = editor.widgets.focused; - // If a widget of the same type is focused, start editing. - if ( focused && focused.name == widgetDef.name ) - focused.edit(); - // Otherwise... - // ... use insert method is was defined. - else if ( widgetDef.insert ) - widgetDef.insert(); - // ... or create a brand-new widget from template. - else if ( widgetDef.template ) { - var defaults = typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults, - element = CKEDITOR.dom.element.createFromHtml( widgetDef.template.output( defaults ) ), - instance, - wrapper = editor.widgets.wrapElement( element, widgetDef.name ), - temp = new CKEDITOR.dom.documentFragment( wrapper.getDocument() ), - editWasCanceled = true; - - // Append wrapper to a temporary document. This will unify the environment - // in which #data listeners work when creating and editing widget. - temp.append( wrapper ); - instance = editor.widgets.initOn( element, widgetDef ); - - // Instance could be destroyed during initialization. - // In this case finalize creation if some new widget - // was left in temporary document fragment. - if ( !instance ) { - finalizeCreation(); - return; - } - - // Listen on edit to finalize widget insertion. - // - // * If dialog was set, then insert widget after dialog was successfully saved or destroy this - // temporary instance. - // * If dialog wasn't set and edit wasn't canceled, insert widget. - var editListener = instance.once( 'edit', function( evt ) { - editWasCanceled = false; - - if ( evt.data.dialog ) { - instance.once( 'dialog', function( evt ) { - var dialog = evt.data, - okListener, - cancelListener; - - // Finalize creation AFTER (20) new data was set. - okListener = dialog.once( 'ok', finalizeCreation, null, null, 20 ); - - cancelListener = dialog.once( 'cancel', function() { - editor.widgets.destroy( instance, true ); - } ); - - dialog.once( 'hide', function() { - okListener.removeListener(); - cancelListener.removeListener(); - } ); - } ); - } - // Dialog hasn't been set, so insert widget now. - else - finalizeCreation(); - }, null, null, 999 ); - - instance.edit(); - - // Remove listener in case someone canceled it before this - // listener was executed. - editListener.removeListener(); - - // In case edit was canceled - finalize creation here which should happen anyway (just without - // initial edit). - if ( editWasCanceled ) - finalizeCreation(); - } - - function finalizeCreation() { - var wrapper = temp.getFirst(); - if ( wrapper && isWidgetWrapper2( wrapper ) ) { - editor.insertElement( wrapper ); - - var widget = editor.widgets.getByElement( wrapper ); - // Fire postponed #ready event. - widget.ready = true; - widget.fire( 'ready' ); - widget.focus(); - } - } - }, - - refresh: function( editor, path ) { - // Disable widgets' commands inside nested editables - - // check if blockLimit is a nested editable or a descendant of any. - this.setState( getNestedEditable( editor.editable(), path.blockLimit ) ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); - }, - // A hack to force command refreshing on context change. - context: 'div', - - allowedContent: widgetDef.allowedContent, - requiredContent: widgetDef.requiredContent, - contentForms: widgetDef.contentForms, - contentTransformations: widgetDef.contentTransformations - } ); - } - - function addWidgetProcessors( widgetsRepo, widgetDef ) { - var upcast = widgetDef.upcast, - upcasts; - - if ( !upcast ) - return; - - // Multiple upcasts defined in string. - if ( typeof upcast == 'string' ) { - upcasts = upcast.split( ',' ); - while ( upcasts.length ) - widgetsRepo._.upcasts.push( [ widgetDef.upcasts[ upcasts.pop() ], widgetDef.name ] ); - } - // Single rule which is automatically activated. - else - widgetsRepo._.upcasts.push( [ upcast, widgetDef.name ] ); - } - - function blurWidget( widgetsRepo, widget ) { - widgetsRepo.focused = null; - - if ( widget.isInited() ) { - // Widget could be destroyed in the meantime - e.g. data could be set. - widgetsRepo.fire( 'widgetBlurred', { widget: widget } ); - widget.setFocused( false ); - } - } - - // Unwraps widget element and clean up element. - // - // This function is used to clean up pasted widgets. - // It should have similar result to widget#destroy plus - // some additional adjustments, specific for pasting. - // - // @param {CKEDITOR.htmlParser.element} el - function cleanUpWidgetElement( el ) { - var parent = el.parent; - if ( parent.type == CKEDITOR.NODE_ELEMENT && parent.attributes[ 'data-cke-widget-wrapper' ] ) - parent.replaceWith( el ); - } - - // Similar to cleanUpWidgetElement, but works on DOM and finds - // widget elements by its own. - // - // Unlike cleanUpWidgetElement it will wrap element back. - // - // @param {CKEDITOR.dom.element} container - function cleanUpAllWidgetElements( widgetsRepo, container ) { - var wrappers = container.find( '.cke_widget_wrapper' ), - wrapper, element, - i = 0, - l = wrappers.count(); - - for ( ; i < l; ++i ) { - wrapper = wrappers.getItem( i ); - element = wrapper.getFirst( isWidgetElement2 ); - // If wrapper contains widget element - unwrap it and wrap again. - if ( element.type == CKEDITOR.NODE_ELEMENT && element.data( 'widget' ) ) { - element.replace( wrapper ); - widgetsRepo.wrapElement( element ); - } - // Otherwise - something is wrong... clean this up. - else - wrapper.remove(); - } - } - - // Creates {@link CKEDITOR.filter} instance for given widget, editable and rules. - // - // Once filter for widget-editable pair is created it is cached, so the same instance - // will be returned when method is executed again. - // - // @param {String} widgetName - // @param {String} editableName - // @param {CKEDITOR.plugins.widget.nestedEditableDefinition} editableDefinition The nested editable definition. - // @returns {CKEDITOR.filter} Filter instance or `null` if rules are not defined. - // @context CKEDITOR.plugins.widget.repository - function createEditableFilter( widgetName, editableName, editableDefinition ) { - if ( !editableDefinition.allowedContent ) - return null; - - var editables = this._.filters[ widgetName ]; - - if ( !editables ) - this._.filters[ widgetName ] = editables = {}; - - var filter = editables[ editableName ]; - - if ( !filter ) - editables[ editableName ] = filter = new CKEDITOR.filter( editableDefinition.allowedContent ); - - return filter; - } - - // Gets nested editable if node is its descendant or the editable itself. - // - // @param {CKEDITOR.dom.element} guard Stop ancestor search on this node (usually editor's editable). - // @param {CKEDITOR.dom.node} node Start search from this node. - // @returns {CKEDITOR.dom.element} Element or null. - function getNestedEditable( guard, node ) { - if ( !node || node.equals( guard ) ) - return null; - - if ( isNestedEditable2( node ) ) - return node; - - return getNestedEditable( guard, node.getParent() ); - } - - function getWrapperAttributes( inlineWidget ) { - return { - // tabindex="-1" means that it can receive focus by code. - tabindex: -1, - contenteditable: 'false', - 'data-cke-widget-wrapper': 1, - 'data-cke-filter': 'off', - // Class cke_widget_new marks widgets which haven't been initialized yet. - 'class': 'cke_widget_wrapper cke_widget_new cke_widget_' + - ( inlineWidget ? 'inline' : 'block' ) - }; - } - - // Inserts element at given index. - // It will check DTD and split ancestor elements up to the first - // that can contain this element. - // - // @param {CKEDITOR.htmlParser.element} parent - // @param {Number} index - // @param {CKEDITOR.htmlParser.element} element - function insertElement( parent, index, element ) { - // Do not split doc fragment... - if ( parent.type == CKEDITOR.NODE_ELEMENT ) { - var parentAllows = CKEDITOR.dtd[ parent.name ]; - // Parent element is known (included in DTD) and cannot contain - // this element. - if ( parentAllows && !parentAllows[ element.name ] ) { - var parent2 = parent.split( index ), - parentParent = parent.parent; - - // Element will now be inserted at right parent's index. - index = parent2.getIndex(); - - // If left part of split is empty - remove it. - if ( !parent.children.length ) { - index -= 1; - parent.remove(); - } - - // If right part of split is empty - remove it. - if ( !parent2.children.length ) - parent2.remove(); - - // Try inserting as grandpas' children. - return insertElement( parentParent, index, element ); - } - } - - // Finally we can add this element. - parent.add( element, index ); - } - - // @param {CKEDITOR.htmlParser.element} - function isWidgetElement( element ) { - return element.type == CKEDITOR.NODE_ELEMENT && !!element.attributes[ 'data-widget' ]; - } - - // @param {CKEDITOR.dom.element} - function isWidgetElement2( element ) { - return element.type == CKEDITOR.NODE_ELEMENT && element.hasAttribute( 'data-widget' ); - } - - // Whether for this definition and element widget should be created in inline or block mode. - function isWidgetInline( widgetDef, elementName ) { - return typeof widgetDef.inline == 'boolean' ? widgetDef.inline : !!CKEDITOR.dtd.$inline[ elementName ]; - } - - // @param {CKEDITOR.htmlParser.element} - function isWidgetWrapper( element ) { - return element.type == CKEDITOR.NODE_ELEMENT && element.attributes[ 'data-cke-widget-wrapper' ]; - } - - // @param {CKEDITOR.dom.element} - function isWidgetWrapper2( element ) { - return element.type == CKEDITOR.NODE_ELEMENT && element.hasAttribute( 'data-cke-widget-wrapper' ); - } - - // @param {CKEDITOR.dom.element} - function isNestedEditable2( node ) { - return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-editable' ); - } - - function moveSelectionToDropPosition( editor, dropEvt ) { - var $evt = dropEvt.data.$, - $range, - range = editor.createRange(); - - // Make testing possible. - if ( dropEvt.data.testRange ) { - dropEvt.data.testRange.select(); - return; - } - - // Webkits. - if ( document.caretRangeFromPoint ) { - $range = editor.document.$.caretRangeFromPoint( $evt.clientX, $evt.clientY ); - range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset ); - range.collapse( true ); - } - // FF. - else if ( $evt.rangeParent ) { - range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset ); - range.collapse( true ); - } - // IEs. - else if ( document.body.createTextRange ) { - $range = editor.document.getBody().$.createTextRange(); - $range.moveToPoint( $evt.clientX, $evt.clientY ); - var id = 'cke-temp-' + ( new Date() ).getTime(); - $range.pasteHTML( '<span id="' + id + '">\u200b</span>' ); - - var span = editor.document.getById( id ); - range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START ); - span.remove(); - } - - range.select(); - } - - function moveWidget( editor, sourceWidget ) { - var widgetHtml = sourceWidget.wrapper.getOuterHtml(); - - sourceWidget.wrapper.remove(); - editor.widgets.destroy( sourceWidget, true ); - - // Create snapshot for the removed widget. - editor.fire( 'saveSnapshot' ); - - // Lock snapshot while pasting to merge those changes with the previous snapshot. - // This way we are grouping all changes done by moveWidget into one snapshot. - editor.fire( 'lockSnapshot' ); - editor.execCommand( 'paste', widgetHtml ); - editor.fire( 'unlockSnapshot' ); - } - - function onEditableKey( widget, keyCode ) { - var focusedEditable = widget.focusedEditable, - range; - - // CTRL+A. - if ( keyCode == CKEDITOR.CTRL + 65 ) { - var bogus = focusedEditable.getBogus(); - - range = widget.editor.createRange(); - range.selectNodeContents( focusedEditable ); - // Exclude bogus if exists. - if ( bogus ) - range.setEndAt( bogus, CKEDITOR.POSITION_BEFORE_START ); - - range.select(); - // Cancel event - block default. - return false; - } - // DEL or BACKSPACE. - else if ( keyCode == 8 || keyCode == 46 ) { - var ranges = widget.editor.getSelection().getRanges(); - - range = ranges[ 0 ]; - - // Block del or backspace if at editable's boundary. - return !( ranges.length == 1 && range.collapsed && - range.checkBoundaryOfElement( focusedEditable, CKEDITOR[ keyCode == 8 ? 'START' : 'END' ] ) ); - } - } - - function setFocusedEditable( widgetsRepo, widget, editableElement, offline ) { - widgetsRepo.editor.fire( 'lockSnapshot' ); - - if ( editableElement ) { - var editableName = editableElement.data( 'cke-widget-editable' ), - editableInstance = widget.editables[ editableName ]; - - widgetsRepo.widgetHoldingFocusedEditable = widget; - widget.focusedEditable = editableInstance; - editableElement.addClass( 'cke_widget_editable_focused' ); - - if ( editableInstance.filter ) - widgetsRepo.editor.setActiveFilter( editableInstance.filter ); - } else { - if ( !offline ) - widget.focusedEditable.removeClass( 'cke_widget_editable_focused' ); - - widget.focusedEditable = null; - widgetsRepo.widgetHoldingFocusedEditable = null; - widgetsRepo.editor.setActiveFilter( null ); - } - - widgetsRepo.editor.fire( 'unlockSnapshot' ); - } - - function setupContextMenu( editor ) { - if ( !editor.contextMenu ) - return; - - editor.contextMenu.addListener( function( element ) { - var widget = editor.widgets.getByElement( element, true ); - - if ( widget ) - return widget.fire( 'contextMenu', {} ); - } ); - } - - // Set up data processing like: - // * toHtml/toDataFormat, - // * pasting handling, - // * undo/redo handling. - function setupDataProcessing( widgetsRepo ) { - var editor = widgetsRepo.editor; - - setupUpcasting( widgetsRepo ); - setupDowncasting( widgetsRepo ); - - editor.on( 'contentDomUnload', function() { - widgetsRepo.destroyAll( true ); - } ); - - // Handle pasted single widget. - editor.on( 'paste', function( evt ) { - evt.data.dataValue = evt.data.dataValue.replace( - /^(?:<div id="cke_copybin">)?<span [^>]*data-cke-copybin-start="1"[^>]*>.?<\/span>([\s\S]+)<span [^>]*data-cke-copybin-end="1"[^>]*>.?<\/span>(?:<\/div>)?$/, - '$1' - ); - } ); - } - - function setupDowncasting( widgetsRepo ) { - var editor = widgetsRepo.editor, - downcastingSessions = {}, - nestedEditableScope = false; - - // Listen before htmlDP#htmlFilter is applied to cache all widgets, because we'll - // loose data-cke-* attributes. - editor.on( 'toDataFormat', function( evt ) { - // To avoid conflicts between htmlDP#toDF calls done at the same time - // (e.g. nestedEditable#getData called during downcasting some widget) - // mark every toDataFormat event chain with the downcasting session id. - var id = CKEDITOR.tools.getNextNumber(), - toBeDowncasted = []; - evt.data.downcastingSessionId = id; - downcastingSessions[ id ] = toBeDowncasted; - - evt.data.dataValue.forEach( function( element ) { - var attrs = element.attributes, - widget, widgetElement; - - // Wrapper. - // Perform first part of downcasting (cleanup) and cache widgets, - // because after applying DP's filter all data-cke-* attributes will be gone. - if ( 'data-cke-widget-id' in attrs ) { - widget = widgetsRepo.instances[ attrs[ 'data-cke-widget-id' ] ]; - if ( widget ) { - widgetElement = element.getFirst( isWidgetElement ); - toBeDowncasted.push( { - wrapper: element, - element: widgetElement, - widget: widget - } ); - - // If widget did not have data-cke-widget attribute before upcasting remove it. - if ( widgetElement.attributes[ 'data-cke-widget-keep-attr' ] != '1' ) - delete widgetElement.attributes[ 'data-widget' ]; - } - } - // Nested editable. - else if ( 'data-cke-widget-editable' in attrs ) { - delete attrs[ 'contenteditable' ]; - - // Replace nested editable's content with its output data. - var editable = toBeDowncasted[ toBeDowncasted.length - 1 ].widget.editables[ attrs[ 'data-cke-widget-editable' ] ]; - element.setHtml( editable.getData() ); - - // Don't check children - there won't be next wrapper or nested editable which we - // should process in this session. - return false; - } - }, CKEDITOR.NODE_ELEMENT ); - }, null, null, 8 ); - - // Listen after dataProcessor.htmlFilter and ACF were applied - // so wrappers securing widgets' contents are removed after all filtering was done. - editor.on( 'toDataFormat', function( evt ) { - // Ignore some unmarked sessions. - if ( !evt.data.downcastingSessionId ) - return; - - var toBeDowncasted = downcastingSessions[ evt.data.downcastingSessionId ], - toBe, widget, widgetElement, retElement; - - while ( ( toBe = toBeDowncasted.shift() ) ) { - widget = toBe.widget; - widgetElement = toBe.element; - retElement = widget._.downcastFn && widget._.downcastFn.call( widget, widgetElement ); - - // Returned element always defaults to widgetElement. - if ( !retElement ) - retElement = widgetElement; - - toBe.wrapper.replaceWith( retElement ); - } - }, null, null, 13 ); - } - - function setupDragAndDrop( widgetsRepo ) { - var editor = widgetsRepo.editor; - - editor.on( 'contentDom', function() { - var editable = editor.editable(); - - editable.attachListener( editable, 'drop', function( evt ) { - var dataStr = evt.data.$.dataTransfer.getData( 'text' ), - dataObj, - sourceWidget; - - if ( !dataStr ) - return; - - try { - dataObj = JSON.parse( dataStr ); - } catch ( e ) { - // Do nothing - data couldn't be parsed so it's not a CKEditor's data. - return; - } - - if ( dataObj.type != 'cke-widget' ) - return; - - evt.data.preventDefault(); - - // Something went wrong... maybe someone is dragging widgets between editors/windows/tabs/browsers/frames. - if ( dataObj.editor != editor.name || !( sourceWidget = widgetsRepo.instances[ dataObj.id ] ) ) - return; - - // Save the snapshot with the state before moving widget. - // TODO unfortunately at this stage widget is not focused any more so - // undoing will not select widget which was moved. - editor.fire( 'saveSnapshot' ); - - moveSelectionToDropPosition( editor, evt ); - - // Hack to prevent cursor loss on Firefox. Without timeout widget is - // correctly pasted but then cursor is invisible (although it works) and can be restored - // only by blurring editable. - if ( CKEDITOR.env.gecko ) - setTimeout( moveWidget, 0, editor, sourceWidget ); - else - moveWidget( editor, sourceWidget ); - } ); - } ); - } - - // Setup mouse observer which will trigger: - // * widget focus on widget click, - // * widget#doubleclick forwarded from editor#doubleclick. - function setupMouseObserver( widgetsRepo ) { - var editor = widgetsRepo.editor; - - editor.on( 'contentDom', function() { - var editable = editor.editable(), - evtRoot = editable.isInline() ? editable : editor.document, - widget, - mouseDownOnDragHandler; - - editable.attachListener( evtRoot, 'mousedown', function( evt ) { - var target = evt.data.getTarget(); - - widget = widgetsRepo.getByElement( target ); - mouseDownOnDragHandler = 0; // Reset. - - // Ignore mousedown on drag and drop handler. - if ( target.type == CKEDITOR.NODE_ELEMENT && target.hasAttribute( 'data-cke-widget-drag-handler' ) ) { - mouseDownOnDragHandler = 1; - return; - } - - // Widget was clicked, but not editable nested in it. - if ( widget ) { - if ( !getNestedEditable( widget.wrapper, target ) ) { - evt.data.preventDefault(); - if ( !CKEDITOR.env.ie ) - widget.focus(); - } - // Reset widget so mouseup listener is not confused. - else - widget = null; - } - } ); - - // Focus widget on mouseup if mousedown was fired on drag handler. - // Note: mouseup won't be fired at all if widget was dragged and dropped, so - // this code will be executed only when drag handler was clicked. - editable.attachListener( evtRoot, 'mouseup', function() { - if ( widget && mouseDownOnDragHandler ) { - mouseDownOnDragHandler = 0; - widget.focus(); - } - } ); - - // On IE it is not enough to block mousedown. If widget wrapper (element with - // contenteditable=false attribute) is clicked directly (it is a target), - // then after mouseup/click IE will select that element. - // It is not possible to prevent that default action, - // so we force fake selection after everything happened. - if ( CKEDITOR.env.ie ) { - editable.attachListener( evtRoot, 'mouseup', function( evt ) { - if ( widget ) { - setTimeout( function() { - widget.focus(); - widget = null; - } ); - } - } ); - } - } ); - - editor.on( 'doubleclick', function( evt ) { - var widget = widgetsRepo.getByElement( evt.data.element ); - - // Not in widget or in nested editable. - if ( !widget || getNestedEditable( widget.wrapper, evt.data.element ) ) - return; - - return widget.fire( 'doubleclick', { element: evt.data.element } ); - }, null, null, 1 ); - } - - // Setup editor#key observer which will forward it - // to focused widget. - function setupKeyboardObserver( widgetsRepo ) { - var editor = widgetsRepo.editor; - - editor.on( 'key', function( evt ) { - var focused = widgetsRepo.focused, - widgetHoldingFocusedEditable = widgetsRepo.widgetHoldingFocusedEditable, - ret; - - if ( focused ) - ret = focused.fire( 'key', { keyCode: evt.data.keyCode } ); - else if ( widgetHoldingFocusedEditable ) - ret = onEditableKey( widgetHoldingFocusedEditable, evt.data.keyCode ); - - return ret; - }, null, null, 1 ); - } - - // Setup selection observer which will trigger: - // * widget select & focus on selection change, - // * nested editable focus (related properites and classes) on selection change, - // * deselecting and blurring all widgets on data, - // * blurring widget on editor blur. - function setupSelectionObserver( widgetsRepo ) { - var editor = widgetsRepo.editor; - - editor.on( 'selectionCheck', function() { - widgetsRepo.fire( 'checkSelection' ); - } ); - - widgetsRepo.on( 'checkSelection', widgetsRepo.checkSelection, widgetsRepo ); - - editor.on( 'selectionChange', function( evt ) { - var nestedEditable = getNestedEditable( editor.editable(), evt.data.selection.getStartElement() ), - newWidget = nestedEditable && widgetsRepo.getByElement( nestedEditable ), - oldWidget = widgetsRepo.widgetHoldingFocusedEditable; - - if ( oldWidget ) { - if ( oldWidget !== newWidget || !oldWidget.focusedEditable.equals( nestedEditable ) ) { - setFocusedEditable( widgetsRepo, oldWidget, null ); - - if ( newWidget && nestedEditable ) - setFocusedEditable( widgetsRepo, newWidget, nestedEditable ); - } - } - // It may happen that there's no widget even if editable was found - - // e.g. if selection was automatically set in editable although widget wasn't initialized yet. - else if ( newWidget && nestedEditable ) - setFocusedEditable( widgetsRepo, newWidget, nestedEditable ); - } ); - - // Invalidate old widgets early - immediately on dataReady. - editor.on( 'dataReady', function( evt ) { - // Deselect and blur all widgets. - stateUpdater( widgetsRepo ).commit(); - } ); - - editor.on( 'blur', function() { - var widget; - - if ( ( widget = widgetsRepo.focused ) ) - blurWidget( widgetsRepo, widget ); - - if ( ( widget = widgetsRepo.widgetHoldingFocusedEditable ) ) - setFocusedEditable( widgetsRepo, widget, null ); - } ); - } - - function setupUpcasting( widgetsRepo ) { - var editor = widgetsRepo.editor, - upcasts = widgetsRepo._.upcasts, - processedWidgetOnly, - snapshotLoaded; - - editor.on( 'dataReady', function() { - // Clean up all widgets loaded from snapshot. - if ( snapshotLoaded ) - cleanUpAllWidgetElements( widgetsRepo, editor.editable() ); - snapshotLoaded = 0; - - // Some widgets were destroyed on contentDomUnload, - // some on loadSnapshot, but that does not include - // e.g. setHtml on inline editor or widgets removed just - // before setting data. - widgetsRepo.destroyAll( true ); - widgetsRepo.initOnAll(); - } ); - - editor.on( 'afterPaste', function() { - editor.fire( 'lockSnapshot' ); - - // Init is enough (no clean up needed), - // because inserted widgets were cleaned up by toHtml. - var newInstances = widgetsRepo.initOnAll(); - - // If just a widget was pasted and nothing more focus it. - if ( processedWidgetOnly && newInstances.length == 1 ) - newInstances[ 0 ].focus(); - - editor.fire( 'unlockSnapshot' ); - } ); - - // Set flag so dataReady will know that additional - // cleanup is needed, because snapshot containing widgets was loaded. - editor.on( 'loadSnapshot', function( evt ) { - // Primitive but sufficient check which will prevent from executing - // heavier cleanUpAllWidgetElements if not needed. - if ( ( /data-cke-widget/ ).test( evt.data ) ) - snapshotLoaded = 1; - - widgetsRepo.destroyAll( true ); - }, null, null, 9 ); - - // Listen after ACF (so data are filtered), - // but before dataProcessor.dataFilter was applied (so we can secure widgets' internals). - editor.on( 'toHtml', function( evt ) { - var toBeWrapped = [], - toBe, - element; - - evt.data.dataValue.forEach( function( element ) { - // Wrapper found - find widget element, add it to be - // cleaned up (unwrapped) and wrapped and stop iterating in this branch. - if ( 'data-cke-widget-wrapper' in element.attributes ) { - element = element.getFirst( isWidgetElement ); - - if ( element ) - toBeWrapped.push( [ element ] ); - - // Do not iterate over descendants. - return false; - } - // Widget element found - add it to be cleaned up (just in case) - // and wrapped and stop iterating in this branch. - else if ( 'data-widget' in element.attributes ) { - toBeWrapped.push( [ element ] ); - - // Do not iterate over descendants. - return false; - } - else if ( upcasts.length ) { - var upcast, upcasted, - data, - i = 0, - l = upcasts.length; - - for ( ; i < l; ++i ) { - upcast = upcasts[ i ]; - data = {}; - - if ( ( upcasted = upcast[ 0 ]( element, data ) ) ) { - // If upcast function returned element, upcast this one. - // It can be e.g. a new element wrapping the original one. - if ( upcasted instanceof CKEDITOR.htmlParser.element ) - element = upcasted; - - // Set initial data attr with data from upcast method. - element.attributes[ 'data-cke-widget-data' ] = JSON.stringify( data ); - - toBeWrapped.push( [ element, upcast[ 1 ] ] ); - - // Do not iterate over descendants. - return false; - } - } - } - }, CKEDITOR.NODE_ELEMENT ); - - // Clean up and wrap all queued elements. - while ( ( toBe = toBeWrapped.pop() ) ) { - cleanUpWidgetElement( toBe[ 0 ] ); - widgetsRepo.wrapElement( toBe[ 0 ], toBe[ 1 ] ); - } - - // Used to determine whether only widget was pasted. - processedWidgetOnly = evt.data.dataValue.children.length == 1 && - isWidgetWrapper( evt.data.dataValue.children[ 0 ] ); - }, null, null, 8 ); - } - - // Setup observer which will trigger checkWidgets on: - // * keyup. - function setupWidgetsObserver( widgetsRepo ) { - var editor = widgetsRepo.editor, - buffer = CKEDITOR.tools.eventsBuffer( widgetsRepo.MIN_WIDGETS_CHECK_INTERVAL, function() { - widgetsRepo.fire( 'checkWidgets' ); - } ), - ignoredKeys = { 16:1,17:1,18:1,37:1,38:1,39:1,40:1,225:1 }; // SHIFT,CTRL,ALT,LEFT,UP,RIGHT,DOWN,RIGHT ALT(FF) - - editor.on( 'contentDom', function() { - var editable = editor.editable(); - - // Schedule check on keyup, but not more often than once per MIN_CHECK_DELAY. - editable.attachListener( editable.isInline() ? editable : editor.document, 'keyup', function( evt ) { - if ( !( evt.data.getKey() in ignoredKeys ) ) - buffer.input(); - }, null, null, 999 ); - } ); - - editor.on( 'contentDomUnload', buffer.reset ); - - widgetsRepo.on( 'checkWidgets', widgetsRepo.checkWidgets, widgetsRepo ); - } - - // Helper for coordinating which widgets should be - // selected/deselected and which one should be focused/blurred. - function stateUpdater( widgetsRepo ) { - var currentlySelected = widgetsRepo.selected, - toBeSelected = [], - toBeDeselected = currentlySelected.slice( 0 ), - focused = null; - - return { - select: function( widget ) { - if ( CKEDITOR.tools.indexOf( currentlySelected, widget ) < 0 ) - toBeSelected.push( widget ); - - var index = CKEDITOR.tools.indexOf( toBeDeselected, widget ); - if ( index >= 0 ) - toBeDeselected.splice( index, 1 ); - - return this; - }, - - focus: function( widget ) { - focused = widget; - return this; - }, - - commit: function() { - var focusedChanged = widgetsRepo.focused !== focused, - widget; - - widgetsRepo.editor.fire( 'lockSnapshot' ); - - if ( focusedChanged && ( widget = widgetsRepo.focused ) ) { - blurWidget( widgetsRepo, widget ); - } - - while ( ( widget = toBeDeselected.pop() ) ) { - currentlySelected.splice( CKEDITOR.tools.indexOf( currentlySelected, widget ), 1 ); - // Widget could be destroyed in the meantime - e.g. data could be set. - if ( widget.isInited() ) - widget.setSelected( false ); - } - - if ( focusedChanged && focused ) { - widgetsRepo.focused = focused; - widgetsRepo.fire( 'widgetFocused', { widget: focused } ); - focused.setFocused( true ); - } - - while ( ( widget = toBeSelected.pop() ) ) { - currentlySelected.push( widget ); - widget.setSelected( true ); - } - - widgetsRepo.editor.fire( 'unlockSnapshot' ); - } - }; - } - - - // - // WIDGET helpers --------------------------------------------------------- - // - - var transparentImageData = 'data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D', - // LEFT, RIGHT, UP, DOWN, DEL, BACKSPACE - unblock default fake sel handlers. - keystrokesNotBlockedByWidget = { 37:1,38:1,39:1,40:1,8:1,46:1 }; - - function cancel( evt ) { - evt.cancel(); - } - - function copySingleWidget( widget, isCut ) { - var editor = widget.editor, - copybin = new CKEDITOR.dom.element( 'div', editor.document ); - - copybin.setAttributes( { - id: 'cke_copybin' - } ); - - copybin.setHtml( '<span data-cke-copybin-start="1">\u200b</span>' + widget.wrapper.getOuterHtml() + '<span data-cke-copybin-end="1">\u200b</span>' ); - - // Save snapshot with the current state. - editor.fire( 'saveSnapshot' ); - - // Ignore copybin. - editor.fire( 'lockSnapshot' ); - - editor.editable().append( copybin ); - - var listener1 = editor.on( 'selectionChange', cancel, null, null, 0 ), - listener2 = widget.repository.on( 'checkSelection', cancel, null, null, 0 ); - - // Once the clone of the widget is inside of copybin, select - // the entire contents. This selection will be copied by the - // native browser's clipboard system. - var range = editor.createRange(); - range.selectNodeContents( copybin ); - range.select(); - - setTimeout( function() { - copybin.remove(); - - if ( !isCut ) - widget.focus(); - - listener1.removeListener(); - listener2.removeListener(); - - editor.fire( 'unlockSnapshot' ); - - if ( isCut ) { - widget.repository.del( widget ); - editor.fire( 'saveSnapshot' ); - } - }, 0 ); - } - - // [IE] Force keeping focus because IE sometimes forgets to fire focus on main editable - // when blurring nested editable. - // @context widget - function onEditableBlur() { - var active = CKEDITOR.document.getActive(), - editor = this.editor, - editable = editor.editable(); - - // If focus stays within editor override blur and set currentActive because it should be - // automatically changed to editable on editable#focus but it is not fired. - if ( ( editable.isInline() ? editable : editor.document.getWindow().getFrame() ).equals( active ) ) - editor.focusManager.focus( editable ); - } - - // Force selectionChange when editable was focused. - // Similar to hack in selection.js#~620. - // @context widget - function onEditableFocus() { - // Gecko does not support 'DOMFocusIn' event on which we unlock selection - // in selection.js to prevent selection locking when entering nested editables. - if ( CKEDITOR.env.gecko ) - this.editor.unlockSelection(); - - // We don't need to force selectionCheck on Webkit, because on Webkit - // we do that on DOMFocusIn in selection.js. - if ( !CKEDITOR.env.webkit ) { - this.editor.forceNextSelectionCheck(); - this.editor.selectionChange( 1 ); - } - } - - // Position drag handler according to the widget's element position. - function positionDragHandler( widget ) { - var handler = widget.dragHandlerContainer; - - handler.setStyle( 'top', widget.element.$.offsetTop - DRAG_HANDLER_SIZE + 'px' ); - handler.setStyle( 'left', widget.element.$.offsetLeft + 'px' ); - } - - function setupDragHandler( widget ) { - var editor = widget.editor, - img = new CKEDITOR.dom.element( 'img', editor.document ), - container = new CKEDITOR.dom.element( 'span', editor.document ); - - container.setAttributes( { - 'class': 'cke_widget_drag_handler_container', - // Split background and background-image for IE8 which will break on rgba(). - style: 'background:rgba(220,220,220,0.5);background-image:url(' + editor.plugins.widget.path + 'images/handle.png)' - } ); - - img.setAttributes( { - draggable: 'true', - 'class': 'cke_widget_drag_handler', - 'data-cke-widget-drag-handler': '1', - src: transparentImageData, - width: DRAG_HANDLER_SIZE, - height: DRAG_HANDLER_SIZE - } ); - - img.on( 'dragstart', function( evt ) { - evt.data.$.dataTransfer.setData( 'text', JSON.stringify( { type: 'cke-widget', editor: editor.name, id: widget.id } ) ); - } ); - - container.append( img ); - widget.wrapper.append( container ); - widget.dragHandlerContainer = container; - } - - function setupEditables( widget ) { - var editableName, - editableDef, - definedEditables = widget.editables; - - widget.editables = {}; - - if ( !widget.editables ) - return; - - for ( editableName in definedEditables ) { - editableDef = definedEditables[ editableName ]; - widget.initEditable( editableName, typeof editableDef == 'string' ? { selector: editableDef } : editableDef ); - } - } - - function setupMask( widget ) { - if ( !widget.mask ) - return; - - var img = new CKEDITOR.dom.element( 'img', widget.editor.document ); - img.setAttributes( { - src: transparentImageData, - 'class': 'cke_widget_mask' - } ); - widget.wrapper.append( img ); - widget.mask = img; - } - - // Replace parts object containing: - // partName => selector pairs - // with: - // partName => element pairs - function setupParts( widget ) { - if ( widget.parts ) { - var parts = {}, - el, partName; - - for ( partName in widget.parts ) { - el = widget.wrapper.findOne( widget.parts[ partName ] ); - parts[ partName ] = el; - } - widget.parts = parts; - } - } - - function setupWidget( widget, widgetDef ) { - setupWrapper( widget ); - setupParts( widget ); - setupEditables( widget ); - setupMask( widget ); - setupDragHandler( widget ); - - widget.wrapper.removeClass( 'cke_widget_new' ); - widget.element.addClass( 'cke_widget_element' ); - - widget.on( 'key', function( evt ) { - var keyCode = evt.data.keyCode; - - // ENTER. - if ( keyCode == 13 ) - widget.edit(); - // CTRL+C or CTRL+X. - else if ( keyCode == CKEDITOR.CTRL + 67 || keyCode == CKEDITOR.CTRL + 88 ) { - copySingleWidget( widget, keyCode == CKEDITOR.CTRL + 88 ); - return; // Do not preventDefault. - } - // Pass chosen keystrokes to other plugins or default fake sel handlers. - // Pass all CTRL keystrokes. - else if ( keyCode in keystrokesNotBlockedByWidget || ( CKEDITOR.CTRL & keyCode ) ) - return; - - return false; - }, null, null, 999 ); - // Listen with high priority so it's possible - // to overwrite this callback. - - widget.on( 'doubleclick', function( evt ) { - widget.edit(); - evt.cancel(); - } ); - - if ( widgetDef.data ) - widget.on( 'data', widgetDef.data ); - - if ( widgetDef.edit ) - widget.on( 'edit', widgetDef.edit ); - - widget.on( 'data', function() { - positionDragHandler( widget ); - }, null, null, 999 ); - } - - function setupWidgetData( widget, startupData ) { - var widgetDataAttr = widget.element.data( 'cke-widget-data' ); - - if ( widgetDataAttr ) - widget.setData( JSON.parse( widgetDataAttr ) ); - if ( startupData ) - widget.setData( startupData ); - - // Unblock data and... - widget.dataReady = true; - - // Write data to element because this was blocked when data wasn't ready. - writeDataToElement( widget ); - - // Fire data event first time, because this was blocked when data wasn't ready. - widget.fire( 'data', widget.data ); - } - - function setupWrapper( widget ) { - // Retrieve widget wrapper. Assign an id to it. - var wrapper = widget.wrapper = widget.element.getParent(); - wrapper.setAttribute( 'data-cke-widget-id', widget.id ); - } - - function writeDataToElement( widget ) { - widget.element.data( 'cke-widget-data', JSON.stringify( widget.data ) ); - } - - // - // EXPOSE PUBLIC API ------------------------------------------------------ - // - - CKEDITOR.plugins.widget = Widget; - Widget.repository = Repository; - Widget.nestedEditable = NestedEditable; -})(); - -/** - * Event fired when widget is ready (fully initialized). This event is fired after: - * - * * {@link #init} is called, - * * first {@link #data} event is fired, - * * widget is attached to document. - * - * Therefore, in case of widget creation with command which opens dialog, this event - * will be delayed after dialog is closed and widget is finally inserted into document. - * - * **Note**: if your widget does not use automatic dialog binding (i.e. you open the dialog manually) - * or other situation occurs in which widget wrapper is not attached to document at the time when it is - * initialized, you need to take care of firing {@link #ready} yourself. - * - * @event ready - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired when widget is about to be destroyed, but before it is - * fully torn down. - * - * @event destroy - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired when widget is focused. - * - * Widget can be focused by executing {@link #method-focus}. - * - * @event focus - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired when widget is blurred. - * - * @event blur - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired when widget is selected. - * - * @event select - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired when widget is deselected. - * - * @event deselect - * @member CKEDITOR.plugins.widget - */ - -/** - * Event fired by {@link #method-edit}. It can be cancelled - * in order to stop default action (opening dialog). - * - * @event edit - * @member CKEDITOR.plugins.widget - * @param data - * @param {String} data.dialog Defaults to {@link CKEDITOR.plugins.widget.definition#dialog} - * and can be changed or set by listener. - */ - -/** - * Event fired when dialog for widget editing is opened. - * This event can be cancelled in order to handle editing dialog - * in a custom manner. - * - * @event dialog - * @member CKEDITOR.plugins.widget - * @param {CKEDITOR.dialog} data The opened dialog instance. - */ - -/** - * Event fired when key is pressed on focused widget. - * This event is forwarded from {@link CKEDITOR.editor#key} event and - * has the ability to block editor's keystrokes. - * - * @event key - * @member CKEDITOR.plugins.widget - * @param data - * @param {Number} data.keyCode A number representing the key code (or combination). - */ - - /** - * Event fired when widget was double clicked. - * - * @event doubleclick - * @member CKEDITOR.plugins.widget - * @param data - * @param {CKEDITOR.dom.element} data.element The double clicked element. - */ - - /** - * Event fired when context menu is opened for a widget. - * - * @event contextMenu - * @member CKEDITOR.plugins.widget - * @param data The object contaning context menu options to be added - * for this widget. See {@link CKEDITOR.plugins.contextMenu#addListener}. - */ - -/** - * Event fired when widget instance is created, but before it is fully - * initialized. - * - * @event instanceCreated - * @member CKEDITOR.plugins.widget.repository - * @param {CKEDITOR.plugins.widget} data The widget instance. - */ - -/** - * Event fired when widget instance was destroyed. - * - * See also {@link CKEDITOR.plugins.widget#event-destroy}. - * - * @event instanceDestroyed - * @member CKEDITOR.plugins.widget.repository - * @param {CKEDITOR.plugins.widget} data The widget instance. - */ - -/** - * Event fired to trigger selection check. - * - * See {@link #method-checkSelection} method. - * - * @event checkSelection - * @member CKEDITOR.plugins.widget.repository - */ - -/** - * Event fired to trigger widgets check. - * - * See {@link #method-checkWidgets} method. - * - * @event checkWidgets - * @member CKEDITOR.plugins.widget.repository - */
\ No newline at end of file diff --git a/addons/website/static/lib/ckeditor/plugins/wysiwygarea/plugin.js b/addons/website/static/lib/ckeditor/plugins/wysiwygarea/plugin.js deleted file mode 100644 index bca6a8a034f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/wysiwygarea/plugin.js +++ /dev/null @@ -1,643 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview The "wysiwygarea" plugin. It registers the "wysiwyg" editing - * mode, which handles the main editing area space. - */ - -(function() { - CKEDITOR.plugins.add( 'wysiwygarea', { - init: function( editor ) { - if ( editor.config.fullPage ) { - editor.addFeature( { - allowedContent: 'html head title; style [media,type]; body (*)[id]; meta link [*]', - requiredContent: 'body' - } ); - } - - editor.addMode( 'wysiwyg', function( callback ) { - var src = 'document.open();' + - // In IE, the document domain must be set any time we call document.open(). - ( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) + - 'document.close();'; - - // With IE, the custom domain has to be taken care at first, - // for other browers, the 'src' attribute should be left empty to - // trigger iframe's 'load' event. - src = CKEDITOR.env.air ? 'javascript:void(0)' : CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent( src ) + '}())' - : - ''; - - var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="' + src + '" frameBorder="0"></iframe>' ); - iframe.setStyles( { width: '100%', height: '100%' } ); - iframe.addClass( 'cke_wysiwyg_frame cke_reset' ); - - var contentSpace = editor.ui.space( 'contents' ); - contentSpace.append( iframe ); - - - // Asynchronous iframe loading is only required in IE>8 and Gecko (other reasons probably). - // Do not use it on WebKit as it'll break the browser-back navigation. - var useOnloadEvent = CKEDITOR.env.ie || CKEDITOR.env.gecko; - if ( useOnloadEvent ) - iframe.on( 'load', onLoad ); - - var frameLabel = editor.title, - frameDesc = editor.lang.common.editorHelp; - - if ( frameLabel ) { - if ( CKEDITOR.env.ie ) - frameLabel += ', ' + frameDesc; - - iframe.setAttribute( 'title', frameLabel ); - } - - var labelId = CKEDITOR.tools.getNextId(), - desc = CKEDITOR.dom.element.createFromHtml( '<span id="' + labelId + '" class="cke_voice_label">' + frameDesc + '</span>' ); - - contentSpace.append( desc, 1 ); - - // Remove the ARIA description. - editor.on( 'beforeModeUnload', function( evt ) { - evt.removeListener(); - desc.remove(); - }); - - iframe.setAttributes({ - 'aria-describedby': labelId, - tabIndex: editor.tabIndex, - allowTransparency: 'true' - }); - - // Execute onLoad manually for all non IE||Gecko browsers. - !useOnloadEvent && onLoad(); - - if ( CKEDITOR.env.webkit ) { - // Webkit: iframe size doesn't auto fit well. (#7360) - var onResize = function() { - // Hide the iframe to get real size of the holder. (#8941) - contentSpace.setStyle( 'width', '100%' ); - - iframe.hide(); - iframe.setSize( 'width', contentSpace.getSize( 'width' ) ); - contentSpace.removeStyle( 'width' ); - iframe.show(); - }; - - iframe.setCustomData( 'onResize', onResize ); - - CKEDITOR.document.getWindow().on( 'resize', onResize ); - } - - editor.fire( 'ariaWidget', iframe ); - - function onLoad( evt ) { - evt && evt.removeListener(); - editor.editable( new framedWysiwyg( editor, iframe.$.contentWindow.document.body ) ); - editor.setData( editor.getData( 1 ), callback ); - } - }); - } - }); - - function onDomReady( win ) { - var editor = this.editor, - doc = win.document, - body = doc.body; - - // Remove helper scripts from the DOM. - var script = doc.getElementById( 'cke_actscrpt' ); - script && script.parentNode.removeChild( script ); - script = doc.getElementById( 'cke_shimscrpt' ); - script && script.parentNode.removeChild( script ); - - if ( CKEDITOR.env.gecko ) { - // Force Gecko to change contentEditable from false to true on domReady - // (because it's previously set to true on iframe's body creation). - // Otherwise del/backspace and some other editable features will be broken in Fx <4 - // See: #107 and https://bugzilla.mozilla.org/show_bug.cgi?id=440916 - body.contentEditable = false; - - // Remove any leading <br> which is between the <body> and the comment. - // This one fixes Firefox 3.6 bug: the browser inserts a leading <br> - // on document.write if the body has contenteditable="true". - if ( CKEDITOR.env.version < 20000 ) { - body.innerHTML = body.innerHTML.replace( /^.*<!-- cke-content-start -->/, '' ); - - // The above hack messes up the selection in FF36. - // To clean this up, manually select collapsed range that - // starts within the body. - setTimeout( function() { - var range = new CKEDITOR.dom.range( new CKEDITOR.dom.document( doc ) ); - range.setStart( new CKEDITOR.dom.node( body ), 0 ); - editor.getSelection().selectRanges( [ range ] ); - }, 0 ); - } - } - - body.contentEditable = true; - - if ( CKEDITOR.env.ie ) { - // Don't display the focus border. - body.hideFocus = true; - - // Disable and re-enable the body to avoid IE from - // taking the editing focus at startup. (#141 / #523) - body.disabled = true; - body.removeAttribute( 'disabled' ); - } - - delete this._.isLoadingData; - - // Play the magic to alter element reference to the reloaded one. - this.$ = body; - - doc = new CKEDITOR.dom.document( doc ); - - this.setup(); - - if ( CKEDITOR.env.ie ) { - doc.getDocumentElement().addClass( doc.$.compatMode ); - - // Prevent IE from leaving new paragraph after deleting all contents in body. (#6966) - editor.config.enterMode != CKEDITOR.ENTER_P && doc.on( 'selectionchange', function() { - var body = doc.getBody(), - sel = editor.getSelection(), - range = sel && sel.getRanges()[ 0 ]; - - if ( range && body.getHtml().match( /^<p> <\/p>$/i ) && range.startContainer.equals( body ) ) { - // Avoid the ambiguity from a real user cursor position. - setTimeout( function() { - range = editor.getSelection().getRanges()[ 0 ]; - if ( !range.startContainer.equals( 'body' ) ) { - body.getFirst().remove( 1 ); - range.moveToElementEditEnd( body ); - range.select(); - } - }, 0 ); - } - }); - } - - // ## START : disableNativeTableHandles and disableObjectResizing settings. - - // Enable dragging of position:absolute elements in IE. - try { - editor.document.$.execCommand( '2D-position', false, true ); - } catch ( e ) {} - - // IE, Opera and Safari may not support it and throw errors. - try { - editor.document.$.execCommand( 'enableInlineTableEditing', false, !editor.config.disableNativeTableHandles ); - } catch ( e ) {} - - if ( editor.config.disableObjectResizing ) { - try { - this.getDocument().$.execCommand( 'enableObjectResizing', false, false ); - } catch ( e ) { - // For browsers in which the above method failed, we can cancel the resizing on the fly (#4208) - this.attachListener( this, CKEDITOR.env.ie ? 'resizestart' : 'resize', function( evt ) { - evt.data.preventDefault(); - }); - } - } - - if ( CKEDITOR.env.gecko || CKEDITOR.env.ie && editor.document.$.compatMode == 'CSS1Compat' ) { - this.attachListener( this, 'keydown', function( evt ) { - var keyCode = evt.data.getKeystroke(); - - // PageUp OR PageDown - if ( keyCode == 33 || keyCode == 34 ) { - // PageUp/PageDown scrolling is broken in document - // with standard doctype, manually fix it. (#4736) - if ( CKEDITOR.env.ie ) { - setTimeout( function() { - editor.getSelection().scrollIntoView(); - }, 0 ); - } - // Page up/down cause editor selection to leak - // outside of editable thus we try to intercept - // the behavior, while it affects only happen - // when editor contents are not overflowed. (#7955) - else if ( editor.window.$.innerHeight > this.$.offsetHeight ) { - var range = editor.createRange(); - range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd' ]( this ); - range.select(); - evt.data.preventDefault(); - } - } - }); - } - - if ( CKEDITOR.env.ie ) { - // [IE] Iframe will still keep the selection when blurred, if - // focus is moved onto a non-editing host, e.g. link or button, but - // it becomes a problem for the object type selection, since the resizer - // handler attached on it will mark other part of the UI, especially - // for the dialog. (#8157) - // [IE<8 & Opera] Even worse For old IEs, the cursor will not vanish even if - // the selection has been moved to another text input in some cases. (#4716) - // - // Now the range restore is disabled, so we simply force IE to clean - // up the selection before blur. - this.attachListener( doc, 'blur', function() { - // Error proof when the editor is not visible. (#6375) - try { - doc.$.selection.empty(); - } catch ( er ) {} - }); - } - - // ## END - - - var title = editor.document.getElementsByTag( 'title' ).getItem( 0 ); - title.data( 'cke-title', editor.document.$.title ); - - // [IE] JAWS will not recognize the aria label we used on the iframe - // unless the frame window title string is used as the voice label, - // backup the original one and restore it on output. - if ( CKEDITOR.env.ie ) - editor.document.$.title = this._.docTitle; - - CKEDITOR.tools.setTimeout( function() { - editor.fire( 'contentDom' ); - - if ( this._.isPendingFocus ) { - editor.focus(); - this._.isPendingFocus = false; - } - - setTimeout( function() { - editor.fire( 'dataReady' ); - }, 0 ); - - // IE BUG: IE might have rendered the iframe with invisible contents. - // (#3623). Push some inconsequential CSS style changes to force IE to - // refresh it. - // - // Also, for some unknown reasons, short timeouts (e.g. 100ms) do not - // fix the problem. :( - if ( CKEDITOR.env.ie ) { - setTimeout( function() { - if ( editor.document ) { - var $body = editor.document.$.body; - $body.runtimeStyle.marginBottom = '0px'; - $body.runtimeStyle.marginBottom = ''; - } - }, 1000 ); - } - }, 0, this ); - } - - var framedWysiwyg = CKEDITOR.tools.createClass({ - $: function( editor ) { - this.base.apply( this, arguments ); - - this._.frameLoadedHandler = CKEDITOR.tools.addFunction( function( win ) { - // Avoid opening design mode in a frame window thread, - // which will cause host page scrolling.(#4397) - CKEDITOR.tools.setTimeout( onDomReady, 0, this, win ); - }, this ); - - this._.docTitle = this.getWindow().getFrame().getAttribute( 'title' ); - }, - - base: CKEDITOR.editable, - - proto: { - setData: function( data, isSnapshot ) { - var editor = this.editor; - - if ( isSnapshot ) { - this.setHtml( data ); - // Fire dataReady for the consistency with inline editors - // and because it makes sense. (#10370) - editor.fire( 'dataReady' ); - } - else { - this._.isLoadingData = true; - editor._.dataStore = { id:1 }; - - var config = editor.config, - fullPage = config.fullPage, - docType = config.docType; - - // Build the additional stuff to be included into <head>. - var headExtra = CKEDITOR.tools.buildStyleHtml( iframeCssFixes() ) - .replace( /<style>/, '<style data-cke-temp="1">' ); - - if ( !fullPage ) - headExtra += CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss ); - - var baseTag = config.baseHref ? '<base href="' + config.baseHref + '" data-cke-temp="1" />' : ''; - - if ( fullPage ) { - // Search and sweep out the doctype declaration. - data = data.replace( /<!DOCTYPE[^>]*>/i, function( match ) { - editor.docType = docType = match; - return ''; - }).replace( /<\?xml\s[^\?]*\?>/i, function( match ) { - editor.xmlDeclaration = match; - return ''; - }); - } - - // Get the HTML version of the data. - data = editor.dataProcessor.toHtml( data ); - - if ( fullPage ) { - // Check if the <body> tag is available. - if ( !( /<body[\s|>]/ ).test( data ) ) - data = '<body>' + data; - - // Check if the <html> tag is available. - if ( !( /<html[\s|>]/ ).test( data ) ) - data = '<html>' + data + '</html>'; - - // Check if the <head> tag is available. - if ( !( /<head[\s|>]/ ).test( data ) ) - data = data.replace( /<html[^>]*>/, '$&<head><title></title></head>' ); - else if ( !( /<title[\s|>]/ ).test( data ) ) - data = data.replace( /<head[^>]*>/, '$&<title></title>' ); - - // The base must be the first tag in the HEAD, e.g. to get relative - // links on styles. - baseTag && ( data = data.replace( /<head>/, '$&' + baseTag ) ); - - // Inject the extra stuff into <head>. - // Attention: do not change it before testing it well. (V2) - // This is tricky... if the head ends with <meta ... content type>, - // Firefox will break. But, it works if we place our extra stuff as - // the last elements in the HEAD. - data = data.replace( /<\/head\s*>/, headExtra + '$&' ); - - // Add the DOCTYPE back to it. - data = docType + data; - } else { - data = config.docType + - '<html dir="' + config.contentsLangDirection + '"' + - ' lang="' + ( config.contentsLanguage || editor.langCode ) + '">' + - '<head>' + - '<title>' + this._.docTitle + '</title>' + - baseTag + - headExtra + - '</head>' + - '<body' + ( config.bodyId ? ' id="' + config.bodyId + '"' : '' ) + - ( config.bodyClass ? ' class="' + config.bodyClass + '"' : '' ) + - '>' + - data + - '</body>' + - '</html>'; - } - - if ( CKEDITOR.env.gecko ) { - // Hack to make Fx put cursor at the start of doc on fresh focus. - data = data.replace( /<body/, '<body contenteditable="true" ' ); - - // Another hack which is used by onDomReady to remove a leading - // <br> which is inserted by Firefox 3.6 when document.write is called. - // This additional <br> is present because of contenteditable="true" - if ( CKEDITOR.env.version < 20000 ) - data = data.replace( /<body[^>]*>/, '$&<!-- cke-content-start -->' ); - } - - // The script that launches the bootstrap logic on 'domReady', so the document - // is fully editable even before the editing iframe is fully loaded (#4455). - var bootstrapCode = - '<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' + - 'var wasLoaded=0;' + // It must be always set to 0 as it remains as a window property. - 'function onload(){' + - 'if(!wasLoaded)' + // FF3.6 calls onload twice when editor.setData. Stop that. - 'window.parent.CKEDITOR.tools.callFunction(' + this._.frameLoadedHandler + ',window);' + - 'wasLoaded=1;' + - '}' + - ( CKEDITOR.env.ie ? 'onload();' : 'document.addEventListener("DOMContentLoaded", onload, false );' ) + - '</script>'; - - // For IE<9 add support for HTML5's elements. - // Note: this code must not be deferred. - if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) { - bootstrapCode += - '<script id="cke_shimscrpt">' + - 'window.parent.CKEDITOR.tools.enableHtml5Elements(document)' + - '</script>'; - } - - data = data.replace( /(?=\s*<\/(:?head)>)/, bootstrapCode ); - - // Current DOM will be deconstructed by document.write, cleanup required. - this.clearCustomData(); - this.clearListeners(); - - editor.fire( 'contentDomUnload' ); - - var doc = this.getDocument(); - - // Work around Firefox bug - error prune when called from XUL (#320), - // defer it thanks to the async nature of this method. - try { doc.write( data ); } catch ( e ) { - setTimeout( function () { doc.write( data ); }, 0 ); - } - } - }, - - getData: function( isSnapshot ) { - if ( isSnapshot ) - return this.getHtml(); - else { - var editor = this.editor, - config = editor.config, - fullPage = config.fullPage, - docType = fullPage && editor.docType, - xmlDeclaration = fullPage && editor.xmlDeclaration, - doc = this.getDocument(); - - var data = fullPage ? doc.getDocumentElement().getOuterHtml() : doc.getBody().getHtml(); - - // BR at the end of document is bogus node for Mozilla. (#5293). - // Prevent BRs from disappearing from the end of the content - // while enterMode is ENTER_BR (#10146). - if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR ) - data = data.replace( /<br>(?=\s*(:?$|<\/body>))/, '' ); - - data = editor.dataProcessor.toDataFormat( data ); - - if ( xmlDeclaration ) - data = xmlDeclaration + '\n' + data; - if ( docType ) - data = docType + '\n' + data; - - return data; - } - }, - - focus: function() { - if ( this._.isLoadingData ) - this._.isPendingFocus = true; - else - framedWysiwyg.baseProto.focus.call( this ); - }, - - detach: function() { - var editor = this.editor, - doc = editor.document, - iframe = editor.window.getFrame(); - - framedWysiwyg.baseProto.detach.call( this ); - - // Memory leak proof. - this.clearCustomData(); - doc.getDocumentElement().clearCustomData(); - iframe.clearCustomData(); - CKEDITOR.tools.removeFunction( this._.frameLoadedHandler ); - - var onResize = iframe.removeCustomData( 'onResize' ); - onResize && onResize.removeListener(); - - - editor.fire( 'contentDomUnload' ); - - // IE BUG: When destroying editor DOM with the selection remains inside - // editing area would break IE7/8's selection system, we have to put the editing - // iframe offline first. (#3812 and #5441) - iframe.remove(); - } - } - }); - - // DOM modification here should not bother dirty flag.(#4385) - function restoreDirty( editor ) { - if ( !editor.checkDirty() ) - setTimeout( function() { - editor.resetDirty(); - }, 0 ); - } - - function iframeCssFixes() { - var css = []; - - // IE>=8 stricts mode doesn't have 'contentEditable' in effect - // on element unless it has layout. (#5562) - if ( CKEDITOR.document.$.documentMode >= 8 ) { - css.push( 'html.CSS1Compat [contenteditable=false]{min-height:0 !important}' ); - - var selectors = []; - - for ( var tag in CKEDITOR.dtd.$removeEmpty ) - selectors.push( 'html.CSS1Compat ' + tag + '[contenteditable=false]' ); - - css.push( selectors.join( ',' ) + '{display:inline-block}' ); - } - // Set the HTML style to 100% to have the text cursor in affect (#6341) - else if ( CKEDITOR.env.gecko ) { - css.push( 'html{height:100% !important}' ); - css.push( 'img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}' ); - } - - // #6341: The text cursor must be set on the editor area. - // #6632: Avoid having "text" shape of cursor in IE7 scrollbars. - css.push( 'html{cursor:text;*cursor:auto}' ); - - // Use correct cursor for these elements - css.push( 'img,input,textarea{cursor:default}' ); - - return css.join('\n'); - } -})(); - -/** - * Disables the ability of resize objects (image and tables) in the editing area. - * - * config.disableObjectResizing = true; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.disableObjectResizing = false; - -/** - * Disables the "table tools" offered natively by the browser (currently - * Firefox only) to make quick table editing operations, like adding or - * deleting rows and columns. - * - * config.disableNativeTableHandles = false; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.disableNativeTableHandles = true; - -/** - * Disables the built-in words spell checker if browser provides one. - * - * **Note:** Although word suggestions provided by browsers (natively) will - * not appear in CKEditor's default context menu, - * users can always reach the native context menu by holding the - * *Ctrl* key when right-clicking if {@link #browserContextMenuOnCtrl} - * is enabled or you're simply not using the context menu plugin. - * - * config.disableNativeSpellChecker = false; - * - * @cfg - * @member CKEDITOR.config - */ -CKEDITOR.config.disableNativeSpellChecker = true; - -/** - * The CSS file(s) to be used to apply style to the contents. It should - * reflect the CSS used in the final pages where the contents are to be - * used. - * - * config.contentsCss = '/css/mysitestyles.css'; - * config.contentsCss = ['/css/mysitestyles.css', '/css/anotherfile.css']; - * - * @cfg {String/Array} [contentsCss=CKEDITOR.basePath + 'contents.css'] - * @member CKEDITOR.config - */ -CKEDITOR.config.contentsCss = CKEDITOR.basePath + 'contents.css'; - -/** - * Language code of the writting language which is used to author the editor - * contents. - * - * config.contentsLanguage = 'fr'; - * - * @cfg {String} [contentsLanguage=same value with editor's UI language] - * @member CKEDITOR.config - */ - -/** - * The base href URL used to resolve relative and absolute URLs in the - * editor content. - * - * config.baseHref = 'http://www.example.com/path/'; - * - * @cfg {String} [baseHref=''] - * @member CKEDITOR.config - */ - -/** - * Whether automatically create wrapping blocks around inline contents inside document body, - * this helps to ensure the integrality of the block enter mode. - * - * **Note:** Changing the default value might introduce unpredictable usability issues. - * - * config.autoParagraph = false; - * - * @since 3.6 - * @cfg {Boolean} [autoParagraph=true] - * @member CKEDITOR.config - */ - -/** - * Fired when some elements are added to the document. - * - * @event ariaWidget - * @member CKEDITOR.editor - * @param {CKEDITOR.editor} editor This editor instance. - * @param {CKEDITOR.dom.element} data The element being added. - */ diff --git a/addons/website/static/lib/ckeditor/plugins/xml/plugin.js b/addons/website/static/lib/ckeditor/plugins/xml/plugin.js deleted file mode 100644 index 32e070e860f..00000000000 --- a/addons/website/static/lib/ckeditor/plugins/xml/plugin.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -/** - * @fileOverview Defines the {@link CKEDITOR.xml} class, which represents a - * loaded XML document. - */ - -(function() { - CKEDITOR.plugins.add( 'xml', {} ); - - /** - * Represents a loaded XML document. - * - * var xml = new CKEDITOR.xml( '<books><book title="My Book" /></books>' ); - * - * @class - * @constructor Creates xml class instance. - * @param {Object/String} xmlObjectOrData A native XML (DOM document) object or - * a string containing the XML definition to be loaded. - */ - CKEDITOR.xml = function( xmlObjectOrData ) { - var baseXml = null; - - if ( typeof xmlObjectOrData == 'object' ) - baseXml = xmlObjectOrData; - else { - var data = ( xmlObjectOrData || '' ).replace( / /g, '\xA0' ); - if ( window.DOMParser ) - baseXml = ( new DOMParser() ).parseFromString( data, 'text/xml' ); - else if ( window.ActiveXObject ) { - try { - baseXml = new ActiveXObject( 'MSXML2.DOMDocument' ); - } catch ( e ) { - try { - baseXml = new ActiveXObject( 'Microsoft.XmlDom' ); - } catch ( e ) {} - } - - if ( baseXml ) { - baseXml.async = false; - baseXml.resolveExternals = false; - baseXml.validateOnParse = false; - baseXml.loadXML( data ); - } - } - } - - /** - * The native XML (DOM document) used by the class instance. - */ - this.baseXml = baseXml; - }; - - CKEDITOR.xml.prototype = { - /** - * Get a single node from the XML document, based on a XPath query. - * - * // Create the XML instance. - * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); - * // Get the first <item> node. - * var itemNode = <b>xml.selectSingleNode( 'list/item' )</b>; - * // Alert "item". - * alert( itemNode.nodeName ); - * - * @param {String} xpath The XPath query to execute. - * @param {Object} [contextNode] The XML DOM node to be used as the context - * for the XPath query. The document root is used by default. - * @returns {Object} A XML node element or null if the query has no results. - */ - selectSingleNode: function( xpath, contextNode ) { - var baseXml = this.baseXml; - - if ( contextNode || ( contextNode = baseXml ) ) { - if ( CKEDITOR.env.ie || contextNode.selectSingleNode ) // IE - return contextNode.selectSingleNode( xpath ); - else if ( baseXml.evaluate ) // Others - { - var result = baseXml.evaluate( xpath, contextNode, null, 9, null ); - return ( result && result.singleNodeValue ) || null; - } - } - - return null; - }, - - /** - * Gets a list node from the XML document, based on a XPath query. - * - * // Create the XML instance. - * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); - * // Get the first <item> node. - * var itemNodes = xml.selectSingleNode( 'list/item' ); - * // Alert "item" twice, one for each <item>. - * for ( var i = 0 ; i < itemNodes.length ; i++ ) - * alert( itemNodes[i].nodeName ); - * - * @param {String} xpath The XPath query to execute. - * @param {Object} [contextNode] The XML DOM node to be used as the context - * for the XPath query. The document root is used by default. - * @returns {Array} An array containing all matched nodes. The array will - * be empty if the query has no results. - */ - selectNodes: function( xpath, contextNode ) { - var baseXml = this.baseXml, - nodes = []; - - if ( contextNode || ( contextNode = baseXml ) ) { - if ( CKEDITOR.env.ie || contextNode.selectNodes ) // IE - return contextNode.selectNodes( xpath ); - else if ( baseXml.evaluate ) // Others - { - var result = baseXml.evaluate( xpath, contextNode, null, 5, null ); - - if ( result ) { - var node; - while ( ( node = result.iterateNext() ) ) - nodes.push( node ); - } - } - } - - return nodes; - }, - - /** - * Gets the string representation of hte inner contents of a XML node, - * based on a XPath query. - * - * // Create the XML instance. - * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); - * // Alert "<item id="test1" /><item id="test2" />". - * alert( xml.getInnerXml( 'list' ) ); - * - * @param {String} xpath The XPath query to execute. - * @param {Object} [contextNode] The XML DOM node to be used as the context - * for the XPath query. The document root is used by default. - * @returns {String} The textual representation of the inner contents of - * the node or null if the query has no results. - */ - getInnerXml: function( xpath, contextNode ) { - var node = this.selectSingleNode( xpath, contextNode ), - xml = []; - if ( node ) { - node = node.firstChild; - while ( node ) { - if ( node.xml ) // IE - xml.push( node.xml ); - else if ( window.XMLSerializer ) // Others - xml.push( ( new XMLSerializer() ).serializeToString( node ) ); - - node = node.nextSibling; - } - } - - return xml.length ? xml.join( '' ) : null; - } - }; -})(); |
