diff --git src/wp-includes/js/mce-view.js src/wp-includes/js/mce-view.js
index d3af61e..587ee42 100644
|
|
window.wp = window.wp || {}; |
41 | 41 | doc = editor.getDoc(); |
42 | 42 | $( doc ).find( '[data-wpview-text="' + this.encodedText + '"]' ).each(function (i, elem) { |
43 | 43 | var node = $( elem ); |
44 | | node.html( html ); |
| 44 | // The <ins> is used to mark the end of the wrapper div. Needed when comparing |
| 45 | // the content as string for preventing extra undo levels. |
| 46 | node.html( html ).append( '<ins data-wpview-end="1"></ins>' ); |
45 | 47 | $( self ).trigger( 'ready', elem ); |
46 | 48 | }); |
47 | 49 | } |
48 | 50 | }, this ); |
49 | | } |
| 51 | }, |
| 52 | unbind: function() {} |
50 | 53 | } ); |
51 | 54 | |
52 | 55 | // take advantage of the Backbone extend method |
… |
… |
window.wp = window.wp || {}; |
93 | 96 | }, |
94 | 97 | |
95 | 98 | /** |
| 99 | * wp.mce.views.unbind( editor ) |
| 100 | * |
| 101 | * The editor DOM is being rebuilt. |
| 102 | * Fire an event for DOM cleanup for the passed TinyMCE instance. |
| 103 | */ |
| 104 | unbind: function() { |
| 105 | _.each( instances, function( instance ) { |
| 106 | instance.unbind(); |
| 107 | } ); |
| 108 | }, |
| 109 | |
| 110 | /** |
96 | 111 | * toViews( content ) |
97 | 112 | * Scans a `content` string for each view's pattern, replacing any |
98 | 113 | * matches with wrapper elements, and creates a new instance for |
… |
… |
window.wp = window.wp || {}; |
475 | 490 | wp.media[ this.shortcode.tag ].defaults |
476 | 491 | ); |
477 | 492 | return this.template({ model: attrs }); |
| 493 | }, |
| 494 | |
| 495 | unbind: function() { |
| 496 | this.unsetPlayer(); |
478 | 497 | } |
479 | 498 | }); |
480 | 499 | _.extend( wp.mce.media.View.prototype, wp.media.mixin ); |
diff --git src/wp-includes/js/media-audiovideo.js src/wp-includes/js/media-audiovideo.js
index 3f659da..9bdddb2 100644
|
|
|
914 | 914 | |
915 | 915 | $( init ); |
916 | 916 | |
917 | | }(jQuery, _, Backbone)); |
918 | | No newline at end of file |
| 917 | }(jQuery, _, Backbone)); |
diff --git src/wp-includes/js/tinymce/plugins/wpview/plugin.js src/wp-includes/js/tinymce/plugins/wpview/plugin.js
index 812341c..368f874 100644
|
|
tinymce.PluginManager.add( 'wpview', function( editor ) { |
80 | 80 | 'contenteditable': 'true' |
81 | 81 | }, getViewText( viewNode ) ); |
82 | 82 | |
83 | | viewNode.appendChild( clipboard ); |
| 83 | // Prepend inside the wrapper |
| 84 | viewNode.insertBefore( clipboard, viewNode.firstChild ); |
84 | 85 | |
85 | 86 | // Both of the following are necessary to prevent manipulating the selection/focus |
86 | | editor.dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop ); |
87 | | editor.dom.bind( selected, 'beforedeactivate focusin focusout', _stop ); |
| 87 | dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop ); |
| 88 | dom.bind( selected, 'beforedeactivate focusin focusout', _stop ); |
88 | 89 | |
89 | 90 | // Make sure that the editor is focused. |
90 | 91 | // It is possible that the editor is not focused when the mouse event fires |
… |
… |
tinymce.PluginManager.add( 'wpview', function( editor ) { |
140 | 141 | return; |
141 | 142 | } |
142 | 143 | |
| 144 | function emptyViews( content ) { |
| 145 | return content.replace(/(<div[^>]+wpview-wrap[^>]+>)[\s\S]+?data-wpview-end[^>]*><\/ins><\/div>/g, '$1</div>' ); |
| 146 | } |
| 147 | |
143 | 148 | editor.on( 'BeforeAddUndo', function( event ) { |
144 | | if ( selected && ! toRemove ) { |
| 149 | if ( event.lastLevel && emptyViews( event.level.content ) === emptyViews( event.lastLevel.content ) ) { |
145 | 150 | event.preventDefault(); |
146 | 151 | } |
147 | 152 | }); |
… |
… |
tinymce.PluginManager.add( 'wpview', function( editor ) { |
149 | 154 | // When the editor's content changes, scan the new content for |
150 | 155 | // matching view patterns, and transform the matches into |
151 | 156 | // view wrappers. |
152 | | editor.on( 'BeforeSetContent', function( e ) { |
153 | | if ( ! e.content ) { |
| 157 | editor.on( 'BeforeSetContent', function( event ) { |
| 158 | if ( ! event.content ) { |
154 | 159 | return; |
155 | 160 | } |
156 | 161 | |
157 | | e.content = wp.mce.views.toViews( e.content ); |
| 162 | if ( ! event.initial ) { |
| 163 | wp.mce.views.unbind( editor ); |
| 164 | } |
| 165 | |
| 166 | event.content = wp.mce.views.toViews( event.content ); |
158 | 167 | }); |
159 | 168 | |
160 | 169 | // When the editor's content has been updated and the DOM has been |
… |
… |
tinymce.PluginManager.add( 'wpview', function( editor ) { |
162 | 171 | editor.on( 'SetContent', function( event ) { |
163 | 172 | var body, padNode; |
164 | 173 | |
165 | | // don't (re-)render views if the format of the content is raw |
166 | | // to avoid adding additional undo levels on undo/redo |
167 | | if ( event.format !== 'raw' ) { |
168 | | wp.mce.views.render(); |
169 | | } |
| 174 | wp.mce.views.render(); |
170 | 175 | |
171 | 176 | // Add padding <p> if the noneditable node is last |
172 | 177 | if ( event.load || ! event.set ) { |