diff -r 346c88efed21 -r 5e2f62d02dcd wp/wp-includes/js/tinymce/plugins/wordpress/plugin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wp/wp-includes/js/tinymce/plugins/wordpress/plugin.js Tue Jun 09 03:35:32 2015 +0200 @@ -0,0 +1,754 @@ +/* global tinymce, getUserSetting, setUserSetting */ + +// Set the minimum value for the modals z-index higher than #wpadminbar (100000) +tinymce.ui.FloatPanel.zIndex = 100100; + +tinymce.PluginManager.add( 'wordpress', function( editor ) { + var DOM = tinymce.DOM, + each = tinymce.each, + __ = editor.editorManager.i18n.translate, + wpAdvButton, style, + last = 0; + + if ( typeof window.jQuery !== 'undefined' ) { + window.jQuery( document ).triggerHandler( 'tinymce-editor-setup', [ editor ] ); + } + + function toggleToolbars( state ) { + var iframe, initial, toolbars, + pixels = 0; + + initial = ( state === 'hide' ); + + if ( editor.theme.panel ) { + toolbars = editor.theme.panel.find('.toolbar:not(.menubar)'); + } + + if ( ! toolbars || toolbars.length < 2 || ( state === 'hide' && ! toolbars[1].visible() ) ) { + return; + } + + if ( ! state && toolbars[1].visible() ) { + state = 'hide'; + } + + each( toolbars, function( toolbar, i ) { + if ( i > 0 ) { + if ( state === 'hide' ) { + toolbar.hide(); + pixels += 30; + } else { + toolbar.show(); + pixels -= 30; + } + } + }); + + if ( pixels && ! initial ) { + // Resize iframe, not needed in iOS + if ( ! tinymce.Env.iOS ) { + iframe = editor.getContentAreaContainer().firstChild; + DOM.setStyle( iframe, 'height', iframe.clientHeight + pixels ); + } + + if ( state === 'hide' ) { + setUserSetting('hidetb', '0'); + wpAdvButton && wpAdvButton.active( false ); + } else { + setUserSetting('hidetb', '1'); + wpAdvButton && wpAdvButton.active( true ); + } + } + + editor.fire( 'wp-toolbar-toggle' ); + } + + // Add the kitchen sink button :) + editor.addButton( 'wp_adv', { + tooltip: 'Toolbar Toggle', + cmd: 'WP_Adv', + onPostRender: function() { + wpAdvButton = this; + wpAdvButton.active( getUserSetting( 'hidetb' ) === '1' ? true : false ); + } + }); + + // Hide the toolbars after loading + editor.on( 'PostRender', function() { + if ( editor.getParam( 'wordpress_adv_hidden', true ) && getUserSetting( 'hidetb', '0' ) === '0' ) { + toggleToolbars( 'hide' ); + } + }); + + editor.addCommand( 'WP_Adv', function() { + toggleToolbars(); + }); + + editor.on( 'focus', function() { + window.wpActiveEditor = editor.id; + }); + + // Replace Read More/Next Page tags with images + editor.on( 'BeforeSetContent', function( e ) { + var title; + + if ( e.content ) { + if ( e.content.indexOf( '/g, function( match, moretext ) { + return ''; + }); + } + + if ( e.content.indexOf( '' ) !== -1 ) { + title = __( 'Page break' ); + + e.content = e.content.replace( //g, + '' ); + } + } + }); + + // Replace images with tags + editor.on( 'PostProcess', function( e ) { + if ( e.get ) { + e.content = e.content.replace(/]+>/g, function( image ) { + var match, moretext = ''; + + if ( image.indexOf( 'data-wp-more="more"' ) !== -1 ) { + if ( match = image.match( /data-wp-more-text="([^"]+)"/ ) ) { + moretext = match[1]; + } + + image = ''; + } else if ( image.indexOf( 'data-wp-more="nextpage"' ) !== -1 ) { + image = ''; + } + + return image; + }); + } + }); + + // Display the tag name instead of img in element path + editor.on( 'ResolveName', function( event ) { + var attr; + + if ( event.target.nodeName === 'IMG' && ( attr = editor.dom.getAttrib( event.target, 'data-wp-more' ) ) ) { + event.name = attr; + } + }); + + // Register commands + editor.addCommand( 'WP_More', function( tag ) { + var parent, html, title, + classname = 'wp-more-tag', + dom = editor.dom, + node = editor.selection.getNode(); + + tag = tag || 'more'; + classname += ' mce-wp-' + tag; + title = tag === 'more' ? 'Read more...' : 'Next page'; + title = __( title ); + html = ''; + + // Most common case + if ( node.nodeName === 'BODY' || ( node.nodeName === 'P' && node.parentNode.nodeName === 'BODY' ) ) { + editor.insertContent( html ); + return; + } + + // Get the top level parent node + parent = dom.getParent( node, function( found ) { + if ( found.parentNode && found.parentNode.nodeName === 'BODY' ) { + return true; + } + + return false; + }, editor.getBody() ); + + if ( parent ) { + if ( parent.nodeName === 'P' ) { + parent.appendChild( dom.create( 'p', null, html ).firstChild ); + } else { + dom.insertAfter( dom.create( 'p', null, html ), parent ); + } + + editor.nodeChanged(); + } + }); + + editor.addCommand( 'WP_Code', function() { + editor.formatter.toggle('code'); + }); + + editor.addCommand( 'WP_Page', function() { + editor.execCommand( 'WP_More', 'nextpage' ); + }); + + editor.addCommand( 'WP_Help', function() { + editor.windowManager.open({ + url: tinymce.baseURL + '/wp-mce-help.php', + title: 'Keyboard Shortcuts', + width: 450, + height: 420, + classes: 'wp-help', + buttons: { text: 'Close', onclick: 'close' } + }); + }); + + editor.addCommand( 'WP_Medialib', function() { + if ( typeof wp !== 'undefined' && wp.media && wp.media.editor ) { + wp.media.editor.open( editor.id ); + } + }); + + // Register buttons + editor.addButton( 'wp_more', { + tooltip: 'Insert Read More tag', + onclick: function() { + editor.execCommand( 'WP_More', 'more' ); + } + }); + + editor.addButton( 'wp_page', { + tooltip: 'Page break', + onclick: function() { + editor.execCommand( 'WP_More', 'nextpage' ); + } + }); + + editor.addButton( 'wp_help', { + tooltip: 'Keyboard Shortcuts', + cmd: 'WP_Help' + }); + + editor.addButton( 'wp_code', { + tooltip: 'Code', + cmd: 'WP_Code', + stateSelector: 'code' + }); + + // Menubar + // Insert->Add Media + if ( typeof wp !== 'undefined' && wp.media && wp.media.editor ) { + editor.addMenuItem( 'add_media', { + text: 'Add Media', + icon: 'wp-media-library', + context: 'insert', + cmd: 'WP_Medialib' + }); + } + + // Insert "Read More..." + editor.addMenuItem( 'wp_more', { + text: 'Insert Read More tag', + icon: 'wp_more', + context: 'insert', + onclick: function() { + editor.execCommand( 'WP_More', 'more' ); + } + }); + + // Insert "Next Page" + editor.addMenuItem( 'wp_page', { + text: 'Page break', + icon: 'wp_page', + context: 'insert', + onclick: function() { + editor.execCommand( 'WP_More', 'nextpage' ); + } + }); + + editor.on( 'BeforeExecCommand', function(e) { + if ( tinymce.Env.webkit && ( e.command === 'InsertUnorderedList' || e.command === 'InsertOrderedList' ) ) { + if ( ! style ) { + style = editor.dom.create( 'style', {'type': 'text/css'}, + '#tinymce,#tinymce span,#tinymce li,#tinymce li>span,#tinymce p,#tinymce p>span{font:medium sans-serif;color:#000;line-height:normal;}'); + } + + editor.getDoc().head.appendChild( style ); + } + }); + + editor.on( 'ExecCommand', function( e ) { + if ( tinymce.Env.webkit && style && + ( 'InsertUnorderedList' === e.command || 'InsertOrderedList' === e.command ) ) { + + editor.dom.remove( style ); + } + }); + + editor.on( 'init', function() { + var env = tinymce.Env, + bodyClass = ['mceContentBody'], // back-compat for themes that use this in editor-style.css... + doc = editor.getDoc(), + dom = editor.dom; + + if ( tinymce.Env.iOS ) { + dom.addClass( doc.documentElement, 'ios' ); + } + + if ( editor.getParam( 'directionality' ) === 'rtl' ) { + bodyClass.push('rtl'); + dom.setAttrib( doc.documentElement, 'dir', 'rtl' ); + } + + if ( env.ie ) { + if ( parseInt( env.ie, 10 ) === 9 ) { + bodyClass.push('ie9'); + } else if ( parseInt( env.ie, 10 ) === 8 ) { + bodyClass.push('ie8'); + } else if ( env.ie < 8 ) { + bodyClass.push('ie7'); + } + } else if ( env.webkit ) { + bodyClass.push('webkit'); + } + + bodyClass.push('wp-editor'); + + each( bodyClass, function( cls ) { + if ( cls ) { + dom.addClass( doc.body, cls ); + } + }); + + // Remove invalid parent paragraphs when inserting HTML + // TODO: still needed? + editor.on( 'BeforeSetContent', function( e ) { + if ( e.content ) { + e.content = e.content.replace(/

