X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/7f1521bf193b382565eb753043c161f4cb3fcda7..4feeb71a9d812a9ae371c28a3d8b442a4394ded7:/wp-includes/js/mce-view.js diff --git a/wp-includes/js/mce-view.js b/wp-includes/js/mce-view.js index eab4560c..b532cb97 100644 --- a/wp-includes/js/mce-view.js +++ b/wp-includes/js/mce-view.js @@ -1,7 +1,5 @@ /* global tinymce */ -window.wp = window.wp || {}; - /* * The TinyMCE view API. * @@ -24,7 +22,7 @@ window.wp = window.wp || {}; * |- registered view * | |- ... */ -( function( window, wp, $ ) { +( function( window, wp, shortcode, $ ) { 'use strict'; var views = {}, @@ -93,8 +91,7 @@ window.wp = window.wp || {}; setMarkers: function( content ) { var pieces = [ { content: content } ], self = this, - instance, - current; + instance, current; _.each( views, function( view, type ) { current = pieces.slice(); @@ -102,7 +99,7 @@ window.wp = window.wp || {}; _.each( current, function( piece ) { var remaining = piece.content, - result; + result, text; // Ignore processed pieces, but retain their location. if ( piece.processed ) { @@ -119,10 +116,11 @@ window.wp = window.wp || {}; } instance = self.createInstance( type, result.content, result.options ); + text = instance.loader ? '.' : instance.text; // Add the processed piece for the match. pieces.push( { - content: '

' + instance.text + '

', + content: instance.ignore ? text : '

' + text + '

', processed: true } ); @@ -138,31 +136,37 @@ window.wp = window.wp || {}; } ); } ); - return _.pluck( pieces, 'content' ).join( '' ); + content = _.pluck( pieces, 'content' ).join( '' ); + return content.replace( /

\s*

' ); }, /** * Create a view instance. * - * @param {String} type The view type. - * @param {String} text The textual representation of the view. - * @param {Object} options Options. + * @param {String} type The view type. + * @param {String} text The textual representation of the view. + * @param {Object} options Options. + * @param {Boolean} force Recreate the instance. Optional. * * @return {wp.mce.View} The view instance. */ - createInstance: function( type, text, options ) { + createInstance: function( type, text, options, force ) { var View = this.get( type ), encodedText, instance; - text = tinymce.DOM.decode( text ), - encodedText = encodeURIComponent( text ), - instance = this.getInstance( encodedText ); + text = tinymce.DOM.decode( text ); - if ( instance ) { - return instance; + if ( ! force ) { + instance = this.getInstance( text ); + + if ( instance ) { + return instance; + } } + encodedText = encodeURIComponent( text ); + options = _.extend( options || {}, { text: text, encodedText: encodedText @@ -214,12 +218,13 @@ window.wp = window.wp || {}; * @param {String} text The new text. * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in. * @param {HTMLElement} node The view node to update. + * @param {Boolean} force Recreate the instance. Optional. */ - update: function( text, editor, node ) { + update: function( text, editor, node, force ) { var instance = this.getInstance( node ); if ( instance ) { - instance.update( text, editor, node ); + instance.update( text, editor, node, force ); } }, @@ -233,8 +238,8 @@ window.wp = window.wp || {}; var instance = this.getInstance( node ); if ( instance && instance.edit ) { - instance.edit( instance.text, function( text ) { - instance.update( text, editor, node ); + instance.edit( instance.text, function( text, force ) { + instance.update( text, editor, node, force ); } ); } }, @@ -300,8 +305,8 @@ window.wp = window.wp || {}; /** * Renders all view nodes tied to this view instance that are not yet rendered. * - * @param {String} content The content to render. Optional. - * @param {Boolean} force Rerender all view nodes tied to this view instance. + * @param {String} content The content to render. Optional. + * @param {Boolean} force Rerender all view nodes tied to this view instance. Optional. */ render: function( content, force ) { if ( content != null ) { @@ -416,23 +421,29 @@ window.wp = window.wp || {}; */ replaceMarkers: function() { this.getMarkers( function( editor, node ) { - if ( $( node ).text() !== this.text ) { + var selected = node === editor.selection.getNode(), + $viewNode; + + if ( ! this.loader && $( node ).text() !== this.text ) { editor.dom.setAttrib( node, 'data-wpview-marker', null ); return; } - editor.dom.replace( - editor.dom.createFragment( - '

' + - '

\u00a0

' + - '
' + - '
' + - '
' + - '

\u00a0

' + - '
' - ), - node + $viewNode = editor.$( + '
' + + '

\u00a0

' + + '
' + + '
' + + '
' + + '

\u00a0

' + + '
' ); + + editor.$( node ).replaceWith( $viewNode ); + + if ( selected ) { + editor.wp.setViewCursor( false, $viewNode[0] ); + } } ); }, @@ -499,10 +510,17 @@ window.wp = window.wp || {}; } } ); + if ( self.iframeHeight ) { + dom.add( contentNode, 'div', { style: { + width: '100%', + height: self.iframeHeight + } } ); + } + // Seems the browsers need a bit of time to insert/set the view nodes, // or the iframe will fail especially when switching Text => Visual. setTimeout( function() { - var iframe, iframeDoc, observer, i; + var iframe, iframeDoc, observer, i, block; contentNode.innerHTML = ''; @@ -516,7 +534,8 @@ window.wp = window.wp || {}; style: { width: '100%', display: 'block' - } + }, + height: self.iframeHeight } ); dom.add( contentNode, 'div', { 'class': 'wpview-overlay' } ); @@ -559,20 +578,33 @@ window.wp = window.wp || {}; iframeDoc.close(); function resize() { - var $iframe, iframeDocHeight; + var $iframe; + + if ( block ) { + return; + } // Make sure the iframe still exists. if ( iframe.contentWindow ) { $iframe = $( iframe ); - iframeDocHeight = $( iframeDoc.body ).height(); + self.iframeHeight = $( iframeDoc.body ).height(); - if ( $iframe.height() !== iframeDocHeight ) { - $iframe.height( iframeDocHeight ); + if ( $iframe.height() !== self.iframeHeight ) { + $iframe.height( self.iframeHeight ); editor.nodeChanged(); } } } + if ( self.iframeHeight ) { + block = true; + + setTimeout( function() { + block = false; + resize(); + }, 3000 ); + } + $( iframe.contentWindow ).on( 'load', resize ); if ( MutationObserver ) { @@ -624,7 +656,7 @@ window.wp = window.wp || {}; * Sets an error for all view nodes tied to this view instance. * * @param {String} message The error message to set. - * @param {String} dashicon A dashicon ID (optional). {@link https://developer.wordpress.org/resource/dashicons/} + * @param {String} dashicon A dashicon ID. Optional. {@link https://developer.wordpress.org/resource/dashicons/} */ setError: function( message, dashicon ) { this.setContent( @@ -643,7 +675,7 @@ window.wp = window.wp || {}; * @return {Object} */ match: function( content ) { - var match = wp.shortcode.next( this.type, content ); + var match = shortcode.next( this.type, content ); if ( match ) { return { @@ -662,15 +694,16 @@ window.wp = window.wp || {}; * @param {String} text The new text. * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in. * @param {HTMLElement} node The view node to update. + * @param {Boolean} force Recreate the instance. Optional. */ - update: function( text, editor, node ) { + update: function( text, editor, node, force ) { _.find( views, function( view, type ) { var match = view.prototype.match( text ); if ( match ) { $( node ).data( 'rendered', false ); editor.dom.setAttrib( node, 'data-wpview-text', encodeURIComponent( text ) ); - wp.mce.views.createInstance( type, text, match.options ).render(); + wp.mce.views.createInstance( type, text, match.options, force ).render(); editor.focus(); return true; @@ -691,29 +724,47 @@ window.wp = window.wp || {}; editor.focus(); } } ); -} )( window, window.wp, window.jQuery ); +} )( window, window.wp, window.wp.shortcode, window.jQuery ); /* * The WordPress core TinyMCE views. * Views for the gallery, audio, video, playlist and embed shortcodes, * and a view for embeddable URLs. */ -( function( window, views, $ ) { - var postID = $( '#post_ID' ).val() || 0, - media, gallery, av, embed; +( function( window, views, media, $ ) { + var base, gallery, av, embed, + schema, parser, serializer; + + function verifyHTML( string ) { + var settings = {}; + + if ( ! window.tinymce ) { + return string.replace( /<[^>]+>/g, '' ); + } + + if ( ! string || ( string.indexOf( '<' ) === -1 && string.indexOf( '>' ) === -1 ) ) { + return string; + } + + schema = schema || new window.tinymce.html.Schema( settings ); + parser = parser || new window.tinymce.html.DomParser( settings, schema ); + serializer = serializer || new window.tinymce.html.Serializer( settings, schema ); + + return serializer.serialize( parser.parse( string, { forced_root_block: false } ) ); + } - media = { + base = { state: [], edit: function( text, update ) { - var media = wp.media[ this.type ], - frame = media.edit( text ); + var type = this.type, + frame = media[ type ].edit( text ); this.pausePlayers && this.pausePlayers(); _.each( this.state, function( state ) { frame.state( state ).on( 'update', function( selection ) { - update( media.shortcode( selection ).string() ); + update( media[ type ].shortcode( selection ).string(), type === 'gallery' ); } ); } ); @@ -725,12 +776,12 @@ window.wp = window.wp || {}; } }; - gallery = _.extend( {}, media, { + gallery = _.extend( {}, base, { state: [ 'gallery-edit' ], - template: wp.media.template( 'editor-gallery' ), + template: media.template( 'editor-gallery' ), initialize: function() { - var attachments = wp.media.gallery.attachments( this.shortcode, postID ), + var attachments = media.gallery.attachments( this.shortcode, media.view.settings.post.id ), attrs = this.shortcode.attrs.named, self = this; @@ -751,8 +802,9 @@ window.wp = window.wp || {}; } ); self.render( self.template( { + verifyHTML: verifyHTML, attachments: attachments, - columns: attrs.columns ? parseInt( attrs.columns, 10 ) : wp.media.galleryDefaults.columns + columns: attrs.columns ? parseInt( attrs.columns, 10 ) : media.galleryDefaults.columns } ) ); } ) .fail( function( jqXHR, textStatus ) { @@ -761,7 +813,7 @@ window.wp = window.wp || {}; } } ); - av = _.extend( {}, media, { + av = _.extend( {}, base, { action: 'parse-media-shortcode', initialize: function() { @@ -769,13 +821,13 @@ window.wp = window.wp || {}; if ( this.url ) { this.loader = false; - this.shortcode = wp.media.embed.shortcode( { + this.shortcode = media.embed.shortcode( { url: this.text } ); } wp.ajax.post( this.action, { - post_ID: postID, + post_ID: media.view.settings.post.id, type: this.shortcode.tag, shortcode: this.shortcode.string() } ) @@ -784,6 +836,7 @@ window.wp = window.wp || {}; } ) .fail( function( response ) { if ( self.url ) { + self.ignore = true; self.removeMarkers(); } else { self.setError( response.message || response.statusText, 'admin-media' ); @@ -816,8 +869,7 @@ window.wp = window.wp || {}; action: 'parse-embed', edit: function( text, update ) { - var media = wp.media.embed, - frame = media.edit( text, this.url ), + var frame = media.embed.edit( text, this.url ), self = this; this.pausePlayers(); @@ -834,7 +886,7 @@ window.wp = window.wp || {}; if ( self.url ) { update( data.url ); } else { - update( media.shortcode( data ).string() ); + update( media.embed.shortcode( data ).string() ); } } ); @@ -878,4 +930,4 @@ window.wp = window.wp || {}; } } } ) ); -} )( window, window.wp.mce.views, window.jQuery ); +} )( window, window.wp.mce.views, window.wp.media, window.jQuery );