Changeset 3410:e2e04005053c for plugins/dcCKEditor/js/ckeditor/ckeditor.js
- Timestamp:
- 11/18/16 18:11:18 (9 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/dcCKEditor/js/ckeditor/ckeditor.js
r3339 r3410 47 47 // for each release and generated by the releaser. 48 48 // (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122) 49 timestamp: 'G 889',49 timestamp: 'GAIF', 50 50 51 51 /** … … 54 54 * alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1' 55 55 */ 56 version: '4. 5.11',56 version: '4.6.0', 57 57 58 58 /** … … 2656 2656 } 2657 2657 return false; 2658 }, 2659 2660 /** 2661 * Converts a keystroke to its string representation. Returns an object with two fields: 2662 * 2663 * * `display` – A string that should be used for visible labels. 2664 * For Mac devices it uses `⌥` for `ALT`, `⇧` for `SHIFT` and `⌘` for `COMMAND`. 2665 * * `aria` – A string that should be used for ARIA descriptions. 2666 * It does not use special characters such as `⌥`, `⇧` or `⌘`. 2667 * 2668 * var lang = editor.lang.common.keyboard; 2669 * var shortcut = CKEDITOR.tools.keystrokeToString( lang, CKEDITOR.CTRL + 88 ); 2670 * console.log( shortcut.display ); // 'CTRL + X', on Mac '⌘ + X'. 2671 * console.log( shortcut.aria ); // 'CTRL + X', on Mac 'COMMAND + X'. 2672 * 2673 * @since 4.6.0 2674 * @param {Object} lang A language object with the key name translation. 2675 * @param {Number} keystroke The keystroke to convert. 2676 * @returns {{display: String, aria: String}} 2677 */ 2678 keystrokeToString: function( lang, keystroke ) { 2679 var special = keystroke & 0xFF0000, 2680 key = keystroke & 0x00FFFF, 2681 isMac = CKEDITOR.env.mac, 2682 CTRL = 17, 2683 CMD = 224, 2684 ALT = 18, 2685 SHIFT = 16, 2686 display = [], 2687 aria = []; 2688 2689 2690 if ( special & CKEDITOR.CTRL ) { 2691 display.push( isMac ? '⌘' : lang[ CTRL ] ); 2692 aria.push( isMac ? lang[ CMD ] : lang[ CTRL ] ); 2693 } 2694 2695 if ( special & CKEDITOR.ALT ) { 2696 display.push( isMac ? '⌥' : lang[ ALT ] ); 2697 aria.push( lang[ ALT ] ); 2698 } 2699 2700 if ( special & CKEDITOR.SHIFT ) { 2701 display.push( isMac ? '⇧' : lang[ SHIFT ] ); 2702 aria.push( lang[ SHIFT ] ); 2703 } 2704 2705 if ( key ) { 2706 if ( lang[ key ] ) { 2707 display.push( lang[ key ] ); 2708 aria.push( lang[ key ] ); 2709 } else { 2710 display.push( String.fromCharCode( key ) ); 2711 aria.push( String.fromCharCode( key ) ); 2712 } 2713 } 2714 2715 return { 2716 display: display.join( '+' ), 2717 aria: aria.join( '+' ) 2718 }; 2658 2719 }, 2659 2720 … … 10649 10710 /** 10650 10711 * Looks for elements matching the `query` selector within a range. 10651 * 10712 * 10652 10713 * @since 4.5.11 10653 10714 * @private … … 10770 10831 CKEDITOR.POSITION_AFTER_END = 4; 10771 10832 10833 /** 10834 * @readonly 10835 * @member CKEDITOR 10836 * @property {Number} [=1] 10837 */ 10772 10838 CKEDITOR.ENLARGE_ELEMENT = 1; 10839 10840 /** 10841 * @readonly 10842 * @member CKEDITOR 10843 * @property {Number} [=2] 10844 */ 10773 10845 CKEDITOR.ENLARGE_BLOCK_CONTENTS = 2; 10846 10847 /** 10848 * @readonly 10849 * @member CKEDITOR 10850 * @property {Number} [=3] 10851 */ 10774 10852 CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS = 3; 10853 10854 /** 10855 * @readonly 10856 * @member CKEDITOR 10857 * @property {Number} [=4] 10858 */ 10775 10859 CKEDITOR.ENLARGE_INLINE = 4; 10776 10860 … … 14179 14263 * 14180 14264 * @param {CKEDITOR.htmlParser.element} element 14181 * @param {String} styleName Name of the style that will be converted.14182 * @param {String} [attrName=styleName] Name of the attribute into which the style will be converted.14265 * @param {String} styleName The name of the style that will be converted. 14266 * @param {String} [attrName=styleName] The name of the attribute into which the style will be converted. 14183 14267 */ 14184 14268 lengthToAttribute: function( element, styleName, attrName ) { … … 14200 14284 14201 14285 /** 14202 * Converts the `align` attribute to the `float` style if not set. Attribute14286 * Converts the `align` attribute to the `float` style if not set. The attribute 14203 14287 * is always removed. 14204 14288 * … … 14218 14302 /** 14219 14303 * Converts the `float` style to the `align` attribute if not set. 14220 * Style is always removed.14304 * The style is always removed. 14221 14305 * 14222 14306 * @param {CKEDITOR.htmlParser.element} element … … 14234 14318 14235 14319 /** 14320 * Converts the shorthand form of the `border` style to seperate styles. 14321 * 14322 * @param {CKEDITOR.htmlParser.element} element 14323 */ 14324 splitBorderShorthand: function( element ) { 14325 if ( !element.styles.border ) { 14326 return; 14327 } 14328 14329 var widths = element.styles.border.match( /([\.\d]+\w+)/g ) || [ '0px' ]; 14330 switch ( widths.length ) { 14331 case 1: 14332 element.styles[ 'border-width' ] = widths[0]; 14333 break; 14334 case 2: 14335 mapStyles( [ 0, 1, 0, 1 ] ); 14336 break; 14337 case 3: 14338 mapStyles( [ 0, 1, 2, 1 ] ); 14339 break; 14340 case 4: 14341 mapStyles( [ 0, 1, 2, 3 ] ); 14342 break; 14343 } 14344 14345 element.styles[ 'border-style' ] = element.styles[ 'border-style' ] || 14346 ( element.styles.border.match( /(none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|initial|inherit)/ ) || [] )[ 0 ]; 14347 if ( !element.styles[ 'border-style' ] ) 14348 delete element.styles[ 'border-style' ]; 14349 14350 delete element.styles.border; 14351 14352 function mapStyles( map ) { 14353 element.styles['border-top-width'] = widths[ map[0] ]; 14354 element.styles['border-right-width'] = widths[ map[1] ]; 14355 element.styles['border-bottom-width'] = widths[ map[2] ]; 14356 element.styles['border-left-width'] = widths[ map[3] ]; 14357 } 14358 }, 14359 14360 listTypeToStyle: function( element ) { 14361 if ( element.attributes.type ) { 14362 switch ( element.attributes.type ) { 14363 case 'a': 14364 element.styles[ 'list-style-type' ] = 'lower-alpha'; 14365 break; 14366 case 'A': 14367 element.styles[ 'list-style-type' ] = 'upper-alpha'; 14368 break; 14369 case 'i': 14370 element.styles[ 'list-style-type' ] = 'lower-roman'; 14371 break; 14372 case 'I': 14373 element.styles[ 'list-style-type' ] = 'upper-roman'; 14374 break; 14375 case '1': 14376 element.styles[ 'list-style-type' ] = 'decimal'; 14377 break; 14378 default: 14379 element.styles[ 'list-style-type' ] = element.attributes.type; 14380 } 14381 } 14382 }, 14383 14384 /** 14385 * Converts the shorthand form of the `margin` style to seperate styles. 14386 * 14387 * @param {CKEDITOR.htmlParser.element} element 14388 */ 14389 splitMarginShorthand: function( element ) { 14390 if ( !element.styles.margin ) { 14391 return; 14392 } 14393 14394 var widths = element.styles.margin.match( /(\-?[\.\d]+\w+)/g ) || [ '0px' ]; 14395 switch ( widths.length ) { 14396 case 1: 14397 element.styles.margin = widths[0]; 14398 break; 14399 case 2: 14400 mapStyles( [ 0, 1, 0, 1 ] ); 14401 break; 14402 case 3: 14403 mapStyles( [ 0, 1, 2, 1 ] ); 14404 break; 14405 case 4: 14406 mapStyles( [ 0, 1, 2, 3 ] ); 14407 break; 14408 } 14409 14410 delete element.styles.margin; 14411 14412 function mapStyles( map ) { 14413 element.styles['margin-top'] = widths[ map[0] ]; 14414 element.styles['margin-right'] = widths[ map[1] ]; 14415 element.styles['margin-bottom'] = widths[ map[2] ]; 14416 element.styles['margin-left'] = widths[ map[3] ]; 14417 } 14418 }, 14419 14420 /** 14236 14421 * Checks whether an element matches a given {@link CKEDITOR.style}. 14237 14422 * The element can be a "superset" of a style, e.g. it may have … … 14244 14429 14245 14430 /** 14246 * Transforms element togiven form.14431 * Transforms an element to a given form. 14247 14432 * 14248 14433 * Form may be a: 14249 14434 * 14250 14435 * * {@link CKEDITOR.style}, 14251 * * string – the new name of anelement.14436 * * string – the new name of the element. 14252 14437 * 14253 14438 * @param {CKEDITOR.htmlParser.element} el … … 15014 15199 'en-au': 1, 'en-ca': 1, 'en-gb': 1, en: 1, eo: 1, es: 1, et: 1, eu: 1, fa: 1, fi: 1, fo: 1, 15015 15200 'fr-ca': 1, fr: 1, gl: 1, gu: 1, he: 1, hi: 1, hr: 1, hu: 1, id: 1, is: 1, it: 1, ja: 1, ka: 1, 15016 km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, pl: 1, 'pt-br': 1,15201 km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, oc: 1, pl: 1, 'pt-br': 1, 15017 15202 pt: 1, ro: 1, ru: 1, si: 1, sk: 1, sl: 1, sq: 1, 'sr-latn': 1, sr: 1, sv: 1, th: 1, tr: 1, tt: 1, ug: 1, 15018 15203 uk: 1, vi: 1, 'zh-cn': 1, zh: 1 … … 17159 17344 17160 17345 /** 17346 * Returns the keystroke that is assigned to a specified {@link CKEDITOR.command}. If no keystroke is assigned, 17347 * it returns null. 17348 * 17349 * @since 4.6.0 17350 * @param {CKEDITOR.command} command 17351 * @returns {Number} The keystroke assigned to the provided command or null if there is no keystroke. 17352 */ 17353 getCommandKeystroke: function( command ) { 17354 var commandName = command.name, 17355 keystrokes = this.keystrokeHandler.keystrokes, 17356 key; 17357 17358 // Some commands have a fake keystroke - for example CUT/COPY/PASTE commands are handled natively. 17359 if ( command.fakeKeystroke ) { 17360 return command.fakeKeystroke; 17361 } 17362 17363 for ( key in keystrokes ) { 17364 if ( keystrokes.hasOwnProperty( key ) && keystrokes[ key ] == commandName ) { 17365 return key; 17366 } 17367 } 17368 17369 return null; 17370 }, 17371 17372 /** 17161 17373 * Shorthand for {@link CKEDITOR.filter#addFeature}. 17162 17374 * … … 17642 17854 * 17643 17855 * @event destroy 17856 * @param {CKEDITOR.editor} editor This editor instance. 17857 */ 17858 17859 /** 17860 * Event fired when the {@link #method-destroy} method is called, 17861 * but before destroying the editor. 17862 * 17863 * @event beforeDestroy 17644 17864 * @param {CKEDITOR.editor} editor This editor instance. 17645 17865 */ … … 20705 20925 20706 20926 /** 20707 * Object presentation of CSS style declaration text.20927 * Object presentation of the CSS style declaration text. 20708 20928 * 20709 20929 * @class … … 21068 21288 * @since 4.3 21069 21289 * @param {Number} index Index at which the element will be split — `0` means the beginning, 21070 * `1` after first child node, etc.21290 * `1` after the first child node, etc. 21071 21291 * @returns {CKEDITOR.htmlParser.element} The new element following this one. 21072 21292 */ … … 21089 21309 21090 21310 return clone; 21311 }, 21312 21313 /** 21314 * Searches through the current node children to find nodes matching the `criteria`. 21315 * 21316 * @param {String/Function} criteria Tag name or evaluator function. 21317 * @param {Boolean} [recursive=false] 21318 * @returns {CKEDITOR.htmlParser.node[]} 21319 */ 21320 find: function( criteria, recursive ) { 21321 if ( recursive === undefined ) { 21322 recursive = false; 21323 } 21324 21325 var ret = [], 21326 i; 21327 21328 for ( i = 0; i < this.children.length; i++ ) { 21329 var curChild = this.children[ i ]; 21330 21331 if ( typeof criteria == 'function' && criteria( curChild ) ) { 21332 ret.push( curChild ); 21333 } else if ( typeof criteria == 'string' && curChild.name === criteria ) { 21334 ret.push( curChild ); 21335 } 21336 21337 if ( recursive && curChild.find ) { 21338 ret = ret.concat( curChild.find( criteria, recursive ) ); 21339 } 21340 } 21341 21342 return ret; 21091 21343 }, 21092 21344 … … 23391 23643 * @method editable 23392 23644 * @member CKEDITOR.editor 23393 * @param {CKEDITOR.dom.element/CKEDITOR.editable} elementOrEditableThe23645 * @param {CKEDITOR.dom.element/CKEDITOR.editable} [elementOrEditable] The 23394 23646 * DOM element to become the editable or a {@link CKEDITOR.editable} object. 23395 23647 */ … … 34645 34897 34646 34898 function showCover( editor ) { 34647 var win = CKEDITOR.document.getWindow(); 34648 var config = editor.config, 34649 backgroundColorStyle = config.dialog_backgroundCoverColor || 'white', 34899 var win = CKEDITOR.document.getWindow(), 34900 config = editor.config, 34901 skinName = ( CKEDITOR.skinName || editor.config.skin ), 34902 backgroundColorStyle = config.dialog_backgroundCoverColor || ( skinName == 'moono-lisa' ? 'black' : 'white' ), 34650 34903 backgroundCoverOpacity = config.dialog_backgroundCoverOpacity, 34651 34904 baseFloatZIndex = config.baseFloatZIndex, … … 37134 37387 canUndo: type == 'cut', // We can't undo copy to clipboard. 37135 37388 startDisabled: true, 37389 fakeKeystroke: type == 'cut' ? CKEDITOR.CTRL + 88 /*X*/ : CKEDITOR.CTRL + 67 /*C*/, 37136 37390 exec: function() { 37137 37391 // Attempts to execute the Cut and Copy operations. … … 37168 37422 canUndo: false, 37169 37423 async: true, 37170 37424 fakeKeystroke: CKEDITOR.CTRL + 86 /*V*/, 37171 37425 exec: function( editor, data ) { 37172 37426 var cmd = this, … … 39208 39462 ' role="button"' + 39209 39463 ' aria-labelledby="{id}_label"' + 39464 ' aria-describedby="{id}_description"' + 39210 39465 ' aria-haspopup="{hasArrow}"' + 39211 39466 ' aria-disabled="{ariaDisabled}"'; … … 39231 39486 template += '> </span>' + 39232 39487 '<span id="{id}_label" class="cke_button_label cke_button__{name}_label" aria-hidden="false">{label}</span>' + 39488 '<span id="{id}_description" class="cke_button_label" aria-hidden="false">{ariaShortcut}</span>' + 39233 39489 '{arrowHtml}' + 39234 39490 '</a>'; … … 39333 39589 command = this.command, 39334 39590 // Get the command name. 39335 clickFn; 39591 clickFn, 39592 keystroke, 39593 shortcut; 39336 39594 39337 39595 this._.editor = editor; … … 39434 39692 } 39435 39693 39436 if ( !command ) 39694 if ( !command ) { 39437 39695 stateName += 'off'; 39696 } else { 39697 keystroke = editor.getCommandKeystroke( command ); 39698 39699 if ( keystroke ) { 39700 shortcut = CKEDITOR.tools.keystrokeToString( editor.lang.common.keyboard, keystroke ); 39701 } 39702 } 39438 39703 39439 39704 var name = this.name || this.command, … … 39454 39719 state: stateName, 39455 39720 ariaDisabled: stateName == 'disabled' ? 'true' : 'false', 39456 title: this.title, 39721 title: this.title + ( shortcut ? ' (' + shortcut.display + ')' : '' ), 39722 ariaShortcut: shortcut ? editor.lang.common.keyboardShortcut + ' ' + shortcut.aria : '', 39457 39723 titleJs: env.gecko && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ), 39458 39724 hasArrow: this.hasArrow ? 'true' : 'false', … … 40732 40998 40733 40999 if ( !CKEDITOR.env.hc ) { 40734 addButton( 'TextColor', 'fore', lang.textColorTitle, 10 ); 41000 addButton( 'TextColor', 'fore', lang.textColorTitle, 10, { 41001 contentTransformations: [ 41002 [ 41003 { 41004 element: 'font', 41005 check: 'span{color}', 41006 left: function( element ) { 41007 return !!element.attributes.color; 41008 }, 41009 right: function( element ) { 41010 element.name = 'span'; 41011 41012 element.attributes.color && ( element.styles.color = element.attributes.color ); 41013 delete element.attributes.color; 41014 } 41015 } 41016 ] 41017 ] 41018 } ); 40735 41019 addButton( 'BGColor', 'back', lang.bgColorTitle, 20 ); 40736 41020 } 40737 41021 40738 function addButton( name, type, title, order ) {41022 function addButton( name, type, title, order, options ) { 40739 41023 var style = new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ] ), 40740 41024 colorBoxId = CKEDITOR.tools.getNextId() + '_colorBox'; 41025 41026 options = options || {}; 40741 41027 40742 41028 editor.ui.add( name, CKEDITOR.UI_PANELBUTTON, { … … 40748 41034 allowedContent: style, 40749 41035 requiredContent: style, 41036 contentTransformations: options.contentTransformations, 40750 41037 40751 41038 panel: { … … 41254 41541 requiredContent: 'div', 41255 41542 contextSensitive: true, 41543 contentTransformations: [ 41544 [ 'div: alignmentToStyle' ] 41545 ], 41256 41546 refresh: function( editor, path ) { 41257 41547 var context = editor.config.div_wrapTable ? path.root : path.blockLimit; … … 44930 45220 }; 44931 45221 45222 this.contentTransformations = [ 45223 [ 'div: splitMarginShorthand' ], 45224 [ 'h1: splitMarginShorthand' ], 45225 [ 'h2: splitMarginShorthand' ], 45226 [ 'h3: splitMarginShorthand' ], 45227 [ 'h4: splitMarginShorthand' ], 45228 [ 'h5: splitMarginShorthand' ], 45229 [ 'h6: splitMarginShorthand' ], 45230 [ 'ol: splitMarginShorthand' ], 45231 [ 'p: splitMarginShorthand' ], 45232 [ 'pre: splitMarginShorthand' ], 45233 [ 'ul: splitMarginShorthand' ] 45234 ]; 45235 44932 45236 if ( this.enterBr ) 44933 45237 this.allowedContent.div = true; … … 45665 45969 45666 45970 if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'advanced' ) ) 45667 allowed = allowed.replace( ']', ',accesskey,charset,dir,id,lang,name,rel,tabindex,title,type ]{*}(*)' );45971 allowed = allowed.replace( ']', ',accesskey,charset,dir,id,lang,name,rel,tabindex,title,type,download]{*}(*)' ); 45668 45972 if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'target' ) ) 45669 45973 allowed = allowed.replace( ']', ',target,onclick]' ); … … 46140 46444 } 46141 46445 46446 var download = element.getAttribute( 'download' ); 46447 if ( download !== null ) { 46448 retval.download = true; 46449 } 46450 46142 46451 var advanced = {}; 46143 46452 … … 46279 46588 } 46280 46589 46590 // Force download attribute. 46591 if ( data.download ) { 46592 set.download = ''; 46593 } 46594 46281 46595 // Advanced attributes. 46282 46596 if ( data.advanced ) { … … 46300 46614 onclick: 1, 46301 46615 'data-cke-pa-onclick': 1, 46302 'data-cke-saved-name': 1 46616 'data-cke-saved-name': 1, 46617 'download': 1 46303 46618 }; 46304 46619 … … 47625 47940 ' title="{title}"' + 47626 47941 ' tabindex="-1"' + 47627 ' _cke_focus=1' +47942 ' _cke_focus=1' + 47628 47943 ' hidefocus="true"' + 47629 47944 ' role="{role}"' + 47945 ' aria-label="{label}"' + 47946 ' aria-describedby="{id}_description"' + 47630 47947 ' aria-haspopup="{hasPopup}"' + 47631 47948 ' aria-disabled="{disabled}"' + … … 47651 47968 47652 47969 menuItemSource += 47970 //'' + 47653 47971 '<span class="cke_menubutton_inner">' + 47654 47972 '<span class="cke_menubutton_icon">' + … … 47658 47976 '{label}' + 47659 47977 '</span>' + 47978 '{shortcutHtml}' + 47660 47979 '{arrowHtml}' + 47661 47980 '</span>' + 47662 '</a>< /span>';47981 '</a><span id="{id}_description" class="cke_voice_label" aria-hidden="false">{ariaShortcut}</span></span>'; 47663 47982 47664 47983 var menuArrowSource = '<span class="cke_menuarrow">' + … … 47666 47985 '</span>'; 47667 47986 47987 var menuShortcutSource = '<span class="cke_menubutton_label cke_menubutton_shortcut">' + 47988 '{shortcut}' + 47989 '</span>'; 47990 47668 47991 var menuItemTpl = CKEDITOR.addTemplate( 'menuItem', menuItemSource ), 47669 menuArrowTpl = CKEDITOR.addTemplate( 'menuArrow', menuArrowSource ); 47992 menuArrowTpl = CKEDITOR.addTemplate( 'menuArrow', menuArrowSource ), 47993 menuShortcutTpl = CKEDITOR.addTemplate( 'menuShortcut', menuShortcutSource ); 47670 47994 47671 47995 /** … … 48002 48326 var id = menu.id + String( index ), 48003 48327 state = ( typeof this.state == 'undefined' ) ? CKEDITOR.TRISTATE_OFF : this.state, 48004 ariaChecked = ''; 48328 ariaChecked = '', 48329 editor = this.editor, 48330 keystroke, 48331 command, 48332 shortcut; 48005 48333 48006 48334 var stateName = state == CKEDITOR.TRISTATE_ON ? 'on' : state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off'; … … 48017 48345 if ( this.icon && !( /\./ ).test( this.icon ) ) 48018 48346 iconName = this.icon; 48347 48348 if ( this.command ) { 48349 command = editor.getCommand( this.command ); 48350 keystroke = editor.getCommandKeystroke( command ); 48351 48352 if ( keystroke ) { 48353 shortcut = CKEDITOR.tools.keystrokeToString( editor.lang.common.keyboard, keystroke ); 48354 } 48355 } 48019 48356 48020 48357 var params = { … … 48027 48364 hasPopup: hasSubMenu ? 'true' : 'false', 48028 48365 disabled: state == CKEDITOR.TRISTATE_DISABLED, 48029 title: this.label, 48366 title: this.label + ( shortcut ? ' (' + shortcut.display + ')' : '' ), 48367 ariaShortcut: shortcut ? editor.lang.common.keyboardShortcut + ' ' + shortcut.aria : '', 48030 48368 href: 'javascript:void(\'' + ( this.label || '' ).replace( "'" + '' ) + '\')', // jshint ignore:line 48031 48369 hoverFn: menu._.itemOverFn, … … 48034 48372 index: index, 48035 48373 iconStyle: CKEDITOR.skin.getIconStyle( iconName, ( this.editor.lang.dir == 'rtl' ), iconName == this.icon ? null : this.icon, this.iconOffset ), 48374 shortcutHtml: shortcut ? menuShortcutTpl.output( { shortcut: shortcut.display } ) : '', 48036 48375 arrowHtml: hasSubMenu ? menuArrowTpl.output( { label: arrowLabel } ) : '', 48037 48376 role: this.role ? this.role : 'menuitem', … … 48261 48600 def = new CKEDITOR.dialogCommand( 'numberedListStyle', { 48262 48601 requiredContent: 'ol', 48263 allowedContent: 'ol{list-style-type}[start]' 48602 allowedContent: 'ol{list-style-type}[start]; li{list-style-type}[value]', 48603 contentTransformations: [ 48604 [ 'ol: listTypeToStyle' ] 48605 ] 48264 48606 } ); 48265 48607 cmd = editor.addCommand( 'numberedListStyle', def ); … … 48269 48611 def = new CKEDITOR.dialogCommand( 'bulletedListStyle', { 48270 48612 requiredContent: 'ul', 48271 allowedContent: 'ul{list-style-type}' 48613 allowedContent: 'ul{list-style-type}', 48614 contentTransformations: [ 48615 [ 'ul: listTypeToStyle' ] 48616 ] 48272 48617 } ); 48273 48618 cmd = editor.addCommand( 'bulletedListStyle', def ); … … 50423 50768 50424 50769 ( function() { 50770 /* global confirm */ 50771 50425 50772 CKEDITOR.plugins.add( 'pastefromword', { 50426 50773 requires: 'clipboard', … … 50474 50821 } ); 50475 50822 50476 // Features br ingby this command beside the normal process:50823 // Features brought by this command beside the normal process: 50477 50824 // 1. No more bothering of user about the clean-up. 50478 // 2. Perform the clean-up even if content is not from M S-Word.50479 // (e.g. from a M S-Word similar application.)50825 // 2. Perform the clean-up even if content is not from Microsoft Word. 50826 // (e.g. from a Microsoft Word similar application.) 50480 50827 // 3. Listen with high priority (3), so clean up is done before content 50481 50828 // type sniffing (priority = 6). 50482 50829 editor.on( 'paste', function( evt ) { 50483 50830 var data = evt.data, 50484 mswordHtml = data.dataValue; 50485 50486 // MS-WORD format sniffing. 50487 if ( mswordHtml && ( forceFromWord || ( /(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/ ).test( mswordHtml ) ) ) { 50488 // Do not apply paste filter to data filtered by the Word filter (#13093). 50489 data.dontFilter = true; 50490 50491 // If filter rules aren't loaded then cancel 'paste' event, 50492 // load them and when they'll get loaded fire new paste event 50493 // for which data will be filtered in second execution of 50494 // this listener. 50495 var isLazyLoad = loadFilterRules( editor, path, function() { 50496 // Event continuation with the original data. 50497 if ( isLazyLoad ) 50498 editor.fire( 'paste', data ); 50499 else if ( !editor.config.pasteFromWordPromptCleanup || ( forceFromWord || confirm( editor.lang.pastefromword.confirmCleanup ) ) ) // jshint ignore:line 50500 data.dataValue = CKEDITOR.cleanWord( mswordHtml, editor ); 50501 50502 // Reset forceFromWord. 50503 forceFromWord = 0; 50504 } ); 50505 50506 // The cleanup rules are to be loaded, we should just cancel 50507 // this event. 50508 isLazyLoad && evt.cancel(); 50509 } 50831 mswordHtml = data.dataValue, 50832 wordRegexp = /(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument|<o:\w+>|<\/font>)/, 50833 pfwEvtData = { dataValue: mswordHtml }; 50834 50835 if ( !mswordHtml || !( forceFromWord || wordRegexp.test( mswordHtml ) ) ) { 50836 return; 50837 } 50838 50839 // PFW might still get prevented, if it's not forced. 50840 if ( editor.fire( 'pasteFromWord', pfwEvtData ) === false && !forceFromWord ) { 50841 return; 50842 } 50843 50844 // Do not apply paste filter to data filtered by the Word filter (#13093). 50845 data.dontFilter = true; 50846 50847 // If filter rules aren't loaded then cancel 'paste' event, 50848 // load them and when they'll get loaded fire new paste event 50849 // for which data will be filtered in second execution of 50850 // this listener. 50851 var isLazyLoad = loadFilterRules( editor, path, function() { 50852 // Event continuation with the original data. 50853 if ( isLazyLoad ) { 50854 editor.fire( 'paste', data ); 50855 } else if ( !editor.config.pasteFromWordPromptCleanup || ( forceFromWord || confirm( editor.lang.pastefromword.confirmCleanup ) ) ) { 50856 pfwEvtData.dataValue = CKEDITOR.cleanWord( pfwEvtData.dataValue, editor ); 50857 50858 editor.fire( 'afterPasteFromWord', pfwEvtData ); 50859 50860 data.dataValue = pfwEvtData.dataValue; 50861 } 50862 50863 // Reset forceFromWord. 50864 forceFromWord = 0; 50865 } ); 50866 50867 // The cleanup rules are to be loaded, we should just cancel 50868 // this event. 50869 isLazyLoad && evt.cancel(); 50510 50870 }, null, null, 3 ); 50511 50871 } … … 50535 50895 50536 50896 /** 50537 * Whether to prompt the user about the clean up of content being pasted from M SWord.50897 * Whether to prompt the user about the clean up of content being pasted from Microsoft Word. 50538 50898 * 50539 50899 * config.pasteFromWordPromptCleanup = true; … … 50545 50905 50546 50906 /** 50547 * The file that provides the M SWord cleanup function for pasting operations.50907 * The file that provides the Microsoft Word cleanup function for pasting operations. 50548 50908 * 50549 50909 * **Note:** This is a global configuration shared by all editor instances present 50550 * in the page.50551 * 50552 * // Load from 'pastefromword' plugin 'filter' sub folder (custom.js file) using path relative toCKEditor installation folder.50910 * on the page. 50911 * 50912 * // Load from the 'pastefromword' plugin 'filter' sub folder (custom.js file) using a path relative to the CKEditor installation folder. 50553 50913 * CKEDITOR.config.pasteFromWordCleanupFile = 'plugins/pastefromword/filter/custom.js'; 50554 50914 * 50555 * // Load from 'pastefromword' plugin 'filter' sub folder (custom.js file) using full path (includingCKEditor installation folder).50915 * // Load from the 'pastefromword' plugin 'filter' sub folder (custom.js file) using a full path (including the CKEditor installation folder). 50556 50916 * CKEDITOR.config.pasteFromWordCleanupFile = '/ckeditor/plugins/pastefromword/filter/custom.js'; 50557 50917 * 50558 * // Load custom.js file from 'customFilerts' folder (located in server's root) usingfull URL.50559 * CKEDITOR.config.pasteFromWordCleanupFile = 'http://my.example.com/customFil erts/custom.js';50918 * // Load custom.js file from the 'customFilters' folder (located in server's root) using the full URL. 50919 * CKEDITOR.config.pasteFromWordCleanupFile = 'http://my.example.com/customFilters/custom.js'; 50560 50920 * 50561 50921 * @since 3.1 … … 50564 50924 */ 50565 50925 50926 /** 50927 * Fired when the pasted content was recognized as Microsoft Word content. 50928 * 50929 * This event is cancellable. If canceled, it will prevent Paste from Word processing. 50930 * 50931 * @since 4.6.0 50932 * @event pasteFromWord 50933 * @param data 50934 * @param {String} data.dataValue Pasted content. Changes to this property will affect the pasted content. 50935 * @member CKEDITOR.editor 50936 */ 50937 50938 /** 50939 * Fired after the Paste form Word filters have been applied. 50940 * 50941 * @since 4.6.0 50942 * @event afterPasteFromWord 50943 * @param data 50944 * @param {String} data.dataValue Pasted content after processing. Changes to this property will affect the pasted content. 50945 * @member CKEDITOR.editor 50946 */ 50566 50947 /** 50567 50948 * Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. … … 51348 51729 var styleDefinition = stylesDefinitions[ i ]; 51349 51730 51350 if ( editor.blockless && ( styleDefinition.element in CKEDITOR.dtd.$block ) ) 51731 if ( editor.blockless && ( styleDefinition.element in CKEDITOR.dtd.$block ) || 51732 ( typeof styleDefinition.type == 'string' && !CKEDITOR.style.customHandlers[ styleDefinition.type ] ) ) { 51733 51351 51734 continue; 51735 } 51352 51736 51353 51737 styleName = styleDefinition.name; … … 51834 52218 requiredContent: 'table', 51835 52219 contentTransformations: [ 51836 [ 'table{width}: sizeToStyle', 'table[width]: sizeToAttribute' ] 52220 [ 'table{width}: sizeToStyle', 'table[width]: sizeToAttribute' ], 52221 [ 'td: splitBorderShorthand' ], 52222 [ { 52223 element: 'table', 52224 right: function( element ) { 52225 if ( element.styles ) { 52226 if ( element.styles.border && element.styles.border.match( /solid/ ) ) { 52227 element.attributes.border = 1; 52228 } 52229 if ( element.styles[ 'border-collapse' ] == 'collapse' ) { 52230 element.attributes.cellspacing = 0; 52231 } 52232 } 52233 } 52234 } ] 51837 52235 ] 51838 52236 } ) ); … … 52581 52979 addCmd( 'cellProperties', new CKEDITOR.dialogCommand( 'cellProperties', createDef( { 52582 52980 allowedContent: 'td th{width,height,border-color,background-color,white-space,vertical-align,text-align}[colspan,rowspan]', 52583 requiredContent: 'table' 52981 requiredContent: 'table', 52982 contentTransformations: [ 52983 [ { 52984 element: 'td', 52985 left: function( element ) { 52986 return element.styles.background && element.styles.background.match( /^(#[a-fA-F0-9]{3,6}|rgb\([\d, ]+\)|\w+)$/ ); 52987 }, 52988 right: function( element ) { 52989 element.styles[ 'background-color' ] = element.styles.background; 52990 } 52991 } ] 52992 ] 52584 52993 } ) ) ); 52585 52994 CKEDITOR.dialog.add( 'cellProperties', this.path + 'dialogs/tableCell.js' ); … … 52994 53403 * config.templates_files = [ 52995 53404 * '/editor_templates/site_default.js', 52996 * 'http://www.example.com/user_templates.js 53405 * 'http://www.example.com/user_templates.js' 52997 53406 * ]; 52998 53407 * … … 53206 53615 53207 53616 var toolbars = editor.toolbox.toolbars, 53208 toolbar = getToolbarConfig( editor ); 53209 53210 for ( var r = 0; r < toolbar.length; r++ ) { 53617 toolbar = getToolbarConfig( editor ), 53618 toolbarLength = toolbar.length; 53619 53620 for ( var r = 0; r < toolbarLength; r++ ) { 53211 53621 var toolbarId, 53212 53622 toolbarObj = 0, 53213 53623 toolbarName, 53214 53624 row = toolbar[ r ], 53625 lastToolbarInRow = row !== '/' && ( toolbar[ r + 1 ] === '/' || r == toolbarLength - 1 ), 53215 53626 items; 53216 53627 … … 53260 53671 53261 53672 // Output the toolbar opener. 53262 output.push( '<span id="', toolbarId, '" class="cke_toolbar"', ( toolbarName ? ' aria-labelledby="' + toolbarId + '_label"' : '' ), ' role="toolbar">' ); 53673 output.push( '<span id="', toolbarId, '" class="cke_toolbar' + ( lastToolbarInRow ? ' cke_toolbar_last"' : '"' ), 53674 ( toolbarName ? ' aria-labelledby="' + toolbarId + '_label"' : '' ), ' role="toolbar">' ); 53263 53675 53264 53676 // If a toolbar name is available, send the voice label.
Note: See TracChangeset
for help on using the changeset viewer.