at path:ROOT / wp-includes / js / mce-view.js
run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
10.3 KB
2026-03-11 16:18:51
R W Run
3.41 KB
2026-03-11 16:18:51
R W Run
3.25 KB
2026-03-11 16:18:51
R W Run
1023 By
2026-03-11 16:18:51
R W Run
21.95 KB
2026-03-11 16:18:51
R W Run
5.67 KB
2026-03-11 16:18:51
R W Run
78.51 KB
2026-03-11 16:18:51
R W Run
23.73 KB
2026-03-11 16:18:51
R W Run
26.18 KB
2026-03-11 16:18:51
R W Run
8.8 KB
2026-03-11 16:18:51
R W Run
28.4 KB
2026-03-11 16:18:51
R W Run
16.11 KB
2026-03-11 16:18:51
R W Run
12.22 KB
2026-03-11 16:18:51
R W Run
2.96 KB
2026-03-11 16:18:51
R W Run
25.22 KB
2026-03-11 16:18:51
R W Run
7.67 KB
2026-03-11 16:18:51
R W Run
7.72 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:51
R W Run
6.66 KB
2026-03-11 16:18:51
R W Run
3.59 KB
2026-03-11 16:18:51
R W Run
14.67 KB
2026-03-11 16:18:51
R W Run
4.92 KB
2026-03-11 16:18:51
R W Run
22.71 KB
2026-03-11 16:18:51
R W Run
7.64 KB
2026-03-11 16:18:51
R W Run
27.93 KB
2026-03-11 16:18:51
R W Run
10.75 KB
2026-03-11 16:18:51
R W Run
32.55 KB
2026-03-11 16:18:51
R W Run
10.44 KB
2026-03-11 16:18:51
R W Run
5.1 KB
2026-03-11 16:18:51
R W Run
2.51 KB
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
5.81 KB
2026-03-11 16:18:51
R W Run
7.06 KB
2026-03-11 16:18:51
R W Run
1.46 KB
2026-03-11 16:18:51
R W Run
1.68 KB
2026-03-11 16:18:51
R W Run
5.39 KB
2026-03-11 16:18:51
R W Run
31 By
2026-03-11 16:18:51
R W Run
35 By
2026-03-11 16:18:51
R W Run
23.57 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:51
R W Run
9.54 KB
2026-03-11 16:18:51
R W Run
24.24 KB
2026-03-11 16:18:51
R W Run
11.77 KB
2026-03-11 16:18:51
R W Run
28.44 KB
2026-03-11 16:18:51
R W Run
10.63 KB
2026-03-11 16:18:51
R W Run
26.15 KB
2026-03-11 16:18:51
R W Run
12.98 KB
2026-03-11 16:18:51
R W Run
42.58 KB
2026-03-11 16:18:51
R W Run
12.97 KB
2026-03-11 16:18:51
R W Run
266.99 KB
2026-03-11 16:18:51
R W Run
108.18 KB
2026-03-11 16:18:51
R W Run
22.07 KB
2026-03-11 16:18:51
R W Run
10.87 KB
2026-03-11 16:18:51
R W Run
10.51 KB
2026-03-11 16:18:51
R W Run
2.58 KB
2026-03-11 16:18:51
R W Run
0 By
2026-03-11 16:18:51
R W Run
35 By
2026-03-11 16:18:51
R W Run
4.85 KB
2026-03-11 16:18:51
R W Run
3.21 KB
2026-03-11 16:18:51
R W Run
36.32 KB
2026-03-11 16:18:51
R W Run
19.39 KB
2026-03-11 16:18:51
R W Run
67.12 KB
2026-03-11 16:18:51
R W Run
18.46 KB
2026-03-11 16:18:51
R W Run
4.56 KB
2026-03-11 16:18:51
R W Run
1.82 KB
2026-03-11 16:18:51
R W Run
3.81 KB
2026-03-11 16:18:51
R W Run
2.51 KB
2026-03-11 16:18:51
R W Run
45.88 KB
2026-03-11 16:18:51
R W Run
14.34 KB
2026-03-11 16:18:51
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
1.62 KB
2026-03-11 16:18:51
R W Run
14.88 KB
2026-03-11 16:18:51
R W Run
2.97 KB
2026-03-11 16:18:51
R W Run
10.22 KB
2026-03-11 16:18:51
R W Run
4.34 KB
2026-03-11 16:18:51
R W Run
6.62 KB
2026-03-11 16:18:51
R W Run
3.1 KB
2026-03-11 16:18:51
R W Run
3.14 KB
2026-03-11 16:18:51
R W Run
1.22 KB
2026-03-11 16:18:51
R W Run
12.89 KB
2026-03-11 16:18:51
R W Run
2.82 KB
2026-03-11 16:18:51
R W Run
22.23 KB
2026-03-11 16:18:51
R W Run
8.59 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:51
R W Run
970 By
2026-03-11 16:18:51
R W Run
597 By
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
7.34 KB
2026-03-11 16:18:51
R W Run
9.99 KB
2026-03-11 16:18:51
R W Run
3.54 KB
2026-03-11 16:18:51
R W Run
1.3 KB
2026-03-11 16:18:51
R W Run
444 By
2026-03-11 16:18:51
R W Run
4.58 KB
2026-03-11 16:18:51
R W Run
1.4 KB
2026-03-11 16:18:51
R W Run
569 By
2026-03-11 16:18:51
R W Run
281 By
2026-03-11 16:18:51
R W Run
20.74 KB
2026-03-11 16:18:51
R W Run
11.05 KB
2026-03-11 16:18:51
R W Run
821 By
2026-03-11 16:18:51
R W Run
351 By
2026-03-11 16:18:51
R W Run
802.97 KB
2026-03-11 16:18:51
R W Run
error_log
📄mce-view.js
1/**
2 * @output wp-includes/js/mce-view.js
3 */
4
5/* global tinymce */
6
7/*
8 * The TinyMCE view API.
9 *
10 * Note: this API is "experimental" meaning that it will probably change
11 * in the next few releases based on feedback from 3.9.0.
12 * If you decide to use it, please follow the development closely.
13 *
14 * Diagram
15 *
16 * |- registered view constructor (type)
17 * | |- view instance (unique text)
18 * | | |- editor 1
19 * | | | |- view node
20 * | | | |- view node
21 * | | | |- ...
22 * | | |- editor 2
23 * | | | |- ...
24 * | |- view instance
25 * | | |- ...
26 * |- registered view
27 * | |- ...
28 */
29( function( window, wp, shortcode, $ ) {
30 'use strict';
31
32 var views = {},
33 instances = {};
34
35 wp.mce = wp.mce || {};
36
37 /**
38 * wp.mce.views
39 *
40 * A set of utilities that simplifies adding custom UI within a TinyMCE editor.
41 * At its core, it serves as a series of converters, transforming text to a
42 * custom UI, and back again.
43 */
44 wp.mce.views = {
45
46 /**
47 * Registers a new view type.
48 *
49 * @param {string} type The view type.
50 * @param {Object} extend An object to extend wp.mce.View.prototype with.
51 */
52 register: function( type, extend ) {
53 views[ type ] = wp.mce.View.extend( _.extend( extend, { type: type } ) );
54 },
55
56 /**
57 * Unregisters a view type.
58 *
59 * @param {string} type The view type.
60 */
61 unregister: function( type ) {
62 delete views[ type ];
63 },
64
65 /**
66 * Returns the settings of a view type.
67 *
68 * @param {string} type The view type.
69 *
70 * @return {Function} The view constructor.
71 */
72 get: function( type ) {
73 return views[ type ];
74 },
75
76 /**
77 * Unbinds all view nodes.
78 * Runs before removing all view nodes from the DOM.
79 */
80 unbind: function() {
81 _.each( instances, function( instance ) {
82 instance.unbind();
83 } );
84 },
85
86 /**
87 * Scans a given string for each view's pattern,
88 * replacing any matches with markers,
89 * and creates a new instance for every match.
90 *
91 * @param {string} content The string to scan.
92 * @param {tinymce.Editor} editor The editor.
93 *
94 * @return {string} The string with markers.
95 */
96 setMarkers: function( content, editor ) {
97 var pieces = [ { content: content } ],
98 self = this,
99 instance, current;
100
101 _.each( views, function( view, type ) {
102 current = pieces.slice();
103 pieces = [];
104
105 _.each( current, function( piece ) {
106 var remaining = piece.content,
107 result, text;
108
109 // Ignore processed pieces, but retain their location.
110 if ( piece.processed ) {
111 pieces.push( piece );
112 return;
113 }
114
115 // Iterate through the string progressively matching views
116 // and slicing the string as we go.
117 while ( remaining && ( result = view.prototype.match( remaining ) ) ) {
118 // Any text before the match becomes an unprocessed piece.
119 if ( result.index ) {
120 pieces.push( { content: remaining.substring( 0, result.index ) } );
121 }
122
123 result.options.editor = editor;
124 instance = self.createInstance( type, result.content, result.options );
125 text = instance.loader ? '.' : instance.text;
126
127 // Add the processed piece for the match.
128 pieces.push( {
129 content: instance.ignore ? text : '<p data-wpview-marker="' + instance.encodedText + '">' + text + '</p>',
130 processed: true
131 } );
132
133 // Update the remaining content.
134 remaining = remaining.slice( result.index + result.content.length );
135 }
136
137 // There are no additional matches.
138 // If any content remains, add it as an unprocessed piece.
139 if ( remaining ) {
140 pieces.push( { content: remaining } );
141 }
142 } );
143 } );
144
145 content = _.pluck( pieces, 'content' ).join( '' );
146 return content.replace( /<p>\s*<p data-wpview-marker=/g, '<p data-wpview-marker=' ).replace( /<\/p>\s*<\/p>/g, '</p>' );
147 },
148
149 /**
150 * Create a view instance.
151 *
152 * @param {string} type The view type.
153 * @param {string} text The textual representation of the view.
154 * @param {Object} options Options.
155 * @param {boolean} force Recreate the instance. Optional.
156 *
157 * @return {wp.mce.View} The view instance.
158 */
159 createInstance: function( type, text, options, force ) {
160 var View = this.get( type ),
161 encodedText,
162 instance;
163
164 if ( text.indexOf( '[' ) !== -1 && text.indexOf( ']' ) !== -1 ) {
165 // Looks like a shortcode? Remove any line breaks from inside of shortcodes
166 // or autop will replace them with <p> and <br> later and the string won't match.
167 text = text.replace( /\[[^\]]+\]/g, function( match ) {
168 return match.replace( /[\r\n]/g, '' );
169 });
170 }
171
172 if ( ! force ) {
173 instance = this.getInstance( text );
174
175 if ( instance ) {
176 return instance;
177 }
178 }
179
180 encodedText = encodeURIComponent( text );
181
182 options = _.extend( options || {}, {
183 text: text,
184 encodedText: encodedText
185 } );
186
187 return instances[ encodedText ] = new View( options );
188 },
189
190 /**
191 * Get a view instance.
192 *
193 * @param {(string|HTMLElement)} object The textual representation of the view or the view node.
194 *
195 * @return {wp.mce.View} The view instance or undefined.
196 */
197 getInstance: function( object ) {
198 if ( typeof object === 'string' ) {
199 return instances[ encodeURIComponent( object ) ];
200 }
201
202 return instances[ $( object ).attr( 'data-wpview-text' ) ];
203 },
204
205 /**
206 * Given a view node, get the view's text.
207 *
208 * @param {HTMLElement} node The view node.
209 *
210 * @return {string} The textual representation of the view.
211 */
212 getText: function( node ) {
213 return decodeURIComponent( $( node ).attr( 'data-wpview-text' ) || '' );
214 },
215
216 /**
217 * Renders all view nodes that are not yet rendered.
218 *
219 * @param {boolean} force Rerender all view nodes.
220 */
221 render: function( force ) {
222 _.each( instances, function( instance ) {
223 instance.render( null, force );
224 } );
225 },
226
227 /**
228 * Update the text of a given view node.
229 *
230 * @param {string} text The new text.
231 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
232 * @param {HTMLElement} node The view node to update.
233 * @param {boolean} force Recreate the instance. Optional.
234 */
235 update: function( text, editor, node, force ) {
236 var instance = this.getInstance( node );
237
238 if ( instance ) {
239 instance.update( text, editor, node, force );
240 }
241 },
242
243 /**
244 * Renders any editing interface based on the view type.
245 *
246 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
247 * @param {HTMLElement} node The view node to edit.
248 */
249 edit: function( editor, node ) {
250 var instance = this.getInstance( node );
251
252 if ( instance && instance.edit ) {
253 instance.edit( instance.text, function( text, force ) {
254 instance.update( text, editor, node, force );
255 } );
256 }
257 },
258
259 /**
260 * Remove a given view node from the DOM.
261 *
262 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
263 * @param {HTMLElement} node The view node to remove.
264 */
265 remove: function( editor, node ) {
266 var instance = this.getInstance( node );
267
268 if ( instance ) {
269 instance.remove( editor, node );
270 }
271 }
272 };
273
274 /**
275 * A Backbone-like View constructor intended for use when rendering a TinyMCE View.
276 * The main difference is that the TinyMCE View is not tied to a particular DOM node.
277 *
278 * @param {Object} options Options.
279 */
280 wp.mce.View = function( options ) {
281 _.extend( this, options );
282 this.initialize();
283 };
284
285 wp.mce.View.extend = Backbone.View.extend;
286
287 _.extend( wp.mce.View.prototype, /** @lends wp.mce.View.prototype */{
288
289 /**
290 * The content.
291 *
292 * @type {*}
293 */
294 content: null,
295
296 /**
297 * Whether or not to display a loader.
298 *
299 * @type {Boolean}
300 */
301 loader: true,
302
303 /**
304 * Runs after the view instance is created.
305 */
306 initialize: function() {},
307
308 /**
309 * Returns the content to render in the view node.
310 *
311 * @return {*}
312 */
313 getContent: function() {
314 return this.content;
315 },
316
317 /**
318 * Renders all view nodes tied to this view instance that are not yet rendered.
319 *
320 * @param {string} content The content to render. Optional.
321 * @param {boolean} force Rerender all view nodes tied to this view instance. Optional.
322 */
323 render: function( content, force ) {
324 if ( content != null ) {
325 this.content = content;
326 }
327
328 content = this.getContent();
329
330 // If there's nothing to render an no loader needs to be shown, stop.
331 if ( ! this.loader && ! content ) {
332 return;
333 }
334
335 // We're about to rerender all views of this instance, so unbind rendered views.
336 force && this.unbind();
337
338 // Replace any left over markers.
339 this.replaceMarkers();
340
341 if ( content ) {
342 this.setContent( content, function( editor, node ) {
343 $( node ).data( 'rendered', true );
344 this.bindNode.call( this, editor, node );
345 }, force ? null : false );
346 } else {
347 this.setLoader();
348 }
349 },
350
351 /**
352 * Binds a given node after its content is added to the DOM.
353 */
354 bindNode: function() {},
355
356 /**
357 * Unbinds a given node before its content is removed from the DOM.
358 */
359 unbindNode: function() {},
360
361 /**
362 * Unbinds all view nodes tied to this view instance.
363 * Runs before their content is removed from the DOM.
364 */
365 unbind: function() {
366 this.getNodes( function( editor, node ) {
367 this.unbindNode.call( this, editor, node );
368 }, true );
369 },
370
371 /**
372 * Gets all the TinyMCE editor instances that support views.
373 *
374 * @param {Function} callback A callback.
375 */
376 getEditors: function( callback ) {
377 _.each( tinymce.editors, function( editor ) {
378 if ( editor.plugins.wpview ) {
379 callback.call( this, editor );
380 }
381 }, this );
382 },
383
384 /**
385 * Gets all view nodes tied to this view instance.
386 *
387 * @param {Function} callback A callback.
388 * @param {boolean} rendered Get (un)rendered view nodes. Optional.
389 */
390 getNodes: function( callback, rendered ) {
391 this.getEditors( function( editor ) {
392 var self = this;
393
394 $( editor.getBody() )
395 .find( '[data-wpview-text="' + self.encodedText + '"]' )
396 .filter( function() {
397 var data;
398
399 if ( rendered == null ) {
400 return true;
401 }
402
403 data = $( this ).data( 'rendered' ) === true;
404
405 return rendered ? data : ! data;
406 } )
407 .each( function() {
408 callback.call( self, editor, this, this /* back compat */ );
409 } );
410 } );
411 },
412
413 /**
414 * Gets all marker nodes tied to this view instance.
415 *
416 * @param {Function} callback A callback.
417 */
418 getMarkers: function( callback ) {
419 this.getEditors( function( editor ) {
420 var self = this;
421
422 $( editor.getBody() )
423 .find( '[data-wpview-marker="' + this.encodedText + '"]' )
424 .each( function() {
425 callback.call( self, editor, this );
426 } );
427 } );
428 },
429
430 /**
431 * Replaces all marker nodes tied to this view instance.
432 */
433 replaceMarkers: function() {
434 this.getMarkers( function( editor, node ) {
435 var selected = node === editor.selection.getNode();
436 var $viewNode;
437
438 if ( ! this.loader && $( node ).text() !== tinymce.DOM.decode( this.text ) ) {
439 editor.dom.setAttrib( node, 'data-wpview-marker', null );
440 return;
441 }
442
443 $viewNode = editor.$(
444 '<div class="wpview wpview-wrap" data-wpview-text="' + this.encodedText + '" data-wpview-type="' + this.type + '" contenteditable="false"></div>'
445 );
446
447 editor.undoManager.ignore( function() {
448 editor.$( node ).replaceWith( $viewNode );
449 } );
450
451 if ( selected ) {
452 setTimeout( function() {
453 editor.undoManager.ignore( function() {
454 editor.selection.select( $viewNode[0] );
455 editor.selection.collapse();
456 } );
457 } );
458 }
459 } );
460 },
461
462 /**
463 * Removes all marker nodes tied to this view instance.
464 */
465 removeMarkers: function() {
466 this.getMarkers( function( editor, node ) {
467 editor.dom.setAttrib( node, 'data-wpview-marker', null );
468 } );
469 },
470
471 /**
472 * Sets the content for all view nodes tied to this view instance.
473 *
474 * @param {*} content The content to set.
475 * @param {Function} callback A callback. Optional.
476 * @param {boolean} rendered Only set for (un)rendered nodes. Optional.
477 */
478 setContent: function( content, callback, rendered ) {
479 if ( _.isObject( content ) && ( content.sandbox || content.head || content.body.indexOf( '<script' ) !== -1 ) ) {
480 this.setIframes( content.head || '', content.body, callback, rendered );
481 } else if ( _.isString( content ) && content.indexOf( '<script' ) !== -1 ) {
482 this.setIframes( '', content, callback, rendered );
483 } else {
484 this.getNodes( function( editor, node ) {
485 content = content.body || content;
486
487 if ( content.indexOf( '<iframe' ) !== -1 ) {
488 content += '<span class="mce-shim"></span>';
489 }
490
491 editor.undoManager.transact( function() {
492 node.innerHTML = '';
493 node.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
494 editor.dom.add( node, 'span', { 'class': 'wpview-end' } );
495 } );
496
497 callback && callback.call( this, editor, node );
498 }, rendered );
499 }
500 },
501
502 /**
503 * Sets the content in an iframe for all view nodes tied to this view instance.
504 *
505 * @param {string} head HTML string to be added to the head of the document.
506 * @param {string} body HTML string to be added to the body of the document.
507 * @param {Function} callback A callback. Optional.
508 * @param {boolean} rendered Only set for (un)rendered nodes. Optional.
509 */
510 setIframes: function( head, body, callback, rendered ) {
511 var self = this;
512
513 if ( body.indexOf( '[' ) !== -1 && body.indexOf( ']' ) !== -1 ) {
514 var shortcodesRegExp = new RegExp( '\\[\\/?(?:' + window.mceViewL10n.shortcodes.join( '|' ) + ')[^\\]]*?\\]', 'g' );
515 // Escape tags inside shortcode previews.
516 body = body.replace( shortcodesRegExp, function( match ) {
517 return match.replace( /</g, '&lt;' ).replace( />/g, '&gt;' );
518 } );
519 }
520
521 this.getNodes( function( editor, node ) {
522 var dom = editor.dom,
523 styles = '',
524 bodyClasses = editor.getBody().className || '',
525 editorHead = editor.getDoc().getElementsByTagName( 'head' )[0],
526 iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block;
527
528 tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) {
529 if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
530 link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {
531
532 styles += dom.getOuterHTML( link );
533 }
534 } );
535
536 if ( self.iframeHeight ) {
537 dom.add( node, 'span', {
538 'data-mce-bogus': 1,
539 style: {
540 display: 'block',
541 width: '100%',
542 height: self.iframeHeight
543 }
544 }, '\u200B' );
545 }
546
547 editor.undoManager.transact( function() {
548 node.innerHTML = '';
549
550 iframe = dom.add( node, 'iframe', {
551 /* jshint scripturl: true */
552 src: tinymce.Env.ie ? 'javascript:""' : '',
553 frameBorder: '0',
554 allowTransparency: 'true',
555 scrolling: 'no',
556 'class': 'wpview-sandbox',
557 style: {
558 width: '100%',
559 display: 'block'
560 },
561 height: self.iframeHeight
562 } );
563
564 dom.add( node, 'span', { 'class': 'mce-shim' } );
565 dom.add( node, 'span', { 'class': 'wpview-end' } );
566 } );
567
568 /*
569 * Bail if the iframe node is not attached to the DOM.
570 * Happens when the view is dragged in the editor.
571 * There is a browser restriction when iframes are moved in the DOM. They get emptied.
572 * The iframe will be rerendered after dropping the view node at the new location.
573 */
574 if ( ! iframe.contentWindow ) {
575 return;
576 }
577
578 iframeWin = iframe.contentWindow;
579 iframeDoc = iframeWin.document;
580 iframeDoc.open();
581
582 iframeDoc.write(
583 '<!DOCTYPE html>' +
584 '<html>' +
585 '<head>' +
586 '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' +
587 head +
588 styles +
589 '<style>' +
590 'html {' +
591 'background: transparent;' +
592 'padding: 0;' +
593 'margin: 0;' +
594 '}' +
595 'body#wpview-iframe-sandbox {' +
596 'background: transparent;' +
597 'padding: 1px 0 !important;' +
598 'margin: -1px 0 0 !important;' +
599 '}' +
600 'body#wpview-iframe-sandbox:before,' +
601 'body#wpview-iframe-sandbox:after {' +
602 'display: none;' +
603 'content: "";' +
604 '}' +
605 'iframe {' +
606 'max-width: 100%;' +
607 '}' +
608 '</style>' +
609 '</head>' +
610 '<body id="wpview-iframe-sandbox" class="' + bodyClasses + '">' +
611 body +
612 '</body>' +
613 '</html>'
614 );
615
616 iframeDoc.close();
617
618 function resize() {
619 var $iframe;
620
621 if ( block ) {
622 return;
623 }
624
625 // Make sure the iframe still exists.
626 if ( iframe.contentWindow ) {
627 $iframe = $( iframe );
628 self.iframeHeight = $( iframeDoc.body ).height();
629
630 if ( $iframe.height() !== self.iframeHeight ) {
631 $iframe.height( self.iframeHeight );
632 editor.nodeChanged();
633 }
634 }
635 }
636
637 if ( self.iframeHeight ) {
638 block = true;
639
640 setTimeout( function() {
641 block = false;
642 resize();
643 }, 3000 );
644 }
645
646 function addObserver() {
647 observer = new MutationObserver( _.debounce( resize, 100 ) );
648
649 observer.observe( iframeDoc.body, {
650 attributes: true,
651 childList: true,
652 subtree: true
653 } );
654 }
655
656 $( iframeWin ).on( 'load', resize );
657
658 MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver;
659
660 if ( MutationObserver ) {
661 if ( ! iframeDoc.body ) {
662 iframeDoc.addEventListener( 'DOMContentLoaded', addObserver, false );
663 } else {
664 addObserver();
665 }
666 } else {
667 for ( i = 1; i < 6; i++ ) {
668 setTimeout( resize, i * 700 );
669 }
670 }
671
672 callback && callback.call( self, editor, node );
673 }, rendered );
674 },
675
676 /**
677 * Sets a loader for all view nodes tied to this view instance.
678 */
679 setLoader: function( dashicon ) {
680 this.setContent(
681 '<div class="loading-placeholder">' +
682 '<div class="dashicons dashicons-' + ( dashicon || 'admin-media' ) + '"></div>' +
683 '<div class="wpview-loading"><ins></ins></div>' +
684 '</div>'
685 );
686 },
687
688 /**
689 * Sets an error for all view nodes tied to this view instance.
690 *
691 * @param {string} message The error message to set.
692 * @param {string} dashicon A dashicon ID. Optional. {@link https://developer.wordpress.org/resource/dashicons/}
693 */
694 setError: function( message, dashicon ) {
695 this.setContent(
696 '<div class="wpview-error">' +
697 '<div class="dashicons dashicons-' + ( dashicon || 'no' ) + '"></div>' +
698 '<p>' + message + '</p>' +
699 '</div>'
700 );
701 },
702
703 /**
704 * Tries to find a text match in a given string.
705 *
706 * @param {string} content The string to scan.
707 *
708 * @return {Object}
709 */
710 match: function( content ) {
711 var match = shortcode.next( this.type, content );
712
713 if ( match ) {
714 return {
715 index: match.index,
716 content: match.content,
717 options: {
718 shortcode: match.shortcode
719 }
720 };
721 }
722 },
723
724 /**
725 * Update the text of a given view node.
726 *
727 * @param {string} text The new text.
728 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
729 * @param {HTMLElement} node The view node to update.
730 * @param {boolean} force Recreate the instance. Optional.
731 */
732 update: function( text, editor, node, force ) {
733 _.find( views, function( view, type ) {
734 var match = view.prototype.match( text );
735
736 if ( match ) {
737 $( node ).data( 'rendered', false );
738 editor.dom.setAttrib( node, 'data-wpview-text', encodeURIComponent( text ) );
739 wp.mce.views.createInstance( type, text, match.options, force ).render();
740
741 editor.selection.select( node );
742 editor.nodeChanged();
743 editor.focus();
744
745 return true;
746 }
747 } );
748 },
749
750 /**
751 * Remove a given view node from the DOM.
752 *
753 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
754 * @param {HTMLElement} node The view node to remove.
755 */
756 remove: function( editor, node ) {
757 this.unbindNode.call( this, editor, node );
758 editor.dom.remove( node );
759 editor.focus();
760 }
761 } );
762} )( window, window.wp, window.wp.shortcode, window.jQuery );
763
764/*
765 * The WordPress core TinyMCE views.
766 * Views for the gallery, audio, video, playlist and embed shortcodes,
767 * and a view for embeddable URLs.
768 */
769( function( window, views, media, $ ) {
770 var base, gallery, av, embed,
771 schema, parser, serializer;
772
773 function verifyHTML( string ) {
774 var settings = {};
775
776 if ( ! window.tinymce ) {
777 return string.replace( /<[^>]+>/g, '' );
778 }
779
780 if ( ! string || ( string.indexOf( '<' ) === -1 && string.indexOf( '>' ) === -1 ) ) {
781 return string;
782 }
783
784 schema = schema || new window.tinymce.html.Schema( settings );
785 parser = parser || new window.tinymce.html.DomParser( settings, schema );
786 serializer = serializer || new window.tinymce.html.Serializer( settings, schema );
787
788 return serializer.serialize( parser.parse( string, { forced_root_block: false } ) );
789 }
790
791 base = {
792 state: [],
793
794 edit: function( text, update ) {
795 var type = this.type,
796 frame = media[ type ].edit( text );
797
798 this.pausePlayers && this.pausePlayers();
799
800 _.each( this.state, function( state ) {
801 frame.state( state ).on( 'update', function( selection ) {
802 update( media[ type ].shortcode( selection ).string(), type === 'gallery' );
803 } );
804 } );
805
806 frame.on( 'close', function() {
807 frame.detach();
808 } );
809
810 frame.open();
811 }
812 };
813
814 gallery = _.extend( {}, base, {
815 state: [ 'gallery-edit' ],
816 template: media.template( 'editor-gallery' ),
817
818 initialize: function() {
819 var attachments = media.gallery.attachments( this.shortcode, media.view.settings.post.id ),
820 attrs = this.shortcode.attrs.named,
821 self = this;
822
823 attachments.more()
824 .done( function() {
825 attachments = attachments.toJSON();
826
827 _.each( attachments, function( attachment ) {
828 if ( attachment.sizes ) {
829 if ( attrs.size && attachment.sizes[ attrs.size ] ) {
830 attachment.thumbnail = attachment.sizes[ attrs.size ];
831 } else if ( attachment.sizes.thumbnail ) {
832 attachment.thumbnail = attachment.sizes.thumbnail;
833 } else if ( attachment.sizes.full ) {
834 attachment.thumbnail = attachment.sizes.full;
835 }
836 }
837 } );
838
839 self.render( self.template( {
840 verifyHTML: verifyHTML,
841 attachments: attachments,
842 columns: attrs.columns ? parseInt( attrs.columns, 10 ) : media.galleryDefaults.columns
843 } ) );
844 } )
845 .fail( function( jqXHR, textStatus ) {
846 self.setError( textStatus );
847 } );
848 }
849 } );
850
851 av = _.extend( {}, base, {
852 action: 'parse-media-shortcode',
853
854 initialize: function() {
855 var self = this, maxwidth = null;
856
857 if ( this.url ) {
858 this.loader = false;
859 this.shortcode = media.embed.shortcode( {
860 url: this.text
861 } );
862 }
863
864 // Obtain the target width for the embed.
865 if ( self.editor ) {
866 maxwidth = self.editor.getBody().clientWidth;
867 }
868
869 wp.ajax.post( this.action, {
870 post_ID: media.view.settings.post.id,
871 type: this.shortcode.tag,
872 shortcode: this.shortcode.string(),
873 maxwidth: maxwidth
874 } )
875 .done( function( response ) {
876 self.render( response );
877 } )
878 .fail( function( response ) {
879 if ( self.url ) {
880 self.ignore = true;
881 self.removeMarkers();
882 } else {
883 self.setError( response.message || response.statusText, 'admin-media' );
884 }
885 } );
886
887 this.getEditors( function( editor ) {
888 editor.on( 'wpview-selected', function() {
889 self.pausePlayers();
890 } );
891 } );
892 },
893
894 pausePlayers: function() {
895 this.getNodes( function( editor, node, content ) {
896 var win = $( 'iframe.wpview-sandbox', content ).get( 0 );
897
898 if ( win && ( win = win.contentWindow ) && win.mejs ) {
899 _.each( win.mejs.players, function( player ) {
900 try {
901 player.pause();
902 } catch ( e ) {}
903 } );
904 }
905 } );
906 }
907 } );
908
909 embed = _.extend( {}, av, {
910 action: 'parse-embed',
911
912 edit: function( text, update ) {
913 var frame = media.embed.edit( text, this.url ),
914 self = this;
915
916 this.pausePlayers();
917
918 frame.state( 'embed' ).props.on( 'change:url', function( model, url ) {
919 if ( url && model.get( 'url' ) ) {
920 frame.state( 'embed' ).metadata = model.toJSON();
921 }
922 } );
923
924 frame.state( 'embed' ).on( 'select', function() {
925 var data = frame.state( 'embed' ).metadata;
926
927 if ( self.url ) {
928 update( data.url );
929 } else {
930 update( media.embed.shortcode( data ).string() );
931 }
932 } );
933
934 frame.on( 'close', function() {
935 frame.detach();
936 } );
937
938 frame.open();
939 }
940 } );
941
942 views.register( 'gallery', _.extend( {}, gallery ) );
943
944 views.register( 'audio', _.extend( {}, av, {
945 state: [ 'audio-details' ]
946 } ) );
947
948 views.register( 'video', _.extend( {}, av, {
949 state: [ 'video-details' ]
950 } ) );
951
952 views.register( 'playlist', _.extend( {}, av, {
953 state: [ 'playlist-edit', 'video-playlist-edit' ]
954 } ) );
955
956 views.register( 'embed', _.extend( {}, embed ) );
957
958 views.register( 'embedURL', _.extend( {}, embed, {
959 match: function( content ) {
960 // There may be a "bookmark" node next to the URL...
961 var re = /(^|<p>(?:<span data-mce-type="bookmark"[^>]+>\s*<\/span>)?)(https?:\/\/[^\s"]+?)((?:<span data-mce-type="bookmark"[^>]+>\s*<\/span>)?<\/p>\s*|$)/gi;
962 var match = re.exec( content );
963
964 if ( match ) {
965 return {
966 index: match.index + match[1].length,
967 content: match[2],
968 options: {
969 url: true
970 }
971 };
972 }
973 }
974 } ) );
975} )( window, window.wp.mce.views, window.wp.media, window.jQuery );
976
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1