\s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)( [^>]*)?>/gi, '<$1$2>'); + e.content = e.content.replace(/<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)>\s*<\/p>/gi, ''); + } + }); + + if ( typeof window.jQuery !== 'undefined' ) { + window.jQuery( document ).triggerHandler( 'tinymce-editor-init', [editor] ); + } + + if ( window.tinyMCEPreInit && window.tinyMCEPreInit.dragDropUpload ) { + dom.bind( doc, 'dragstart dragend dragover drop', function( event ) { + if ( typeof window.jQuery !== 'undefined' ) { + // Trigger the jQuery handlers. + window.jQuery( document ).trigger( new window.jQuery.Event( event ) ); + } + }); + } + + if ( editor.getParam( 'wp_paste_filters', true ) ) { + if ( ! tinymce.Env.webkit ) { + // In WebKit handled by removeWebKitStyles() + editor.on( 'PastePreProcess', function( event ) { + // Remove all inline styles + event.content = event.content.replace( /(<[^>]+) style="[^"]*"([^>]*>)/gi, '$1$2' ); + + // Put back the internal styles + event.content = event.content.replace(/(<[^>]+) data-mce-style=([^>]+>)/gi, '$1 style=$2' ); + }); + } + + editor.on( 'PastePostProcess', function( event ) { + // Remove empty paragraphs + each( dom.select( 'p', event.node ), function( node ) { + if ( dom.isEmpty( node ) ) { + dom.remove( node ); + } + }); + }); + } + }); + + // Word count + if ( typeof window.jQuery !== 'undefined' ) { + editor.on( 'keyup', function( e ) { + var key = e.keyCode || e.charCode; + + if ( key === last ) { + return; + } + + if ( 13 === key || 8 === last || 46 === last ) { + window.jQuery( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ] ); + } + + last = key; + }); + } + + editor.on( 'SaveContent', function( e ) { + // If editor is hidden, we just want the textarea's value to be saved + if ( ! editor.inline && editor.isHidden() ) { + e.content = e.element.value; + return; + } + + // Keep empty paragraphs :( + e.content = e.content.replace( /

(?:
|\u00a0|\uFEFF| )*<\/p>/g, '

 

' ); + + if ( editor.getParam( 'wpautop', true ) && typeof window.switchEditors !== 'undefined' ) { + e.content = window.switchEditors.pre_wpautop( e.content ); + } + }); + + // Remove spaces from empty paragraphs. + editor.on( 'BeforeSetContent', function( event ) { + var paragraph = tinymce.Env.webkit ? '


' : '

'; + + if ( event.content ) { + event.content = event.content.replace( /

(?: |\u00a0|\uFEFF|\s)+<\/p>/gi, paragraph ); + } + }); + + editor.on( 'preInit', function() { + // Don't replace with and with and don't remove them when empty + editor.schema.addValidElements( '@[id|accesskey|class|dir|lang|style|tabindex|title|contenteditable|draggable|dropzone|hidden|spellcheck|translate],i,b' ); + + if ( tinymce.Env.iOS ) { + editor.settings.height = 300; + } + + each( { + c: 'JustifyCenter', + r: 'JustifyRight', + l: 'JustifyLeft', + j: 'JustifyFull', + q: 'mceBlockQuote', + u: 'InsertUnorderedList', + o: 'InsertOrderedList', + s: 'unlink', + m: 'WP_Medialib', + z: 'WP_Adv', + t: 'WP_More', + d: 'Strikethrough', + h: 'WP_Help', + p: 'WP_Page', + x: 'WP_Code' + }, function( command, key ) { + editor.shortcuts.add( 'access+' + key, '', command ); + } ); + + editor.addShortcut( 'meta+s', '', function() { + if ( typeof wp !== 'undefined' && wp.autosave ) { + wp.autosave.server.triggerSave(); + } + } ); + } ); + + /** + * Experimental: create a floating toolbar. + * This functionality will change in the next releases. Not recommended for use by plugins. + */ + ( function() { + var Factory = tinymce.ui.Factory, + settings = editor.settings, + currentToolbar, + currentSelection; + + function create( buttons ) { + var toolbar, + toolbarItems = [], + buttonGroup; + + each( buttons, function( item ) { + var itemName; + + function bindSelectorChanged() { + var selection = editor.selection; + + if ( itemName === 'bullist' ) { + selection.selectorChanged( 'ul > li', function( state, args ) { + var i = args.parents.length, + nodeName; + + while ( i-- ) { + nodeName = args.parents[ i ].nodeName; + + if ( nodeName === 'OL' || nodeName == 'UL' ) { + break; + } + } + + item.active( state && nodeName === 'UL' ); + } ); + } + + if ( itemName === 'numlist' ) { + selection.selectorChanged( 'ol > li', function( state, args ) { + var i = args.parents.length, + nodeName; + + while ( i-- ) { + nodeName = args.parents[ i ].nodeName; + + if ( nodeName === 'OL' || nodeName === 'UL' ) { + break; + } + } + + item.active( state && nodeName === 'OL' ); + } ); + } + + if ( item.settings.stateSelector ) { + selection.selectorChanged( item.settings.stateSelector, function( state ) { + item.active( state ); + }, true ); + } + + if ( item.settings.disabledStateSelector ) { + selection.selectorChanged( item.settings.disabledStateSelector, function( state ) { + item.disabled( state ); + } ); + } + } + + if ( item === '|' ) { + buttonGroup = null; + } else { + if ( Factory.has( item ) ) { + item = { + type: item + }; + + if ( settings.toolbar_items_size ) { + item.size = settings.toolbar_items_size; + } + + toolbarItems.push( item ); + + buttonGroup = null; + } else { + if ( ! buttonGroup ) { + buttonGroup = { + type: 'buttongroup', + items: [] + }; + + toolbarItems.push( buttonGroup ); + } + + if ( editor.buttons[ item ] ) { + itemName = item; + item = editor.buttons[ itemName ]; + + if ( typeof item === 'function' ) { + item = item(); + } + + item.type = item.type || 'button'; + + if ( settings.toolbar_items_size ) { + item.size = settings.toolbar_items_size; + } + + item = Factory.create( item ); + + buttonGroup.items.push( item ); + + if ( editor.initialized ) { + bindSelectorChanged(); + } else { + editor.on( 'init', bindSelectorChanged ); + } + } + } + } + } ); + + toolbar = Factory.create( { + type: 'panel', + layout: 'stack', + classes: 'toolbar-grp inline-toolbar-grp', + ariaRoot: true, + ariaRemember: true, + items: [ { + type: 'toolbar', + layout: 'flow', + items: toolbarItems + } ] + } ); + + function hide() { + toolbar.hide(); + } + + function reposition() { + var top, left, minTop, className, + windowPos, adminbar, mceToolbar, boundary, + boundaryMiddle, boundaryVerticalMiddle, spaceTop, + spaceBottom, windowWidth, toolbarWidth, toolbarHalf, + iframe, iframePos, iframeWidth, iframeHeigth, + toolbarNodeHeight, verticalSpaceNeeded, + toolbarNode = this.getEl(), + buffer = 5, + margin = 8, + adminbarHeight = 0; + + if ( ! currentSelection ) { + return; + } + + windowPos = window.pageYOffset || document.documentElement.scrollTop; + adminbar = tinymce.$( '#wpadminbar' )[0]; + mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0]; + boundary = currentSelection.getBoundingClientRect(); + boundaryMiddle = ( boundary.left + boundary.right ) / 2; + boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2; + spaceTop = boundary.top; + spaceBottom = iframeHeigth - boundary.bottom; + windowWidth = window.innerWidth; + toolbarWidth = toolbarNode.offsetWidth; + toolbarHalf = toolbarWidth / 2; + iframe = document.getElementById( editor.id + '_ifr' ); + iframePos = DOM.getPos( iframe ); + iframeWidth = iframe.offsetWidth; + iframeHeigth = iframe.offsetHeight; + toolbarNodeHeight = toolbarNode.offsetHeight; + verticalSpaceNeeded = toolbarNodeHeight + margin + buffer; + + if ( spaceTop >= verticalSpaceNeeded ) { + className = ' mce-arrow-down'; + top = boundary.top + iframePos.y - toolbarNodeHeight - margin; + } else if ( spaceBottom >= verticalSpaceNeeded ) { + className = ' mce-arrow-up'; + top = boundary.bottom + iframePos.y; + } else { + top = buffer; + + if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) { + className = ' mce-arrow-down'; + } else { + className = ' mce-arrow-up'; + } + } + + // Make sure the image toolbar is below the main toolbar. + if ( mceToolbar ) { + minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight; + } else { + minTop = iframePos.y; + } + + // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window. + if ( windowPos ) { + if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) { + adminbarHeight = adminbar.clientHeight; + } + + if ( windowPos + adminbarHeight > minTop ) { + minTop = windowPos + adminbarHeight; + } + } + + if ( top && minTop && ( minTop + buffer > top ) ) { + top = minTop + buffer; + className = ''; + } + + left = boundaryMiddle - toolbarHalf; + left += iframePos.x; + + if ( boundary.left < 0 || boundary.right > iframeWidth ) { + left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2; + } else if ( toolbarWidth >= windowWidth ) { + className += ' mce-arrow-full'; + left = 0; + } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) || + ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) { + + left = ( windowWidth - toolbarWidth ) / 2; + } else if ( left < iframePos.x ) { + className += ' mce-arrow-left'; + left = boundary.left + iframePos.x; + } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) { + className += ' mce-arrow-right'; + left = boundary.right - toolbarWidth + iframePos.x; + } + + toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' ); + toolbarNode.className += className; + + DOM.setStyles( toolbarNode, { 'left': left, 'top': top } ); + + return this; + } + + toolbar.on( 'show', function() { + currentToolbar = this; + this.reposition(); + } ); + + toolbar.on( 'hide', function() { + currentToolbar = false; + } ); + + toolbar.on( 'keydown', function( event ) { + if ( event.keyCode === 27 ) { + this.hide(); + editor.focus(); + } + } ); + + toolbar.on( 'remove', function() { + DOM.unbind( window, 'resize scroll', hide ); + editor.dom.unbind( editor.getWin(), 'resize scroll', hide ); + editor.off( 'blur hide', hide ); + } ); + + editor.once( 'init', function() { + DOM.bind( window, 'resize scroll', hide ); + editor.dom.bind( editor.getWin(), 'resize scroll', hide ); + editor.on( 'blur hide', hide ); + } ); + + toolbar.reposition = reposition; + toolbar.hide().renderTo( document.body ); + + return toolbar; + } + + editor.shortcuts.add( 'alt+119', '', function() { + var node; + + if ( currentToolbar ) { + node = currentToolbar.find( 'toolbar' )[0]; + node && node.focus( true ); + } + } ); + + editor.on( 'nodechange', function( event ) { + var collapsed = editor.selection.isCollapsed(); + + var args = { + element: event.element, + parents: event.parents, + collapsed: collapsed + }; + + editor.fire( 'wptoolbar', args ); + + currentSelection = args.selection || args.element; + + currentToolbar && currentToolbar.hide(); + args.toolbar && args.toolbar.show(); + } ); + + editor.wp = editor.wp || {}; + editor.wp._createToolbar = create; + }()); + + function noop() {} + + // Expose some functions (back-compat) + return { + _showButtons: noop, + _hideButtons: noop, + _setEmbed: noop, + _getEmbed: noop + }; +});