run:R W Run
15.41 KB
2026-03-11 16:18:51
R W Run
5.45 KB
2026-03-11 16:18:51
R W Run
4.18 KB
2026-03-11 16:18:51
R W Run
1.41 KB
2026-03-11 16:18:51
R W Run
10.11 KB
2026-03-11 16:18:51
R W Run
3.68 KB
2026-03-11 16:18:51
R W Run
5.34 KB
2026-03-11 16:18:51
R W Run
1.98 KB
2026-03-11 16:18:51
R W Run
6.86 KB
2026-03-11 16:18:51
R W Run
2.64 KB
2026-03-11 16:18:51
R W Run
41.86 KB
2026-03-11 16:18:51
R W Run
13.91 KB
2026-03-11 16:18:51
R W Run
17.63 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
error_log
📄text-widgets.js
1/**
2 * @output wp-admin/js/widgets/text-widgets.js
3 */
4
5/* global tinymce, switchEditors */
6/* eslint consistent-this: [ "error", "control" ] */
7
8/**
9 * @namespace wp.textWidgets
10 */
11wp.textWidgets = ( function( $ ) {
12 'use strict';
13
14 var component = {
15 dismissedPointers: [],
16 idBases: [ 'text' ]
17 };
18
19 component.TextWidgetControl = Backbone.View.extend(/** @lends wp.textWidgets.TextWidgetControl.prototype */{
20
21 /**
22 * View events.
23 *
24 * @type {Object}
25 */
26 events: {},
27
28 /**
29 * Text widget control.
30 *
31 * @constructs wp.textWidgets.TextWidgetControl
32 * @augments Backbone.View
33 * @abstract
34 *
35 * @param {Object} options - Options.
36 * @param {jQuery} options.el - Control field container element.
37 * @param {jQuery} options.syncContainer - Container element where fields are synced for the server.
38 *
39 * @return {void}
40 */
41 initialize: function initialize( options ) {
42 var control = this;
43
44 if ( ! options.el ) {
45 throw new Error( 'Missing options.el' );
46 }
47 if ( ! options.syncContainer ) {
48 throw new Error( 'Missing options.syncContainer' );
49 }
50
51 Backbone.View.prototype.initialize.call( control, options );
52 control.syncContainer = options.syncContainer;
53
54 control.$el.addClass( 'text-widget-fields' );
55 control.$el.html( wp.template( 'widget-text-control-fields' ) );
56
57 control.customHtmlWidgetPointer = control.$el.find( '.wp-pointer.custom-html-widget-pointer' );
58 if ( control.customHtmlWidgetPointer.length ) {
59 control.customHtmlWidgetPointer.find( '.close' ).on( 'click', function( event ) {
60 event.preventDefault();
61 control.customHtmlWidgetPointer.hide();
62 $( '#' + control.fields.text.attr( 'id' ) + '-html' ).trigger( 'focus' );
63 control.dismissPointers( [ 'text_widget_custom_html' ] );
64 });
65 control.customHtmlWidgetPointer.find( '.add-widget' ).on( 'click', function( event ) {
66 event.preventDefault();
67 control.customHtmlWidgetPointer.hide();
68 control.openAvailableWidgetsPanel();
69 });
70 }
71
72 control.pasteHtmlPointer = control.$el.find( '.wp-pointer.paste-html-pointer' );
73 if ( control.pasteHtmlPointer.length ) {
74 control.pasteHtmlPointer.find( '.close' ).on( 'click', function( event ) {
75 event.preventDefault();
76 control.pasteHtmlPointer.hide();
77 control.editor.focus();
78 control.dismissPointers( [ 'text_widget_custom_html', 'text_widget_paste_html' ] );
79 });
80 }
81
82 control.fields = {
83 title: control.$el.find( '.title' ),
84 text: control.$el.find( '.text' )
85 };
86
87 // Sync input fields to hidden sync fields which actually get sent to the server.
88 _.each( control.fields, function( fieldInput, fieldName ) {
89 fieldInput.on( 'input change', function updateSyncField() {
90 var syncInput = control.syncContainer.find( '.sync-input.' + fieldName );
91 if ( syncInput.val() !== fieldInput.val() ) {
92 syncInput.val( fieldInput.val() );
93 syncInput.trigger( 'change' );
94 }
95 });
96
97 // Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event.
98 fieldInput.val( control.syncContainer.find( '.sync-input.' + fieldName ).val() );
99 });
100 },
101
102 /**
103 * Dismiss pointers for Custom HTML widget.
104 *
105 * @since 4.8.1
106 *
107 * @param {Array} pointers Pointer IDs to dismiss.
108 * @return {void}
109 */
110 dismissPointers: function dismissPointers( pointers ) {
111 _.each( pointers, function( pointer ) {
112 wp.ajax.post( 'dismiss-wp-pointer', {
113 pointer: pointer
114 });
115 component.dismissedPointers.push( pointer );
116 });
117 },
118
119 /**
120 * Open available widgets panel.
121 *
122 * @since 4.8.1
123 * @return {void}
124 */
125 openAvailableWidgetsPanel: function openAvailableWidgetsPanel() {
126 var sidebarControl;
127 wp.customize.section.each( function( section ) {
128 if ( section.extended( wp.customize.Widgets.SidebarSection ) && section.expanded() ) {
129 sidebarControl = wp.customize.control( 'sidebars_widgets[' + section.params.sidebarId + ']' );
130 }
131 });
132 if ( ! sidebarControl ) {
133 return;
134 }
135 setTimeout( function() { // Timeout to prevent click event from causing panel to immediately collapse.
136 wp.customize.Widgets.availableWidgetsPanel.open( sidebarControl );
137 wp.customize.Widgets.availableWidgetsPanel.$search.val( 'HTML' ).trigger( 'keyup' );
138 });
139 },
140
141 /**
142 * Update input fields from the sync fields.
143 *
144 * This function is called at the widget-updated and widget-synced events.
145 * A field will only be updated if it is not currently focused, to avoid
146 * overwriting content that the user is entering.
147 *
148 * @return {void}
149 */
150 updateFields: function updateFields() {
151 var control = this, syncInput;
152
153 if ( ! control.fields.title.is( document.activeElement ) ) {
154 syncInput = control.syncContainer.find( '.sync-input.title' );
155 control.fields.title.val( syncInput.val() );
156 }
157
158 syncInput = control.syncContainer.find( '.sync-input.text' );
159 if ( control.fields.text.is( ':visible' ) ) {
160 if ( ! control.fields.text.is( document.activeElement ) ) {
161 control.fields.text.val( syncInput.val() );
162 }
163 } else if ( control.editor && ! control.editorFocused && syncInput.val() !== control.fields.text.val() ) {
164 control.editor.setContent( wp.oldEditor.autop( syncInput.val() ) );
165 }
166 },
167
168 /**
169 * Initialize editor.
170 *
171 * @return {void}
172 */
173 initializeEditor: function initializeEditor() {
174 var control = this, changeDebounceDelay = 1000, id, textarea, triggerChangeIfDirty, restoreTextMode = false, needsTextareaChangeTrigger = false, previousValue;
175 textarea = control.fields.text;
176 id = textarea.attr( 'id' );
177 previousValue = textarea.val();
178
179 /**
180 * Trigger change if dirty.
181 *
182 * @return {void}
183 */
184 triggerChangeIfDirty = function() {
185 var updateWidgetBuffer = 300; // See wp.customize.Widgets.WidgetControl._setupUpdateUI() which uses 250ms for updateWidgetDebounced.
186 if ( control.editor.isDirty() ) {
187
188 /*
189 * Account for race condition in customizer where user clicks Save & Publish while
190 * focus was just previously given to the editor. Since updates to the editor
191 * are debounced at 1 second and since widget input changes are only synced to
192 * settings after 250ms, the customizer needs to be put into the processing
193 * state during the time between the change event is triggered and updateWidget
194 * logic starts. Note that the debounced update-widget request should be able
195 * to be removed with the removal of the update-widget request entirely once
196 * widgets are able to mutate their own instance props directly in JS without
197 * having to make server round-trips to call the respective WP_Widget::update()
198 * callbacks. See <https://core.trac.wordpress.org/ticket/33507>.
199 */
200 if ( wp.customize && wp.customize.state ) {
201 wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() + 1 );
202 _.delay( function() {
203 wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() - 1 );
204 }, updateWidgetBuffer );
205 }
206
207 if ( ! control.editor.isHidden() ) {
208 control.editor.save();
209 }
210 }
211
212 // Trigger change on textarea when it has changed so the widget can enter a dirty state.
213 if ( needsTextareaChangeTrigger && previousValue !== textarea.val() ) {
214 textarea.trigger( 'change' );
215 needsTextareaChangeTrigger = false;
216 previousValue = textarea.val();
217 }
218 };
219
220 // Just-in-time force-update the hidden input fields.
221 control.syncContainer.closest( '.widget' ).find( '[name=savewidget]:first' ).on( 'click', function onClickSaveButton() {
222 triggerChangeIfDirty();
223 });
224
225 /**
226 * Build (or re-build) the visual editor.
227 *
228 * @return {void}
229 */
230 function buildEditor() {
231 var editor, onInit, showPointerElement;
232
233 // Abort building if the textarea is gone, likely due to the widget having been deleted entirely.
234 if ( ! document.getElementById( id ) ) {
235 return;
236 }
237
238 // The user has disabled TinyMCE.
239 if ( typeof window.tinymce === 'undefined' ) {
240 wp.oldEditor.initialize( id, {
241 quicktags: true,
242 mediaButtons: true
243 });
244
245 return;
246 }
247
248 // Destroy any existing editor so that it can be re-initialized after a widget-updated event.
249 if ( tinymce.get( id ) ) {
250 restoreTextMode = tinymce.get( id ).isHidden();
251 wp.oldEditor.remove( id );
252 }
253
254 // Add or enable the `wpview` plugin.
255 $( document ).one( 'wp-before-tinymce-init.text-widget-init', function( event, init ) {
256 // If somebody has removed all plugins, they must have a good reason.
257 // Keep it that way.
258 if ( ! init.plugins ) {
259 return;
260 } else if ( ! /\bwpview\b/.test( init.plugins ) ) {
261 init.plugins += ',wpview';
262 }
263 } );
264
265 wp.oldEditor.initialize( id, {
266 tinymce: {
267 wpautop: true
268 },
269 quicktags: true,
270 mediaButtons: true
271 });
272
273 /**
274 * Show a pointer, focus on dismiss, and speak the contents for a11y.
275 *
276 * @param {jQuery} pointerElement Pointer element.
277 * @return {void}
278 */
279 showPointerElement = function( pointerElement ) {
280 pointerElement.show();
281 pointerElement.find( '.close' ).trigger( 'focus' );
282 wp.a11y.speak( pointerElement.find( 'h3, p' ).map( function() {
283 return $( this ).text();
284 } ).get().join( '\n\n' ) );
285 };
286
287 editor = window.tinymce.get( id );
288 if ( ! editor ) {
289 throw new Error( 'Failed to initialize editor' );
290 }
291 onInit = function() {
292
293 // When a widget is moved in the DOM the dynamically-created TinyMCE iframe will be destroyed and has to be re-built.
294 $( editor.getWin() ).on( 'pagehide', function() {
295 _.defer( buildEditor );
296 });
297
298 // If a prior mce instance was replaced, and it was in text mode, toggle to text mode.
299 if ( restoreTextMode ) {
300 switchEditors.go( id, 'html' );
301 }
302
303 // Show the pointer.
304 $( '#' + id + '-html' ).on( 'click', function() {
305 control.pasteHtmlPointer.hide(); // Hide the HTML pasting pointer.
306
307 if ( -1 !== component.dismissedPointers.indexOf( 'text_widget_custom_html' ) ) {
308 return;
309 }
310 showPointerElement( control.customHtmlWidgetPointer );
311 });
312
313 // Hide the pointer when switching tabs.
314 $( '#' + id + '-tmce' ).on( 'click', function() {
315 control.customHtmlWidgetPointer.hide();
316 });
317
318 // Show pointer when pasting HTML.
319 editor.on( 'pastepreprocess', function( event ) {
320 var content = event.content;
321 if ( -1 !== component.dismissedPointers.indexOf( 'text_widget_paste_html' ) || ! content || ! /&lt;\w+.*?&gt;/.test( content ) ) {
322 return;
323 }
324
325 // Show the pointer after a slight delay so the user sees what they pasted.
326 _.delay( function() {
327 showPointerElement( control.pasteHtmlPointer );
328 }, 250 );
329 });
330 };
331
332 if ( editor.initialized ) {
333 onInit();
334 } else {
335 editor.on( 'init', onInit );
336 }
337
338 control.editorFocused = false;
339
340 editor.on( 'focus', function onEditorFocus() {
341 control.editorFocused = true;
342 });
343 editor.on( 'paste', function onEditorPaste() {
344 editor.setDirty( true ); // Because pasting doesn't currently set the dirty state.
345 triggerChangeIfDirty();
346 });
347 editor.on( 'NodeChange', function onNodeChange() {
348 needsTextareaChangeTrigger = true;
349 });
350 editor.on( 'NodeChange', _.debounce( triggerChangeIfDirty, changeDebounceDelay ) );
351 editor.on( 'blur hide', function onEditorBlur() {
352 control.editorFocused = false;
353 triggerChangeIfDirty();
354 });
355
356 control.editor = editor;
357 }
358
359 buildEditor();
360 }
361 });
362
363 /**
364 * Mapping of widget ID to instances of TextWidgetControl subclasses.
365 *
366 * @memberOf wp.textWidgets
367 *
368 * @type {Object.<string, wp.textWidgets.TextWidgetControl>}
369 */
370 component.widgetControls = {};
371
372 /**
373 * Handle widget being added or initialized for the first time at the widget-added event.
374 *
375 * @memberOf wp.textWidgets
376 *
377 * @param {jQuery.Event} event - Event.
378 * @param {jQuery} widgetContainer - Widget container element.
379 *
380 * @return {void}
381 */
382 component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) {
383 var widgetForm, idBase, widgetControl, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone, fieldContainer, syncContainer;
384 widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.
385
386 idBase = widgetForm.find( '> .id_base' ).val();
387 if ( -1 === component.idBases.indexOf( idBase ) ) {
388 return;
389 }
390
391 // Prevent initializing already-added widgets.
392 widgetId = widgetForm.find( '.widget-id' ).val();
393 if ( component.widgetControls[ widgetId ] ) {
394 return;
395 }
396
397 // Bypass using TinyMCE when widget is in legacy mode.
398 if ( ! widgetForm.find( '.visual' ).val() ) {
399 return;
400 }
401
402 /*
403 * Create a container element for the widget control fields.
404 * This is inserted into the DOM immediately before the .widget-content
405 * element because the contents of this element are essentially "managed"
406 * by PHP, where each widget update cause the entire element to be emptied
407 * and replaced with the rendered output of WP_Widget::form() which is
408 * sent back in Ajax request made to save/update the widget instance.
409 * To prevent a "flash of replaced DOM elements and re-initialized JS
410 * components", the JS template is rendered outside of the normal form
411 * container.
412 */
413 fieldContainer = $( '<div></div>' );
414 syncContainer = widgetContainer.find( '.widget-content:first' );
415 syncContainer.before( fieldContainer );
416
417 widgetControl = new component.TextWidgetControl({
418 el: fieldContainer,
419 syncContainer: syncContainer
420 });
421
422 component.widgetControls[ widgetId ] = widgetControl;
423
424 /*
425 * Render the widget once the widget parent's container finishes animating,
426 * as the widget-added event fires with a slideDown of the container.
427 * This ensures that the textarea is visible and an iframe can be embedded
428 * with TinyMCE being able to set contenteditable on it.
429 */
430 renderWhenAnimationDone = function() {
431 if ( ! widgetContainer.hasClass( 'open' ) ) {
432 setTimeout( renderWhenAnimationDone, animatedCheckDelay );
433 } else {
434 widgetControl.initializeEditor();
435 }
436 };
437 renderWhenAnimationDone();
438 };
439
440 /**
441 * Setup widget in accessibility mode.
442 *
443 * @memberOf wp.textWidgets
444 *
445 * @return {void}
446 */
447 component.setupAccessibleMode = function setupAccessibleMode() {
448 var widgetForm, idBase, widgetControl, fieldContainer, syncContainer;
449 widgetForm = $( '.editwidget > form' );
450 if ( 0 === widgetForm.length ) {
451 return;
452 }
453
454 idBase = widgetForm.find( '.id_base' ).val();
455 if ( -1 === component.idBases.indexOf( idBase ) ) {
456 return;
457 }
458
459 // Bypass using TinyMCE when widget is in legacy mode.
460 if ( ! widgetForm.find( '.visual' ).val() ) {
461 return;
462 }
463
464 fieldContainer = $( '<div></div>' );
465 syncContainer = widgetForm.find( '> .widget-inside' );
466 syncContainer.before( fieldContainer );
467
468 widgetControl = new component.TextWidgetControl({
469 el: fieldContainer,
470 syncContainer: syncContainer
471 });
472
473 widgetControl.initializeEditor();
474 };
475
476 /**
477 * Sync widget instance data sanitized from server back onto widget model.
478 *
479 * This gets called via the 'widget-updated' event when saving a widget from
480 * the widgets admin screen and also via the 'widget-synced' event when making
481 * a change to a widget in the customizer.
482 *
483 * @memberOf wp.textWidgets
484 *
485 * @param {jQuery.Event} event - Event.
486 * @param {jQuery} widgetContainer - Widget container element.
487 * @return {void}
488 */
489 component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) {
490 var widgetForm, widgetId, widgetControl, idBase;
491 widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' );
492
493 idBase = widgetForm.find( '> .id_base' ).val();
494 if ( -1 === component.idBases.indexOf( idBase ) ) {
495 return;
496 }
497
498 widgetId = widgetForm.find( '> .widget-id' ).val();
499 widgetControl = component.widgetControls[ widgetId ];
500 if ( ! widgetControl ) {
501 return;
502 }
503
504 widgetControl.updateFields();
505 };
506
507 /**
508 * Initialize functionality.
509 *
510 * This function exists to prevent the JS file from having to boot itself.
511 * When WordPress enqueues this script, it should have an inline script
512 * attached which calls wp.textWidgets.init().
513 *
514 * @memberOf wp.textWidgets
515 *
516 * @return {void}
517 */
518 component.init = function init() {
519 var $document = $( document );
520 $document.on( 'widget-added', component.handleWidgetAdded );
521 $document.on( 'widget-synced widget-updated', component.handleWidgetUpdated );
522
523 /*
524 * Manually trigger widget-added events for media widgets on the admin
525 * screen once they are expanded. The widget-added event is not triggered
526 * for each pre-existing widget on the widgets admin screen like it is
527 * on the customizer. Likewise, the customizer only triggers widget-added
528 * when the widget is expanded to just-in-time construct the widget form
529 * when it is actually going to be displayed. So the following implements
530 * the same for the widgets admin screen, to invoke the widget-added
531 * handler when a pre-existing media widget is expanded.
532 */
533 $( function initializeExistingWidgetContainers() {
534 var widgetContainers;
535 if ( 'widgets' !== window.pagenow ) {
536 return;
537 }
538 widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' );
539 widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() {
540 var widgetContainer = $( this );
541 component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer );
542 });
543
544 // Accessibility mode.
545 component.setupAccessibleMode();
546 });
547 };
548
549 return component;
550})( jQuery );
551
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