diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
| commit | 5bf66662a9bdd62c5bccab15e607cd95cfb8fcab (patch) | |
| tree | 39a1a4629749056191c05dfd899f931701b7acf3 /srcs/wordpress/wp-admin/js/widgets | |
| parent | 5afd237bbd22028b85532b8c0b3fcead49a00764 (diff) | |
| download | ft_server-master.tar.gz ft_server-master.tar.bz2 ft_server-master.zip | |
Removed wordpress and phpmyadmin, my server doesn't handle it well and it brings shame on my famillyHEADmaster
Diffstat (limited to 'srcs/wordpress/wp-admin/js/widgets')
14 files changed, 0 insertions, 3266 deletions
diff --git a/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.js b/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.js deleted file mode 100644 index 93aa901..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.js +++ /dev/null @@ -1,456 +0,0 @@ -/** - * @output wp-admin/js/widgets/custom-html-widgets.js - */ - -/* global wp */ -/* eslint consistent-this: [ "error", "control" ] */ -/* eslint no-magic-numbers: ["error", { "ignore": [0,1,-1] }] */ - -/** - * @namespace wp.customHtmlWidget - * @memberOf wp - */ -wp.customHtmlWidgets = ( function( $ ) { - 'use strict'; - - var component = { - idBases: [ 'custom_html' ], - codeEditorSettings: {}, - l10n: { - errorNotice: { - singular: '', - plural: '' - } - } - }; - - component.CustomHtmlWidgetControl = Backbone.View.extend(/** @lends wp.customHtmlWidgets.CustomHtmlWidgetControl.prototype */{ - - /** - * View events. - * - * @type {Object} - */ - events: {}, - - /** - * Text widget control. - * - * @constructs wp.customHtmlWidgets.CustomHtmlWidgetControl - * @augments Backbone.View - * @abstract - * - * @param {Object} options - Options. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. - * - * @returns {void} - */ - initialize: function initialize( options ) { - var control = this; - - if ( ! options.el ) { - throw new Error( 'Missing options.el' ); - } - if ( ! options.syncContainer ) { - throw new Error( 'Missing options.syncContainer' ); - } - - Backbone.View.prototype.initialize.call( control, options ); - control.syncContainer = options.syncContainer; - control.widgetIdBase = control.syncContainer.parent().find( '.id_base' ).val(); - control.widgetNumber = control.syncContainer.parent().find( '.widget_number' ).val(); - control.customizeSettingId = 'widget_' + control.widgetIdBase + '[' + String( control.widgetNumber ) + ']'; - - control.$el.addClass( 'custom-html-widget-fields' ); - control.$el.html( wp.template( 'widget-custom-html-control-fields' )( { codeEditorDisabled: component.codeEditorSettings.disabled } ) ); - - control.errorNoticeContainer = control.$el.find( '.code-editor-error-container' ); - control.currentErrorAnnotations = []; - control.saveButton = control.syncContainer.add( control.syncContainer.parent().find( '.widget-control-actions' ) ).find( '.widget-control-save, #savewidget' ); - control.saveButton.addClass( 'custom-html-widget-save-button' ); // To facilitate style targeting. - - control.fields = { - title: control.$el.find( '.title' ), - content: control.$el.find( '.content' ) - }; - - // Sync input fields to hidden sync fields which actually get sent to the server. - _.each( control.fields, function( fieldInput, fieldName ) { - fieldInput.on( 'input change', function updateSyncField() { - var syncInput = control.syncContainer.find( '.sync-input.' + fieldName ); - if ( syncInput.val() !== fieldInput.val() ) { - syncInput.val( fieldInput.val() ); - syncInput.trigger( 'change' ); - } - }); - - // Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event. - fieldInput.val( control.syncContainer.find( '.sync-input.' + fieldName ).val() ); - }); - }, - - /** - * Update input fields from the sync fields. - * - * This function is called at the widget-updated and widget-synced events. - * A field will only be updated if it is not currently focused, to avoid - * overwriting content that the user is entering. - * - * @returns {void} - */ - updateFields: function updateFields() { - var control = this, syncInput; - - if ( ! control.fields.title.is( document.activeElement ) ) { - syncInput = control.syncContainer.find( '.sync-input.title' ); - control.fields.title.val( syncInput.val() ); - } - - /* - * Prevent updating content when the editor is focused or if there are current error annotations, - * to prevent the editor's contents from getting sanitized as soon as a user removes focus from - * the editor. This is particularly important for users who cannot unfiltered_html. - */ - control.contentUpdateBypassed = control.fields.content.is( document.activeElement ) || control.editor && control.editor.codemirror.state.focused || 0 !== control.currentErrorAnnotations.length; - if ( ! control.contentUpdateBypassed ) { - syncInput = control.syncContainer.find( '.sync-input.content' ); - control.fields.content.val( syncInput.val() ); - } - }, - - /** - * Show linting error notice. - * - * @param {Array} errorAnnotations - Error annotations. - * @returns {void} - */ - updateErrorNotice: function( errorAnnotations ) { - var control = this, errorNotice, message = '', customizeSetting; - - if ( 1 === errorAnnotations.length ) { - message = component.l10n.errorNotice.singular.replace( '%d', '1' ); - } else if ( errorAnnotations.length > 1 ) { - message = component.l10n.errorNotice.plural.replace( '%d', String( errorAnnotations.length ) ); - } - - if ( control.fields.content[0].setCustomValidity ) { - control.fields.content[0].setCustomValidity( message ); - } - - if ( wp.customize && wp.customize.has( control.customizeSettingId ) ) { - customizeSetting = wp.customize( control.customizeSettingId ); - customizeSetting.notifications.remove( 'htmlhint_error' ); - if ( 0 !== errorAnnotations.length ) { - customizeSetting.notifications.add( 'htmlhint_error', new wp.customize.Notification( 'htmlhint_error', { - message: message, - type: 'error' - } ) ); - } - } else if ( 0 !== errorAnnotations.length ) { - errorNotice = $( '<div class="inline notice notice-error notice-alt"></div>' ); - errorNotice.append( $( '<p></p>', { - text: message - } ) ); - control.errorNoticeContainer.empty(); - control.errorNoticeContainer.append( errorNotice ); - control.errorNoticeContainer.slideDown( 'fast' ); - wp.a11y.speak( message ); - } else { - control.errorNoticeContainer.slideUp( 'fast' ); - } - }, - - /** - * Initialize editor. - * - * @returns {void} - */ - initializeEditor: function initializeEditor() { - var control = this, settings; - - if ( component.codeEditorSettings.disabled ) { - return; - } - - settings = _.extend( {}, component.codeEditorSettings, { - - /** - * Handle tabbing to the field before the editor. - * - * @ignore - * - * @returns {void} - */ - onTabPrevious: function onTabPrevious() { - control.fields.title.focus(); - }, - - /** - * Handle tabbing to the field after the editor. - * - * @ignore - * - * @returns {void} - */ - onTabNext: function onTabNext() { - var tabbables = control.syncContainer.add( control.syncContainer.parent().find( '.widget-position, .widget-control-actions' ) ).find( ':tabbable' ); - tabbables.first().focus(); - }, - - /** - * Disable save button and store linting errors for use in updateFields. - * - * @ignore - * - * @param {Array} errorAnnotations - Error notifications. - * @returns {void} - */ - onChangeLintingErrors: function onChangeLintingErrors( errorAnnotations ) { - control.currentErrorAnnotations = errorAnnotations; - }, - - /** - * Update error notice. - * - * @ignore - * - * @param {Array} errorAnnotations - Error annotations. - * @returns {void} - */ - onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) { - control.saveButton.toggleClass( 'validation-blocked disabled', errorAnnotations.length > 0 ); - control.updateErrorNotice( errorAnnotations ); - } - }); - - control.editor = wp.codeEditor.initialize( control.fields.content, settings ); - - // Improve the editor accessibility. - $( control.editor.codemirror.display.lineDiv ) - .attr({ - role: 'textbox', - 'aria-multiline': 'true', - 'aria-labelledby': control.fields.content[0].id + '-label', - 'aria-describedby': 'editor-keyboard-trap-help-1 editor-keyboard-trap-help-2 editor-keyboard-trap-help-3 editor-keyboard-trap-help-4' - }); - - // Focus the editor when clicking on its label. - $( '#' + control.fields.content[0].id + '-label' ).on( 'click', function() { - control.editor.codemirror.focus(); - }); - - control.fields.content.on( 'change', function() { - if ( this.value !== control.editor.codemirror.getValue() ) { - control.editor.codemirror.setValue( this.value ); - } - }); - control.editor.codemirror.on( 'change', function() { - var value = control.editor.codemirror.getValue(); - if ( value !== control.fields.content.val() ) { - control.fields.content.val( value ).trigger( 'change' ); - } - }); - - // Make sure the editor gets updated if the content was updated on the server (sanitization) but not updated in the editor since it was focused. - control.editor.codemirror.on( 'blur', function() { - if ( control.contentUpdateBypassed ) { - control.syncContainer.find( '.sync-input.content' ).trigger( 'change' ); - } - }); - - // Prevent hitting Esc from collapsing the widget control. - if ( wp.customize ) { - control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) { - var escKeyCode = 27; - if ( escKeyCode === event.keyCode ) { - event.stopPropagation(); - } - }); - } - } - }); - - /** - * Mapping of widget ID to instances of CustomHtmlWidgetControl subclasses. - * - * @alias wp.customHtmlWidgets.widgetControls - * - * @type {Object.<string, wp.textWidgets.CustomHtmlWidgetControl>} - */ - component.widgetControls = {}; - - /** - * Handle widget being added or initialized for the first time at the widget-added event. - * - * @alias wp.customHtmlWidgets.handleWidgetAdded - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * - * @returns {void} - */ - component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) { - var widgetForm, idBase, widgetControl, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone, fieldContainer, syncContainer; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen. - - idBase = widgetForm.find( '> .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - // Prevent initializing already-added widgets. - widgetId = widgetForm.find( '.widget-id' ).val(); - if ( component.widgetControls[ widgetId ] ) { - return; - } - - /* - * Create a container element for the widget control fields. - * This is inserted into the DOM immediately before the the .widget-content - * element because the contents of this element are essentially "managed" - * by PHP, where each widget update cause the entire element to be emptied - * and replaced with the rendered output of WP_Widget::form() which is - * sent back in Ajax request made to save/update the widget instance. - * To prevent a "flash of replaced DOM elements and re-initialized JS - * components", the JS template is rendered outside of the normal form - * container. - */ - fieldContainer = $( '<div></div>' ); - syncContainer = widgetContainer.find( '.widget-content:first' ); - syncContainer.before( fieldContainer ); - - widgetControl = new component.CustomHtmlWidgetControl({ - el: fieldContainer, - syncContainer: syncContainer - }); - - component.widgetControls[ widgetId ] = widgetControl; - - /* - * Render the widget once the widget parent's container finishes animating, - * as the widget-added event fires with a slideDown of the container. - * This ensures that the textarea is visible and the editor can be initialized. - */ - renderWhenAnimationDone = function() { - if ( ! ( wp.customize ? widgetContainer.parent().hasClass( 'expanded' ) : widgetContainer.hasClass( 'open' ) ) ) { // Core merge: The wp.customize condition can be eliminated with this change being in core: https://github.com/xwp/wordpress-develop/pull/247/commits/5322387d - setTimeout( renderWhenAnimationDone, animatedCheckDelay ); - } else { - widgetControl.initializeEditor(); - } - }; - renderWhenAnimationDone(); - }; - - /** - * Setup widget in accessibility mode. - * - * @alias wp.customHtmlWidgets.setupAccessibleMode - * - * @returns {void} - */ - component.setupAccessibleMode = function setupAccessibleMode() { - var widgetForm, idBase, widgetControl, fieldContainer, syncContainer; - widgetForm = $( '.editwidget > form' ); - if ( 0 === widgetForm.length ) { - return; - } - - idBase = widgetForm.find( '> .widget-control-actions > .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - fieldContainer = $( '<div></div>' ); - syncContainer = widgetForm.find( '> .widget-inside' ); - syncContainer.before( fieldContainer ); - - widgetControl = new component.CustomHtmlWidgetControl({ - el: fieldContainer, - syncContainer: syncContainer - }); - - widgetControl.initializeEditor(); - }; - - /** - * Sync widget instance data sanitized from server back onto widget model. - * - * This gets called via the 'widget-updated' event when saving a widget from - * the widgets admin screen and also via the 'widget-synced' event when making - * a change to a widget in the customizer. - * - * @alias wp.customHtmlWidgets.handleWidgetUpdated - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * @returns {void} - */ - component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) { - var widgetForm, widgetId, widgetControl, idBase; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); - - idBase = widgetForm.find( '> .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - widgetId = widgetForm.find( '> .widget-id' ).val(); - widgetControl = component.widgetControls[ widgetId ]; - if ( ! widgetControl ) { - return; - } - - widgetControl.updateFields(); - }; - - /** - * Initialize functionality. - * - * This function exists to prevent the JS file from having to boot itself. - * When WordPress enqueues this script, it should have an inline script - * attached which calls wp.textWidgets.init(). - * - * @alias wp.customHtmlWidgets.init - * - * @param {object} settings - Options for code editor, exported from PHP. - * - * @returns {void} - */ - component.init = function init( settings ) { - var $document = $( document ); - _.extend( component.codeEditorSettings, settings ); - - $document.on( 'widget-added', component.handleWidgetAdded ); - $document.on( 'widget-synced widget-updated', component.handleWidgetUpdated ); - - /* - * Manually trigger widget-added events for media widgets on the admin - * screen once they are expanded. The widget-added event is not triggered - * for each pre-existing widget on the widgets admin screen like it is - * on the customizer. Likewise, the customizer only triggers widget-added - * when the widget is expanded to just-in-time construct the widget form - * when it is actually going to be displayed. So the following implements - * the same for the widgets admin screen, to invoke the widget-added - * handler when a pre-existing media widget is expanded. - */ - $( function initializeExistingWidgetContainers() { - var widgetContainers; - if ( 'widgets' !== window.pagenow ) { - return; - } - widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' ); - widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() { - var widgetContainer = $( this ); - component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer ); - }); - - // Accessibility mode. - $( window ).on( 'load', function() { - component.setupAccessibleMode(); - }); - }); - }; - - return component; -})( jQuery ); diff --git a/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.min.js b/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.min.js deleted file mode 100644 index 4fcc0c0..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/custom-html-widgets.min.js +++ /dev/null @@ -1 +0,0 @@ -wp.customHtmlWidgets=function(l){"use strict";var c={idBases:["custom_html"],codeEditorSettings:{},l10n:{errorNotice:{singular:"",plural:""}}};return c.CustomHtmlWidgetControl=Backbone.View.extend({events:{},initialize:function(e){var n=this;if(!e.el)throw new Error("Missing options.el");if(!e.syncContainer)throw new Error("Missing options.syncContainer");Backbone.View.prototype.initialize.call(n,e),n.syncContainer=e.syncContainer,n.widgetIdBase=n.syncContainer.parent().find(".id_base").val(),n.widgetNumber=n.syncContainer.parent().find(".widget_number").val(),n.customizeSettingId="widget_"+n.widgetIdBase+"["+String(n.widgetNumber)+"]",n.$el.addClass("custom-html-widget-fields"),n.$el.html(wp.template("widget-custom-html-control-fields")({codeEditorDisabled:c.codeEditorSettings.disabled})),n.errorNoticeContainer=n.$el.find(".code-editor-error-container"),n.currentErrorAnnotations=[],n.saveButton=n.syncContainer.add(n.syncContainer.parent().find(".widget-control-actions")).find(".widget-control-save, #savewidget"),n.saveButton.addClass("custom-html-widget-save-button"),n.fields={title:n.$el.find(".title"),content:n.$el.find(".content")},_.each(n.fields,function(t,i){t.on("input change",function(){var e=n.syncContainer.find(".sync-input."+i);e.val()!==t.val()&&(e.val(t.val()),e.trigger("change"))}),t.val(n.syncContainer.find(".sync-input."+i).val())})},updateFields:function(){var e,t=this;t.fields.title.is(document.activeElement)||(e=t.syncContainer.find(".sync-input.title"),t.fields.title.val(e.val())),t.contentUpdateBypassed=t.fields.content.is(document.activeElement)||t.editor&&t.editor.codemirror.state.focused||0!==t.currentErrorAnnotations.length,t.contentUpdateBypassed||(e=t.syncContainer.find(".sync-input.content"),t.fields.content.val(e.val()))},updateErrorNotice:function(e){var t,i,n=this,o="";1===e.length?o=c.l10n.errorNotice.singular.replace("%d","1"):1<e.length&&(o=c.l10n.errorNotice.plural.replace("%d",String(e.length))),n.fields.content[0].setCustomValidity&&n.fields.content[0].setCustomValidity(o),wp.customize&&wp.customize.has(n.customizeSettingId)?((i=wp.customize(n.customizeSettingId)).notifications.remove("htmlhint_error"),0!==e.length&&i.notifications.add("htmlhint_error",new wp.customize.Notification("htmlhint_error",{message:o,type:"error"}))):0!==e.length?((t=l('<div class="inline notice notice-error notice-alt"></div>')).append(l("<p></p>",{text:o})),n.errorNoticeContainer.empty(),n.errorNoticeContainer.append(t),n.errorNoticeContainer.slideDown("fast"),wp.a11y.speak(o)):n.errorNoticeContainer.slideUp("fast")},initializeEditor:function(){var e,t=this;c.codeEditorSettings.disabled||(e=_.extend({},c.codeEditorSettings,{onTabPrevious:function(){t.fields.title.focus()},onTabNext:function(){t.syncContainer.add(t.syncContainer.parent().find(".widget-position, .widget-control-actions")).find(":tabbable").first().focus()},onChangeLintingErrors:function(e){t.currentErrorAnnotations=e},onUpdateErrorNotice:function(e){t.saveButton.toggleClass("validation-blocked disabled",0<e.length),t.updateErrorNotice(e)}}),t.editor=wp.codeEditor.initialize(t.fields.content,e),l(t.editor.codemirror.display.lineDiv).attr({role:"textbox","aria-multiline":"true","aria-labelledby":t.fields.content[0].id+"-label","aria-describedby":"editor-keyboard-trap-help-1 editor-keyboard-trap-help-2 editor-keyboard-trap-help-3 editor-keyboard-trap-help-4"}),l("#"+t.fields.content[0].id+"-label").on("click",function(){t.editor.codemirror.focus()}),t.fields.content.on("change",function(){this.value!==t.editor.codemirror.getValue()&&t.editor.codemirror.setValue(this.value)}),t.editor.codemirror.on("change",function(){var e=t.editor.codemirror.getValue();e!==t.fields.content.val()&&t.fields.content.val(e).trigger("change")}),t.editor.codemirror.on("blur",function(){t.contentUpdateBypassed&&t.syncContainer.find(".sync-input.content").trigger("change")}),wp.customize&&t.editor.codemirror.on("keydown",function(e,t){27===t.keyCode&&t.stopPropagation()}))}}),c.widgetControls={},c.handleWidgetAdded=function(e,t){var i,n,o,d,r,a,s;n=(i=t.find("> .widget-inside > .form, > .widget-inside > form")).find("> .id_base").val(),-1!==c.idBases.indexOf(n)&&(d=i.find(".widget-id").val(),c.widgetControls[d]||(a=l("<div></div>"),(s=t.find(".widget-content:first")).before(a),o=new c.CustomHtmlWidgetControl({el:a,syncContainer:s}),c.widgetControls[d]=o,(r=function(){(wp.customize?t.parent().hasClass("expanded"):t.hasClass("open"))?o.initializeEditor():setTimeout(r,50)})()))},c.setupAccessibleMode=function(){var e,t,i,n;0!==(e=l(".editwidget > form")).length&&(t=e.find("> .widget-control-actions > .id_base").val(),-1!==c.idBases.indexOf(t)&&(i=l("<div></div>"),(n=e.find("> .widget-inside")).before(i),new c.CustomHtmlWidgetControl({el:i,syncContainer:n}).initializeEditor()))},c.handleWidgetUpdated=function(e,t){var i,n,o,d;d=(i=t.find("> .widget-inside > .form, > .widget-inside > form")).find("> .id_base").val(),-1!==c.idBases.indexOf(d)&&(n=i.find("> .widget-id").val(),(o=c.widgetControls[n])&&o.updateFields())},c.init=function(e){var t=l(document);_.extend(c.codeEditorSettings,e),t.on("widget-added",c.handleWidgetAdded),t.on("widget-synced widget-updated",c.handleWidgetUpdated),l(function(){"widgets"===window.pagenow&&(l(".widgets-holder-wrap:not(#available-widgets)").find("div.widget").one("click.toggle-widget-expanded",function(){var e=l(this);c.handleWidgetAdded(new jQuery.Event("widget-added"),e)}),l(window).on("load",function(){c.setupAccessibleMode()}))})},c}(jQuery);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.js b/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.js deleted file mode 100644 index e050c30..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.js +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @output wp-admin/js/widgets/media-audio-widget.js - */ - -/* eslint consistent-this: [ "error", "control" ] */ -(function( component ) { - 'use strict'; - - var AudioWidgetModel, AudioWidgetControl, AudioDetailsMediaFrame; - - /** - * Custom audio details frame that removes the replace-audio state. - * - * @class wp.mediaWidgets.controlConstructors~AudioDetailsMediaFrame - * @augments wp.media.view.MediaFrame.AudioDetails - */ - AudioDetailsMediaFrame = wp.media.view.MediaFrame.AudioDetails.extend(/** @lends wp.mediaWidgets.controlConstructors~AudioDetailsMediaFrame.prototype */{ - - /** - * Create the default states. - * - * @returns {void} - */ - createStates: function createStates() { - this.states.add([ - new wp.media.controller.AudioDetails({ - media: this.media - }), - - new wp.media.controller.MediaLibrary({ - type: 'audio', - id: 'add-audio-source', - title: wp.media.view.l10n.audioAddSourceTitle, - toolbar: 'add-audio-source', - media: this.media, - menu: false - }) - ]); - } - }); - - /** - * Audio widget model. - * - * See WP_Widget_Audio::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.modelConstructors.media_audio - * @augments wp.mediaWidgets.MediaWidgetModel - */ - AudioWidgetModel = component.MediaWidgetModel.extend({}); - - /** - * Audio widget control. - * - * See WP_Widget_Audio::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.controlConstructors.media_audio - * @augments wp.mediaWidgets.MediaWidgetControl - */ - AudioWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_audio.prototype */{ - - /** - * Show display settings. - * - * @type {boolean} - */ - showDisplaySettings: false, - - /** - * Map model props to media frame props. - * - * @param {Object} modelProps - Model props. - * @returns {Object} Media frame props. - */ - mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { - var control = this, mediaFrameProps; - mediaFrameProps = component.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call( control, modelProps ); - mediaFrameProps.link = 'embed'; - return mediaFrameProps; - }, - - /** - * Render preview. - * - * @returns {void} - */ - renderPreview: function renderPreview() { - var control = this, previewContainer, previewTemplate, attachmentId, attachmentUrl; - attachmentId = control.model.get( 'attachment_id' ); - attachmentUrl = control.model.get( 'url' ); - - if ( ! attachmentId && ! attachmentUrl ) { - return; - } - - previewContainer = control.$el.find( '.media-widget-preview' ); - previewTemplate = wp.template( 'wp-media-widget-audio-preview' ); - - previewContainer.html( previewTemplate({ - model: { - attachment_id: control.model.get( 'attachment_id' ), - src: attachmentUrl - }, - error: control.model.get( 'error' ) - })); - wp.mediaelement.initialize(); - }, - - /** - * Open the media audio-edit frame to modify the selected item. - * - * @returns {void} - */ - editMedia: function editMedia() { - var control = this, mediaFrame, metadata, updateCallback; - - metadata = control.mapModelToMediaFrameProps( control.model.toJSON() ); - - // Set up the media frame. - mediaFrame = new AudioDetailsMediaFrame({ - frame: 'audio', - state: 'audio-details', - metadata: metadata - }); - wp.media.frame = mediaFrame; - mediaFrame.$el.addClass( 'media-widget' ); - - updateCallback = function( mediaFrameProps ) { - - // Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview. - control.selectedAttachment.set( mediaFrameProps ); - - control.model.set( _.extend( - control.model.defaults(), - control.mapMediaToModelProps( mediaFrameProps ), - { error: false } - ) ); - }; - - mediaFrame.state( 'audio-details' ).on( 'update', updateCallback ); - mediaFrame.state( 'replace-audio' ).on( 'replace', updateCallback ); - mediaFrame.on( 'close', function() { - mediaFrame.detach(); - }); - - mediaFrame.open(); - } - }); - - // Exports. - component.controlConstructors.media_audio = AudioWidgetControl; - component.modelConstructors.media_audio = AudioWidgetModel; - -})( wp.mediaWidgets ); diff --git a/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.min.js b/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.min.js deleted file mode 100644 index d1c44fc..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-audio-widget.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(d){"use strict";var e,t,i;i=wp.media.view.MediaFrame.AudioDetails.extend({createStates:function(){this.states.add([new wp.media.controller.AudioDetails({media:this.media}),new wp.media.controller.MediaLibrary({type:"audio",id:"add-audio-source",title:wp.media.view.l10n.audioAddSourceTitle,toolbar:"add-audio-source",media:this.media,menu:!1})])}}),e=d.MediaWidgetModel.extend({}),t=d.MediaWidgetControl.extend({showDisplaySettings:!1,mapModelToMediaFrameProps:function(e){var t;return(t=d.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call(this,e)).link="embed",t},renderPreview:function(){var e,t,d,a,i=this;d=i.model.get("attachment_id"),a=i.model.get("url"),(d||a)&&(e=i.$el.find(".media-widget-preview"),t=wp.template("wp-media-widget-audio-preview"),e.html(t({model:{attachment_id:i.model.get("attachment_id"),src:a},error:i.model.get("error")})),wp.mediaelement.initialize())},editMedia:function(){var e,t,d,a=this;t=a.mapModelToMediaFrameProps(a.model.toJSON()),e=new i({frame:"audio",state:"audio-details",metadata:t}),(wp.media.frame=e).$el.addClass("media-widget"),d=function(e){a.selectedAttachment.set(e),a.model.set(_.extend(a.model.defaults(),a.mapMediaToModelProps(e),{error:!1}))},e.state("audio-details").on("update",d),e.state("replace-audio").on("replace",d),e.on("close",function(){e.detach()}),e.open()}}),d.controlConstructors.media_audio=t,d.modelConstructors.media_audio=e}(wp.mediaWidgets);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.js b/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.js deleted file mode 100644 index 45671e7..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.js +++ /dev/null @@ -1,341 +0,0 @@ -/** - * @output wp-admin/js/widgets/media-gallery-widget.js - */ - -/* eslint consistent-this: [ "error", "control" ] */ -(function( component ) { - 'use strict'; - - var GalleryWidgetModel, GalleryWidgetControl, GalleryDetailsMediaFrame; - - /** - * Custom gallery details frame. - * - * @since 4.9.0 - * @class wp.mediaWidgets~GalleryDetailsMediaFrame - * @augments wp.media.view.MediaFrame.Post - */ - GalleryDetailsMediaFrame = wp.media.view.MediaFrame.Post.extend(/** @lends wp.mediaWidgets~GalleryDetailsMediaFrame.prototype */{ - - /** - * Create the default states. - * - * @since 4.9.0 - * @returns {void} - */ - createStates: function createStates() { - this.states.add([ - new wp.media.controller.Library({ - id: 'gallery', - title: wp.media.view.l10n.createGalleryTitle, - priority: 40, - toolbar: 'main-gallery', - filterable: 'uploaded', - multiple: 'add', - editable: true, - - library: wp.media.query( _.defaults({ - type: 'image' - }, this.options.library ) ) - }), - - // Gallery states. - new wp.media.controller.GalleryEdit({ - library: this.options.selection, - editing: this.options.editing, - menu: 'gallery' - }), - - new wp.media.controller.GalleryAdd() - ]); - } - } ); - - /** - * Gallery widget model. - * - * See WP_Widget_Gallery::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @since 4.9.0 - * - * @class wp.mediaWidgets.modelConstructors.media_gallery - * @augments wp.mediaWidgets.MediaWidgetModel - */ - GalleryWidgetModel = component.MediaWidgetModel.extend(/** @lends wp.mediaWidgets.modelConstructors.media_gallery.prototype */{} ); - - GalleryWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_gallery.prototype */{ - - /** - * View events. - * - * @since 4.9.0 - * @type {object} - */ - events: _.extend( {}, component.MediaWidgetControl.prototype.events, { - 'click .media-widget-gallery-preview': 'editMedia' - } ), - - /** - * Gallery widget control. - * - * See WP_Widget_Gallery::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @constructs wp.mediaWidgets.controlConstructors.media_gallery - * @augments wp.mediaWidgets.MediaWidgetControl - * - * @since 4.9.0 - * @param {Object} options - Options. - * @param {Backbone.Model} options.model - Model. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. - * @returns {void} - */ - initialize: function initialize( options ) { - var control = this; - - component.MediaWidgetControl.prototype.initialize.call( control, options ); - - _.bindAll( control, 'updateSelectedAttachments', 'handleAttachmentDestroy' ); - control.selectedAttachments = new wp.media.model.Attachments(); - control.model.on( 'change:ids', control.updateSelectedAttachments ); - control.selectedAttachments.on( 'change', control.renderPreview ); - control.selectedAttachments.on( 'reset', control.renderPreview ); - control.updateSelectedAttachments(); - - /* - * Refresh a Gallery widget partial when the user modifies one of the selected attachments. - * This ensures that when an attachment's caption is updated in the media modal the Gallery - * widget in the preview will then be refreshed to show the change. Normally doing this - * would not be necessary because all of the state should be contained inside the changeset, - * as everything done in the Customizer should not make a change to the site unless the - * changeset itself is published. Attachments are a current exception to this rule. - * For a proposal to include attachments in the customized state, see #37887. - */ - if ( wp.customize && wp.customize.previewer ) { - control.selectedAttachments.on( 'change', function() { - wp.customize.previewer.send( 'refresh-widget-partial', control.model.get( 'widget_id' ) ); - } ); - } - }, - - /** - * Update the selected attachments if necessary. - * - * @since 4.9.0 - * @returns {void} - */ - updateSelectedAttachments: function updateSelectedAttachments() { - var control = this, newIds, oldIds, removedIds, addedIds, addedQuery; - - newIds = control.model.get( 'ids' ); - oldIds = _.pluck( control.selectedAttachments.models, 'id' ); - - removedIds = _.difference( oldIds, newIds ); - _.each( removedIds, function( removedId ) { - control.selectedAttachments.remove( control.selectedAttachments.get( removedId ) ); - }); - - addedIds = _.difference( newIds, oldIds ); - if ( addedIds.length ) { - addedQuery = wp.media.query({ - order: 'ASC', - orderby: 'post__in', - perPage: -1, - post__in: newIds, - query: true, - type: 'image' - }); - addedQuery.more().done( function() { - control.selectedAttachments.reset( addedQuery.models ); - }); - } - }, - - /** - * Render preview. - * - * @since 4.9.0 - * @returns {void} - */ - renderPreview: function renderPreview() { - var control = this, previewContainer, previewTemplate, data; - - previewContainer = control.$el.find( '.media-widget-preview' ); - previewTemplate = wp.template( 'wp-media-widget-gallery-preview' ); - - data = control.previewTemplateProps.toJSON(); - data.attachments = {}; - control.selectedAttachments.each( function( attachment ) { - data.attachments[ attachment.id ] = attachment.toJSON(); - } ); - - previewContainer.html( previewTemplate( data ) ); - }, - - /** - * Determine whether there are selected attachments. - * - * @since 4.9.0 - * @returns {boolean} Selected. - */ - isSelected: function isSelected() { - var control = this; - - if ( control.model.get( 'error' ) ) { - return false; - } - - return control.model.get( 'ids' ).length > 0; - }, - - /** - * Open the media select frame to edit images. - * - * @since 4.9.0 - * @returns {void} - */ - editMedia: function editMedia() { - var control = this, selection, mediaFrame, mediaFrameProps; - - selection = new wp.media.model.Selection( control.selectedAttachments.models, { - multiple: true - }); - - mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() ); - selection.gallery = new Backbone.Model( mediaFrameProps ); - if ( mediaFrameProps.size ) { - control.displaySettings.set( 'size', mediaFrameProps.size ); - } - mediaFrame = new GalleryDetailsMediaFrame({ - frame: 'manage', - text: control.l10n.add_to_widget, - selection: selection, - mimeType: control.mime_type, - selectedDisplaySettings: control.displaySettings, - showDisplaySettings: control.showDisplaySettings, - metadata: mediaFrameProps, - editing: true, - multiple: true, - state: 'gallery-edit' - }); - wp.media.frame = mediaFrame; // See wp.media(). - - // Handle selection of a media item. - mediaFrame.on( 'update', function onUpdate( newSelection ) { - var state = mediaFrame.state(), resultSelection; - - resultSelection = newSelection || state.get( 'selection' ); - if ( ! resultSelection ) { - return; - } - - // Copy orderby_random from gallery state. - if ( resultSelection.gallery ) { - control.model.set( control.mapMediaToModelProps( resultSelection.gallery.toJSON() ) ); - } - - // Directly update selectedAttachments to prevent needing to do additional request. - control.selectedAttachments.reset( resultSelection.models ); - - // Update models in the widget instance. - control.model.set( { - ids: _.pluck( resultSelection.models, 'id' ) - } ); - } ); - - mediaFrame.$el.addClass( 'media-widget' ); - mediaFrame.open(); - - if ( selection ) { - selection.on( 'destroy', control.handleAttachmentDestroy ); - } - }, - - /** - * Open the media select frame to chose an item. - * - * @since 4.9.0 - * @returns {void} - */ - selectMedia: function selectMedia() { - var control = this, selection, mediaFrame, mediaFrameProps; - selection = new wp.media.model.Selection( control.selectedAttachments.models, { - multiple: true - }); - - mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() ); - if ( mediaFrameProps.size ) { - control.displaySettings.set( 'size', mediaFrameProps.size ); - } - mediaFrame = new GalleryDetailsMediaFrame({ - frame: 'select', - text: control.l10n.add_to_widget, - selection: selection, - mimeType: control.mime_type, - selectedDisplaySettings: control.displaySettings, - showDisplaySettings: control.showDisplaySettings, - metadata: mediaFrameProps, - state: 'gallery' - }); - wp.media.frame = mediaFrame; // See wp.media(). - - // Handle selection of a media item. - mediaFrame.on( 'update', function onUpdate( newSelection ) { - var state = mediaFrame.state(), resultSelection; - - resultSelection = newSelection || state.get( 'selection' ); - if ( ! resultSelection ) { - return; - } - - // Copy orderby_random from gallery state. - if ( resultSelection.gallery ) { - control.model.set( control.mapMediaToModelProps( resultSelection.gallery.toJSON() ) ); - } - - // Directly update selectedAttachments to prevent needing to do additional request. - control.selectedAttachments.reset( resultSelection.models ); - - // Update widget instance. - control.model.set( { - ids: _.pluck( resultSelection.models, 'id' ) - } ); - } ); - - mediaFrame.$el.addClass( 'media-widget' ); - mediaFrame.open(); - - if ( selection ) { - selection.on( 'destroy', control.handleAttachmentDestroy ); - } - - /* - * Make sure focus is set inside of modal so that hitting Esc will close - * the modal and not inadvertently cause the widget to collapse in the customizer. - */ - mediaFrame.$el.find( ':focusable:first' ).focus(); - }, - - /** - * Clear the selected attachment when it is deleted in the media select frame. - * - * @since 4.9.0 - * @param {wp.media.models.Attachment} attachment - Attachment. - * @returns {void} - */ - handleAttachmentDestroy: function handleAttachmentDestroy( attachment ) { - var control = this; - control.model.set( { - ids: _.difference( - control.model.get( 'ids' ), - [ attachment.id ] - ) - } ); - } - } ); - - // Exports. - component.controlConstructors.media_gallery = GalleryWidgetControl; - component.modelConstructors.media_gallery = GalleryWidgetModel; - -})( wp.mediaWidgets ); diff --git a/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.min.js b/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.min.js deleted file mode 100644 index 9ef0d05..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-gallery-widget.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(i){"use strict";var e,t,l;l=wp.media.view.MediaFrame.Post.extend({createStates:function(){this.states.add([new wp.media.controller.Library({id:"gallery",title:wp.media.view.l10n.createGalleryTitle,priority:40,toolbar:"main-gallery",filterable:"uploaded",multiple:"add",editable:!0,library:wp.media.query(_.defaults({type:"image"},this.options.library))}),new wp.media.controller.GalleryEdit({library:this.options.selection,editing:this.options.editing,menu:"gallery"}),new wp.media.controller.GalleryAdd])}}),e=i.MediaWidgetModel.extend({}),t=i.MediaWidgetControl.extend({events:_.extend({},i.MediaWidgetControl.prototype.events,{"click .media-widget-gallery-preview":"editMedia"}),initialize:function(e){var t=this;i.MediaWidgetControl.prototype.initialize.call(t,e),_.bindAll(t,"updateSelectedAttachments","handleAttachmentDestroy"),t.selectedAttachments=new wp.media.model.Attachments,t.model.on("change:ids",t.updateSelectedAttachments),t.selectedAttachments.on("change",t.renderPreview),t.selectedAttachments.on("reset",t.renderPreview),t.updateSelectedAttachments(),wp.customize&&wp.customize.previewer&&t.selectedAttachments.on("change",function(){wp.customize.previewer.send("refresh-widget-partial",t.model.get("widget_id"))})},updateSelectedAttachments:function(){var e,t,i,d,a=this;e=a.model.get("ids"),t=_.pluck(a.selectedAttachments.models,"id"),i=_.difference(t,e),_.each(i,function(e){a.selectedAttachments.remove(a.selectedAttachments.get(e))}),_.difference(e,t).length&&(d=wp.media.query({order:"ASC",orderby:"post__in",perPage:-1,post__in:e,query:!0,type:"image"})).more().done(function(){a.selectedAttachments.reset(d.models)})},renderPreview:function(){var e,t,i,d=this;e=d.$el.find(".media-widget-preview"),t=wp.template("wp-media-widget-gallery-preview"),(i=d.previewTemplateProps.toJSON()).attachments={},d.selectedAttachments.each(function(e){i.attachments[e.id]=e.toJSON()}),e.html(t(i))},isSelected:function(){return!this.model.get("error")&&0<this.model.get("ids").length},editMedia:function(){var e,d,t,a=this;e=new wp.media.model.Selection(a.selectedAttachments.models,{multiple:!0}),t=a.mapModelToMediaFrameProps(a.model.toJSON()),e.gallery=new Backbone.Model(t),t.size&&a.displaySettings.set("size",t.size),d=new l({frame:"manage",text:a.l10n.add_to_widget,selection:e,mimeType:a.mime_type,selectedDisplaySettings:a.displaySettings,showDisplaySettings:a.showDisplaySettings,metadata:t,editing:!0,multiple:!0,state:"gallery-edit"}),(wp.media.frame=d).on("update",function(e){var t,i=d.state();(t=e||i.get("selection"))&&(t.gallery&&a.model.set(a.mapMediaToModelProps(t.gallery.toJSON())),a.selectedAttachments.reset(t.models),a.model.set({ids:_.pluck(t.models,"id")}))}),d.$el.addClass("media-widget"),d.open(),e&&e.on("destroy",a.handleAttachmentDestroy)},selectMedia:function(){var e,d,t,a=this;e=new wp.media.model.Selection(a.selectedAttachments.models,{multiple:!0}),(t=a.mapModelToMediaFrameProps(a.model.toJSON())).size&&a.displaySettings.set("size",t.size),d=new l({frame:"select",text:a.l10n.add_to_widget,selection:e,mimeType:a.mime_type,selectedDisplaySettings:a.displaySettings,showDisplaySettings:a.showDisplaySettings,metadata:t,state:"gallery"}),(wp.media.frame=d).on("update",function(e){var t,i=d.state();(t=e||i.get("selection"))&&(t.gallery&&a.model.set(a.mapMediaToModelProps(t.gallery.toJSON())),a.selectedAttachments.reset(t.models),a.model.set({ids:_.pluck(t.models,"id")}))}),d.$el.addClass("media-widget"),d.open(),e&&e.on("destroy",a.handleAttachmentDestroy),d.$el.find(":focusable:first").focus()},handleAttachmentDestroy:function(e){this.model.set({ids:_.difference(this.model.get("ids"),[e.id])})}}),i.controlConstructors.media_gallery=t,i.modelConstructors.media_gallery=e}(wp.mediaWidgets);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/media-image-widget.js b/srcs/wordpress/wp-admin/js/widgets/media-image-widget.js deleted file mode 100644 index 3ea4f9b..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-image-widget.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @output wp-admin/js/widgets/media-image-widget.js - */ - -/* eslint consistent-this: [ "error", "control" ] */ -(function( component, $ ) { - 'use strict'; - - var ImageWidgetModel, ImageWidgetControl; - - /** - * Image widget model. - * - * See WP_Widget_Media_Image::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.modelConstructors.media_image - * @augments wp.mediaWidgets.MediaWidgetModel - */ - ImageWidgetModel = component.MediaWidgetModel.extend({}); - - /** - * Image widget control. - * - * See WP_Widget_Media_Image::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.controlConstructors.media_audio - * @augments wp.mediaWidgets.MediaWidgetControl - */ - ImageWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_image.prototype */{ - - /** - * View events. - * - * @type {object} - */ - events: _.extend( {}, component.MediaWidgetControl.prototype.events, { - 'click .media-widget-preview.populated': 'editMedia' - } ), - - /** - * Render preview. - * - * @returns {void} - */ - renderPreview: function renderPreview() { - var control = this, previewContainer, previewTemplate, fieldsContainer, fieldsTemplate, linkInput; - if ( ! control.model.get( 'attachment_id' ) && ! control.model.get( 'url' ) ) { - return; - } - - previewContainer = control.$el.find( '.media-widget-preview' ); - previewTemplate = wp.template( 'wp-media-widget-image-preview' ); - previewContainer.html( previewTemplate( control.previewTemplateProps.toJSON() ) ); - previewContainer.addClass( 'populated' ); - - linkInput = control.$el.find( '.link' ); - if ( ! linkInput.is( document.activeElement ) ) { - fieldsContainer = control.$el.find( '.media-widget-fields' ); - fieldsTemplate = wp.template( 'wp-media-widget-image-fields' ); - fieldsContainer.html( fieldsTemplate( control.previewTemplateProps.toJSON() ) ); - } - }, - - /** - * Open the media image-edit frame to modify the selected item. - * - * @returns {void} - */ - editMedia: function editMedia() { - var control = this, mediaFrame, updateCallback, defaultSync, metadata; - - metadata = control.mapModelToMediaFrameProps( control.model.toJSON() ); - - // Needed or else none will not be selected if linkUrl is not also empty. - if ( 'none' === metadata.link ) { - metadata.linkUrl = ''; - } - - // Set up the media frame. - mediaFrame = wp.media({ - frame: 'image', - state: 'image-details', - metadata: metadata - }); - mediaFrame.$el.addClass( 'media-widget' ); - - updateCallback = function() { - var mediaProps, linkType; - - // Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview. - mediaProps = mediaFrame.state().attributes.image.toJSON(); - linkType = mediaProps.link; - mediaProps.link = mediaProps.linkUrl; - control.selectedAttachment.set( mediaProps ); - control.displaySettings.set( 'link', linkType ); - - control.model.set( _.extend( - control.mapMediaToModelProps( mediaProps ), - { error: false } - ) ); - }; - - mediaFrame.state( 'image-details' ).on( 'update', updateCallback ); - mediaFrame.state( 'replace-image' ).on( 'replace', updateCallback ); - - // Disable syncing of attachment changes back to server. See <https://core.trac.wordpress.org/ticket/40403>. - defaultSync = wp.media.model.Attachment.prototype.sync; - wp.media.model.Attachment.prototype.sync = function rejectedSync() { - return $.Deferred().rejectWith( this ).promise(); - }; - mediaFrame.on( 'close', function onClose() { - mediaFrame.detach(); - wp.media.model.Attachment.prototype.sync = defaultSync; - }); - - mediaFrame.open(); - }, - - /** - * Get props which are merged on top of the model when an embed is chosen (as opposed to an attachment). - * - * @returns {Object} Reset/override props. - */ - getEmbedResetProps: function getEmbedResetProps() { - return _.extend( - component.MediaWidgetControl.prototype.getEmbedResetProps.call( this ), - { - size: 'full', - width: 0, - height: 0 - } - ); - }, - - /** - * Get the instance props from the media selection frame. - * - * Prevent the image_title attribute from being initially set when adding an image from the media library. - * - * @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame. - * @returns {Object} Props. - */ - getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) { - var control = this; - return _.omit( - component.MediaWidgetControl.prototype.getModelPropsFromMediaFrame.call( control, mediaFrame ), - 'image_title' - ); - }, - - /** - * Map model props to preview template props. - * - * @returns {Object} Preview template props. - */ - mapModelToPreviewTemplateProps: function mapModelToPreviewTemplateProps() { - var control = this, previewTemplateProps, url; - url = control.model.get( 'url' ); - previewTemplateProps = component.MediaWidgetControl.prototype.mapModelToPreviewTemplateProps.call( control ); - previewTemplateProps.currentFilename = url ? url.replace( /\?.*$/, '' ).replace( /^.+\//, '' ) : ''; - previewTemplateProps.link_url = control.model.get( 'link_url' ); - return previewTemplateProps; - } - }); - - // Exports. - component.controlConstructors.media_image = ImageWidgetControl; - component.modelConstructors.media_image = ImageWidgetModel; - -})( wp.mediaWidgets, jQuery ); diff --git a/srcs/wordpress/wp-admin/js/widgets/media-image-widget.min.js b/srcs/wordpress/wp-admin/js/widgets/media-image-widget.min.js deleted file mode 100644 index c5165c3..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-image-widget.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,d){"use strict";var e,t;e=a.MediaWidgetModel.extend({}),t=a.MediaWidgetControl.extend({events:_.extend({},a.MediaWidgetControl.prototype.events,{"click .media-widget-preview.populated":"editMedia"}),renderPreview:function(){var e,t,i,a,o=this;(o.model.get("attachment_id")||o.model.get("url"))&&(e=o.$el.find(".media-widget-preview"),t=wp.template("wp-media-widget-image-preview"),e.html(t(o.previewTemplateProps.toJSON())),e.addClass("populated"),o.$el.find(".link").is(document.activeElement)||(i=o.$el.find(".media-widget-fields"),a=wp.template("wp-media-widget-image-fields"),i.html(a(o.previewTemplateProps.toJSON()))))},editMedia:function(){var i,e,t,a,o=this;"none"===(a=o.mapModelToMediaFrameProps(o.model.toJSON())).link&&(a.linkUrl=""),(i=wp.media({frame:"image",state:"image-details",metadata:a})).$el.addClass("media-widget"),e=function(){var e,t;t=(e=i.state().attributes.image.toJSON()).link,e.link=e.linkUrl,o.selectedAttachment.set(e),o.displaySettings.set("link",t),o.model.set(_.extend(o.mapMediaToModelProps(e),{error:!1}))},i.state("image-details").on("update",e),i.state("replace-image").on("replace",e),t=wp.media.model.Attachment.prototype.sync,wp.media.model.Attachment.prototype.sync=function(){return d.Deferred().rejectWith(this).promise()},i.on("close",function(){i.detach(),wp.media.model.Attachment.prototype.sync=t}),i.open()},getEmbedResetProps:function(){return _.extend(a.MediaWidgetControl.prototype.getEmbedResetProps.call(this),{size:"full",width:0,height:0})},getModelPropsFromMediaFrame:function(e){return _.omit(a.MediaWidgetControl.prototype.getModelPropsFromMediaFrame.call(this,e),"image_title")},mapModelToPreviewTemplateProps:function(){var e,t,i=this;return t=i.model.get("url"),(e=a.MediaWidgetControl.prototype.mapModelToPreviewTemplateProps.call(i)).currentFilename=t?t.replace(/\?.*$/,"").replace(/^.+\//,""):"",e.link_url=i.model.get("link_url"),e}}),a.controlConstructors.media_image=t,a.modelConstructors.media_image=e}(wp.mediaWidgets,jQuery);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/media-video-widget.js b/srcs/wordpress/wp-admin/js/widgets/media-video-widget.js deleted file mode 100644 index b716cce..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-video-widget.js +++ /dev/null @@ -1,256 +0,0 @@ -/** - * @output wp-admin/js/widgets/media-video-widget.js - */ - -/* eslint consistent-this: [ "error", "control" ] */ -(function( component ) { - 'use strict'; - - var VideoWidgetModel, VideoWidgetControl, VideoDetailsMediaFrame; - - /** - * Custom video details frame that removes the replace-video state. - * - * @class wp.mediaWidgets.controlConstructors~VideoDetailsMediaFrame - * @augments wp.media.view.MediaFrame.VideoDetails - * - * @private - */ - VideoDetailsMediaFrame = wp.media.view.MediaFrame.VideoDetails.extend(/** @lends wp.mediaWidgets.controlConstructors~VideoDetailsMediaFrame.prototype */{ - - /** - * Create the default states. - * - * @returns {void} - */ - createStates: function createStates() { - this.states.add([ - new wp.media.controller.VideoDetails({ - media: this.media - }), - - new wp.media.controller.MediaLibrary({ - type: 'video', - id: 'add-video-source', - title: wp.media.view.l10n.videoAddSourceTitle, - toolbar: 'add-video-source', - media: this.media, - menu: false - }), - - new wp.media.controller.MediaLibrary({ - type: 'text', - id: 'add-track', - title: wp.media.view.l10n.videoAddTrackTitle, - toolbar: 'add-track', - media: this.media, - menu: 'video-details' - }) - ]); - } - }); - - /** - * Video widget model. - * - * See WP_Widget_Video::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.modelConstructors.media_video - * @augments wp.mediaWidgets.MediaWidgetModel - */ - VideoWidgetModel = component.MediaWidgetModel.extend({}); - - /** - * Video widget control. - * - * See WP_Widget_Video::enqueue_admin_scripts() for amending prototype from PHP exports. - * - * @class wp.mediaWidgets.controlConstructors.media_video - * @augments wp.mediaWidgets.MediaWidgetControl - */ - VideoWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_video.prototype */{ - - /** - * Show display settings. - * - * @type {boolean} - */ - showDisplaySettings: false, - - /** - * Cache of oembed responses. - * - * @type {Object} - */ - oembedResponses: {}, - - /** - * Map model props to media frame props. - * - * @param {Object} modelProps - Model props. - * @returns {Object} Media frame props. - */ - mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { - var control = this, mediaFrameProps; - mediaFrameProps = component.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call( control, modelProps ); - mediaFrameProps.link = 'embed'; - return mediaFrameProps; - }, - - /** - * Fetches embed data for external videos. - * - * @returns {void} - */ - fetchEmbed: function fetchEmbed() { - var control = this, url; - url = control.model.get( 'url' ); - - // If we already have a local cache of the embed response, return. - if ( control.oembedResponses[ url ] ) { - return; - } - - // If there is an in-flight embed request, abort it. - if ( control.fetchEmbedDfd && 'pending' === control.fetchEmbedDfd.state() ) { - control.fetchEmbedDfd.abort(); - } - - control.fetchEmbedDfd = wp.apiRequest({ - url: wp.media.view.settings.oEmbedProxyUrl, - data: { - url: control.model.get( 'url' ), - maxwidth: control.model.get( 'width' ), - maxheight: control.model.get( 'height' ), - discover: false - }, - type: 'GET', - dataType: 'json', - context: control - }); - - control.fetchEmbedDfd.done( function( response ) { - control.oembedResponses[ url ] = response; - control.renderPreview(); - }); - - control.fetchEmbedDfd.fail( function() { - control.oembedResponses[ url ] = null; - }); - }, - - /** - * Whether a url is a supported external host. - * - * @deprecated since 4.9. - * - * @returns {boolean} Whether url is a supported video host. - */ - isHostedVideo: function isHostedVideo() { - return true; - }, - - /** - * Render preview. - * - * @returns {void} - */ - renderPreview: function renderPreview() { - var control = this, previewContainer, previewTemplate, attachmentId, attachmentUrl, poster, html = '', isOEmbed = false, mime, error, urlParser, matches; - attachmentId = control.model.get( 'attachment_id' ); - attachmentUrl = control.model.get( 'url' ); - error = control.model.get( 'error' ); - - if ( ! attachmentId && ! attachmentUrl ) { - return; - } - - // Verify the selected attachment mime is supported. - mime = control.selectedAttachment.get( 'mime' ); - if ( mime && attachmentId ) { - if ( ! _.contains( _.values( wp.media.view.settings.embedMimes ), mime ) ) { - error = 'unsupported_file_type'; - } - } else if ( ! attachmentId ) { - urlParser = document.createElement( 'a' ); - urlParser.href = attachmentUrl; - matches = urlParser.pathname.toLowerCase().match( /\.(\w+)$/ ); - if ( matches ) { - if ( ! _.contains( _.keys( wp.media.view.settings.embedMimes ), matches[1] ) ) { - error = 'unsupported_file_type'; - } - } else { - isOEmbed = true; - } - } - - if ( isOEmbed ) { - control.fetchEmbed(); - if ( control.oembedResponses[ attachmentUrl ] ) { - poster = control.oembedResponses[ attachmentUrl ].thumbnail_url; - html = control.oembedResponses[ attachmentUrl ].html.replace( /\swidth="\d+"/, ' width="100%"' ).replace( /\sheight="\d+"/, '' ); - } - } - - previewContainer = control.$el.find( '.media-widget-preview' ); - previewTemplate = wp.template( 'wp-media-widget-video-preview' ); - - previewContainer.html( previewTemplate({ - model: { - attachment_id: attachmentId, - html: html, - src: attachmentUrl, - poster: poster - }, - is_oembed: isOEmbed, - error: error - })); - wp.mediaelement.initialize(); - }, - - /** - * Open the media image-edit frame to modify the selected item. - * - * @returns {void} - */ - editMedia: function editMedia() { - var control = this, mediaFrame, metadata, updateCallback; - - metadata = control.mapModelToMediaFrameProps( control.model.toJSON() ); - - // Set up the media frame. - mediaFrame = new VideoDetailsMediaFrame({ - frame: 'video', - state: 'video-details', - metadata: metadata - }); - wp.media.frame = mediaFrame; - mediaFrame.$el.addClass( 'media-widget' ); - - updateCallback = function( mediaFrameProps ) { - - // Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview. - control.selectedAttachment.set( mediaFrameProps ); - - control.model.set( _.extend( - _.omit( control.model.defaults(), 'title' ), - control.mapMediaToModelProps( mediaFrameProps ), - { error: false } - ) ); - }; - - mediaFrame.state( 'video-details' ).on( 'update', updateCallback ); - mediaFrame.state( 'replace-video' ).on( 'replace', updateCallback ); - mediaFrame.on( 'close', function() { - mediaFrame.detach(); - }); - - mediaFrame.open(); - } - }); - - // Exports. - component.controlConstructors.media_video = VideoWidgetControl; - component.modelConstructors.media_video = VideoWidgetModel; - -})( wp.mediaWidgets ); diff --git a/srcs/wordpress/wp-admin/js/widgets/media-video-widget.min.js b/srcs/wordpress/wp-admin/js/widgets/media-video-widget.min.js deleted file mode 100644 index 9d3704c..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-video-widget.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(d){"use strict";var e,t,o;o=wp.media.view.MediaFrame.VideoDetails.extend({createStates:function(){this.states.add([new wp.media.controller.VideoDetails({media:this.media}),new wp.media.controller.MediaLibrary({type:"video",id:"add-video-source",title:wp.media.view.l10n.videoAddSourceTitle,toolbar:"add-video-source",media:this.media,menu:!1}),new wp.media.controller.MediaLibrary({type:"text",id:"add-track",title:wp.media.view.l10n.videoAddTrackTitle,toolbar:"add-track",media:this.media,menu:"video-details"})])}}),e=d.MediaWidgetModel.extend({}),t=d.MediaWidgetControl.extend({showDisplaySettings:!1,oembedResponses:{},mapModelToMediaFrameProps:function(e){var t;return(t=d.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call(this,e)).link="embed",t},fetchEmbed:function(){var t,d=this;t=d.model.get("url"),d.oembedResponses[t]||(d.fetchEmbedDfd&&"pending"===d.fetchEmbedDfd.state()&&d.fetchEmbedDfd.abort(),d.fetchEmbedDfd=wp.apiRequest({url:wp.media.view.settings.oEmbedProxyUrl,data:{url:d.model.get("url"),maxwidth:d.model.get("width"),maxheight:d.model.get("height"),discover:!1},type:"GET",dataType:"json",context:d}),d.fetchEmbedDfd.done(function(e){d.oembedResponses[t]=e,d.renderPreview()}),d.fetchEmbedDfd.fail(function(){d.oembedResponses[t]=null}))},isHostedVideo:function(){return!0},renderPreview:function(){var e,t,d,i,o,a,s,m,n,r=this,l="",p=!1;d=r.model.get("attachment_id"),i=r.model.get("url"),s=r.model.get("error"),(d||i)&&((a=r.selectedAttachment.get("mime"))&&d?_.contains(_.values(wp.media.view.settings.embedMimes),a)||(s="unsupported_file_type"):d||((m=document.createElement("a")).href=i,(n=m.pathname.toLowerCase().match(/\.(\w+)$/))?_.contains(_.keys(wp.media.view.settings.embedMimes),n[1])||(s="unsupported_file_type"):p=!0),p&&(r.fetchEmbed(),r.oembedResponses[i]&&(o=r.oembedResponses[i].thumbnail_url,l=r.oembedResponses[i].html.replace(/\swidth="\d+"/,' width="100%"').replace(/\sheight="\d+"/,""))),e=r.$el.find(".media-widget-preview"),t=wp.template("wp-media-widget-video-preview"),e.html(t({model:{attachment_id:d,html:l,src:i,poster:o},is_oembed:p,error:s})),wp.mediaelement.initialize())},editMedia:function(){var e,t,d,i=this;t=i.mapModelToMediaFrameProps(i.model.toJSON()),e=new o({frame:"video",state:"video-details",metadata:t}),(wp.media.frame=e).$el.addClass("media-widget"),d=function(e){i.selectedAttachment.set(e),i.model.set(_.extend(_.omit(i.model.defaults(),"title"),i.mapMediaToModelProps(e),{error:!1}))},e.state("video-details").on("update",d),e.state("replace-video").on("replace",d),e.on("close",function(){e.detach()}),e.open()}}),d.controlConstructors.media_video=t,d.modelConstructors.media_video=e}(wp.mediaWidgets);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/media-widgets.js b/srcs/wordpress/wp-admin/js/widgets/media-widgets.js deleted file mode 100644 index 9a243a9..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-widgets.js +++ /dev/null @@ -1,1330 +0,0 @@ -/** - * @output wp-admin/js/widgets/media-widgets.js - */ - -/* eslint consistent-this: [ "error", "control" ] */ - -/** - * @namespace wp.mediaWidgets - * @memberOf wp - */ -wp.mediaWidgets = ( function( $ ) { - 'use strict'; - - var component = {}; - - /** - * Widget control (view) constructors, mapping widget id_base to subclass of MediaWidgetControl. - * - * Media widgets register themselves by assigning subclasses of MediaWidgetControl onto this object by widget ID base. - * - * @memberOf wp.mediaWidgets - * - * @type {Object.<string, wp.mediaWidgets.MediaWidgetModel>} - */ - component.controlConstructors = {}; - - /** - * Widget model constructors, mapping widget id_base to subclass of MediaWidgetModel. - * - * Media widgets register themselves by assigning subclasses of MediaWidgetControl onto this object by widget ID base. - * - * @memberOf wp.mediaWidgets - * - * @type {Object.<string, wp.mediaWidgets.MediaWidgetModel>} - */ - component.modelConstructors = {}; - - component.PersistentDisplaySettingsLibrary = wp.media.controller.Library.extend(/** @lends wp.mediaWidgets.PersistentDisplaySettingsLibrary.prototype */{ - - /** - * Library which persists the customized display settings across selections. - * - * @constructs wp.mediaWidgets.PersistentDisplaySettingsLibrary - * @augments wp.media.controller.Library - * - * @param {Object} options - Options. - * - * @returns {void} - */ - initialize: function initialize( options ) { - _.bindAll( this, 'handleDisplaySettingChange' ); - wp.media.controller.Library.prototype.initialize.call( this, options ); - }, - - /** - * Sync changes to the current display settings back into the current customized. - * - * @param {Backbone.Model} displaySettings - Modified display settings. - * @returns {void} - */ - handleDisplaySettingChange: function handleDisplaySettingChange( displaySettings ) { - this.get( 'selectedDisplaySettings' ).set( displaySettings.attributes ); - }, - - /** - * Get the display settings model. - * - * Model returned is updated with the current customized display settings, - * and an event listener is added so that changes made to the settings - * will sync back into the model storing the session's customized display - * settings. - * - * @param {Backbone.Model} model - Display settings model. - * @returns {Backbone.Model} Display settings model. - */ - display: function getDisplaySettingsModel( model ) { - var display, selectedDisplaySettings = this.get( 'selectedDisplaySettings' ); - display = wp.media.controller.Library.prototype.display.call( this, model ); - - display.off( 'change', this.handleDisplaySettingChange ); // Prevent duplicated event handlers. - display.set( selectedDisplaySettings.attributes ); - if ( 'custom' === selectedDisplaySettings.get( 'link_type' ) ) { - display.linkUrl = selectedDisplaySettings.get( 'link_url' ); - } - display.on( 'change', this.handleDisplaySettingChange ); - return display; - } - }); - - /** - * Extended view for managing the embed UI. - * - * @class wp.mediaWidgets.MediaEmbedView - * @augments wp.media.view.Embed - */ - component.MediaEmbedView = wp.media.view.Embed.extend(/** @lends wp.mediaWidgets.MediaEmbedView.prototype */{ - - /** - * Initialize. - * - * @since 4.9.0 - * - * @param {object} options - Options. - * @returns {void} - */ - initialize: function( options ) { - var view = this, embedController; // eslint-disable-line consistent-this - wp.media.view.Embed.prototype.initialize.call( view, options ); - if ( 'image' !== view.controller.options.mimeType ) { - embedController = view.controller.states.get( 'embed' ); - embedController.off( 'scan', embedController.scanImage, embedController ); - } - }, - - /** - * Refresh embed view. - * - * Forked override of {wp.media.view.Embed#refresh()} to suppress irrelevant "link text" field. - * - * @returns {void} - */ - refresh: function refresh() { - /** - * @class wp.mediaWidgets~Constructor - */ - var Constructor; - - if ( 'image' === this.controller.options.mimeType ) { - Constructor = wp.media.view.EmbedImage; - } else { - - // This should be eliminated once #40450 lands of when this is merged into core. - Constructor = wp.media.view.EmbedLink.extend(/** @lends wp.mediaWidgets~Constructor.prototype */{ - - /** - * Set the disabled state on the Add to Widget button. - * - * @param {boolean} disabled - Disabled. - * @returns {void} - */ - setAddToWidgetButtonDisabled: function setAddToWidgetButtonDisabled( disabled ) { - this.views.parent.views.parent.views.get( '.media-frame-toolbar' )[0].$el.find( '.media-button-select' ).prop( 'disabled', disabled ); - }, - - /** - * Set or clear an error notice. - * - * @param {string} notice - Notice. - * @returns {void} - */ - setErrorNotice: function setErrorNotice( notice ) { - var embedLinkView = this, noticeContainer; // eslint-disable-line consistent-this - - noticeContainer = embedLinkView.views.parent.$el.find( '> .notice:first-child' ); - if ( ! notice ) { - if ( noticeContainer.length ) { - noticeContainer.slideUp( 'fast' ); - } - } else { - if ( ! noticeContainer.length ) { - noticeContainer = $( '<div class="media-widget-embed-notice notice notice-error notice-alt"></div>' ); - noticeContainer.hide(); - embedLinkView.views.parent.$el.prepend( noticeContainer ); - } - noticeContainer.empty(); - noticeContainer.append( $( '<p>', { - html: notice - })); - noticeContainer.slideDown( 'fast' ); - } - }, - - /** - * Update oEmbed. - * - * @since 4.9.0 - * - * @returns {void} - */ - updateoEmbed: function() { - var embedLinkView = this, url; // eslint-disable-line consistent-this - - url = embedLinkView.model.get( 'url' ); - - // Abort if the URL field was emptied out. - if ( ! url ) { - embedLinkView.setErrorNotice( '' ); - embedLinkView.setAddToWidgetButtonDisabled( true ); - return; - } - - if ( ! url.match( /^(http|https):\/\/.+\// ) ) { - embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' ); - embedLinkView.setAddToWidgetButtonDisabled( true ); - } - - wp.media.view.EmbedLink.prototype.updateoEmbed.call( embedLinkView ); - }, - - /** - * Fetch media. - * - * @returns {void} - */ - fetch: function() { - var embedLinkView = this, fetchSuccess, matches, fileExt, urlParser, url, re, youTubeEmbedMatch; // eslint-disable-line consistent-this - url = embedLinkView.model.get( 'url' ); - - if ( embedLinkView.dfd && 'pending' === embedLinkView.dfd.state() ) { - embedLinkView.dfd.abort(); - } - - fetchSuccess = function( response ) { - embedLinkView.renderoEmbed({ - data: { - body: response - } - }); - - embedLinkView.controller.$el.find( '#embed-url-field' ).removeClass( 'invalid' ); - embedLinkView.setErrorNotice( '' ); - embedLinkView.setAddToWidgetButtonDisabled( false ); - }; - - urlParser = document.createElement( 'a' ); - urlParser.href = url; - matches = urlParser.pathname.toLowerCase().match( /\.(\w+)$/ ); - if ( matches ) { - fileExt = matches[1]; - if ( ! wp.media.view.settings.embedMimes[ fileExt ] ) { - embedLinkView.renderFail(); - } else if ( 0 !== wp.media.view.settings.embedMimes[ fileExt ].indexOf( embedLinkView.controller.options.mimeType ) ) { - embedLinkView.renderFail(); - } else { - fetchSuccess( '<!--success-->' ); - } - return; - } - - // Support YouTube embed links. - re = /https?:\/\/www\.youtube\.com\/embed\/([^/]+)/; - youTubeEmbedMatch = re.exec( url ); - if ( youTubeEmbedMatch ) { - url = 'https://www.youtube.com/watch?v=' + youTubeEmbedMatch[ 1 ]; - // silently change url to proper oembed-able version. - embedLinkView.model.attributes.url = url; - } - - embedLinkView.dfd = wp.apiRequest({ - url: wp.media.view.settings.oEmbedProxyUrl, - data: { - url: url, - maxwidth: embedLinkView.model.get( 'width' ), - maxheight: embedLinkView.model.get( 'height' ), - discover: false - }, - type: 'GET', - dataType: 'json', - context: embedLinkView - }); - - embedLinkView.dfd.done( function( response ) { - if ( embedLinkView.controller.options.mimeType !== response.type ) { - embedLinkView.renderFail(); - return; - } - fetchSuccess( response.html ); - }); - embedLinkView.dfd.fail( _.bind( embedLinkView.renderFail, embedLinkView ) ); - }, - - /** - * Handle render failure. - * - * Overrides the {EmbedLink#renderFail()} method to prevent showing the "Link Text" field. - * The element is getting display:none in the stylesheet, but the underlying method uses - * uses {jQuery.fn.show()} which adds an inline style. This avoids the need for !important. - * - * @returns {void} - */ - renderFail: function renderFail() { - var embedLinkView = this; // eslint-disable-line consistent-this - embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' ); - embedLinkView.setErrorNotice( embedLinkView.controller.options.invalidEmbedTypeError || 'ERROR' ); - embedLinkView.setAddToWidgetButtonDisabled( true ); - } - }); - } - - this.settings( new Constructor({ - controller: this.controller, - model: this.model.props, - priority: 40 - })); - } - }); - - /** - * Custom media frame for selecting uploaded media or providing media by URL. - * - * @class wp.mediaWidgets.MediaFrameSelect - * @augments wp.media.view.MediaFrame.Post - */ - component.MediaFrameSelect = wp.media.view.MediaFrame.Post.extend(/** @lends wp.mediaWidgets.MediaFrameSelect.prototype */{ - - /** - * Create the default states. - * - * @returns {void} - */ - createStates: function createStates() { - var mime = this.options.mimeType, specificMimes = []; - _.each( wp.media.view.settings.embedMimes, function( embedMime ) { - if ( 0 === embedMime.indexOf( mime ) ) { - specificMimes.push( embedMime ); - } - }); - if ( specificMimes.length > 0 ) { - mime = specificMimes; - } - - this.states.add([ - - // Main states. - new component.PersistentDisplaySettingsLibrary({ - id: 'insert', - title: this.options.title, - selection: this.options.selection, - priority: 20, - toolbar: 'main-insert', - filterable: 'dates', - library: wp.media.query({ - type: mime - }), - multiple: false, - editable: true, - - selectedDisplaySettings: this.options.selectedDisplaySettings, - displaySettings: _.isUndefined( this.options.showDisplaySettings ) ? true : this.options.showDisplaySettings, - displayUserSettings: false // We use the display settings from the current/default widget instance props. - }), - - new wp.media.controller.EditImage({ model: this.options.editImage }), - - // Embed states. - new wp.media.controller.Embed({ - metadata: this.options.metadata, - type: 'image' === this.options.mimeType ? 'image' : 'link', - invalidEmbedTypeError: this.options.invalidEmbedTypeError - }) - ]); - }, - - /** - * Main insert toolbar. - * - * Forked override of {wp.media.view.MediaFrame.Post#mainInsertToolbar()} to override text. - * - * @param {wp.Backbone.View} view - Toolbar view. - * @this {wp.media.controller.Library} - * @returns {void} - */ - mainInsertToolbar: function mainInsertToolbar( view ) { - var controller = this; // eslint-disable-line consistent-this - view.set( 'insert', { - style: 'primary', - priority: 80, - text: controller.options.text, // The whole reason for the fork. - requires: { selection: true }, - - /** - * Handle click. - * - * @ignore - * - * @fires wp.media.controller.State#insert() - * @returns {void} - */ - click: function onClick() { - var state = controller.state(), - selection = state.get( 'selection' ); - - controller.close(); - state.trigger( 'insert', selection ).reset(); - } - }); - }, - - /** - * Main embed toolbar. - * - * Forked override of {wp.media.view.MediaFrame.Post#mainEmbedToolbar()} to override text. - * - * @param {wp.Backbone.View} toolbar - Toolbar view. - * @this {wp.media.controller.Library} - * @returns {void} - */ - mainEmbedToolbar: function mainEmbedToolbar( toolbar ) { - toolbar.view = new wp.media.view.Toolbar.Embed({ - controller: this, - text: this.options.text, - event: 'insert' - }); - }, - - /** - * Embed content. - * - * Forked override of {wp.media.view.MediaFrame.Post#embedContent()} to suppress irrelevant "link text" field. - * - * @returns {void} - */ - embedContent: function embedContent() { - var view = new component.MediaEmbedView({ - controller: this, - model: this.state() - }).render(); - - this.content.set( view ); - } - }); - - component.MediaWidgetControl = Backbone.View.extend(/** @lends wp.mediaWidgets.MediaWidgetControl.prototype */{ - - /** - * Translation strings. - * - * The mapping of translation strings is handled by media widget subclasses, - * exported from PHP to JS such as is done in WP_Widget_Media_Image::enqueue_admin_scripts(). - * - * @type {Object} - */ - l10n: { - add_to_widget: '{{add_to_widget}}', - add_media: '{{add_media}}' - }, - - /** - * Widget ID base. - * - * This may be defined by the subclass. It may be exported from PHP to JS - * such as is done in WP_Widget_Media_Image::enqueue_admin_scripts(). If not, - * it will attempt to be discovered by looking to see if this control - * instance extends each member of component.controlConstructors, and if - * it does extend one, will use the key as the id_base. - * - * @type {string} - */ - id_base: '', - - /** - * Mime type. - * - * This must be defined by the subclass. It may be exported from PHP to JS - * such as is done in WP_Widget_Media_Image::enqueue_admin_scripts(). - * - * @type {string} - */ - mime_type: '', - - /** - * View events. - * - * @type {Object} - */ - events: { - 'click .notice-missing-attachment a': 'handleMediaLibraryLinkClick', - 'click .select-media': 'selectMedia', - 'click .placeholder': 'selectMedia', - 'click .edit-media': 'editMedia' - }, - - /** - * Show display settings. - * - * @type {boolean} - */ - showDisplaySettings: true, - - /** - * Media Widget Control. - * - * @constructs wp.mediaWidgets.MediaWidgetControl - * @augments Backbone.View - * @abstract - * - * @param {Object} options - Options. - * @param {Backbone.Model} options.model - Model. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. - * - * @returns {void} - */ - initialize: function initialize( options ) { - var control = this; - - Backbone.View.prototype.initialize.call( control, options ); - - if ( ! ( control.model instanceof component.MediaWidgetModel ) ) { - throw new Error( 'Missing options.model' ); - } - if ( ! options.el ) { - throw new Error( 'Missing options.el' ); - } - if ( ! options.syncContainer ) { - throw new Error( 'Missing options.syncContainer' ); - } - - control.syncContainer = options.syncContainer; - - control.$el.addClass( 'media-widget-control' ); - - // Allow methods to be passed in with control context preserved. - _.bindAll( control, 'syncModelToInputs', 'render', 'updateSelectedAttachment', 'renderPreview' ); - - if ( ! control.id_base ) { - _.find( component.controlConstructors, function( Constructor, idBase ) { - if ( control instanceof Constructor ) { - control.id_base = idBase; - return true; - } - return false; - }); - if ( ! control.id_base ) { - throw new Error( 'Missing id_base.' ); - } - } - - // Track attributes needed to renderPreview in it's own model. - control.previewTemplateProps = new Backbone.Model( control.mapModelToPreviewTemplateProps() ); - - // Re-render the preview when the attachment changes. - control.selectedAttachment = new wp.media.model.Attachment(); - control.renderPreview = _.debounce( control.renderPreview ); - control.listenTo( control.previewTemplateProps, 'change', control.renderPreview ); - - // Make sure a copy of the selected attachment is always fetched. - control.model.on( 'change:attachment_id', control.updateSelectedAttachment ); - control.model.on( 'change:url', control.updateSelectedAttachment ); - control.updateSelectedAttachment(); - - /* - * Sync the widget instance model attributes onto the hidden inputs that widgets currently use to store the state. - * In the future, when widgets are JS-driven, the underlying widget instance data should be exposed as a model - * from the start, without having to sync with hidden fields. See <https://core.trac.wordpress.org/ticket/33507>. - */ - control.listenTo( control.model, 'change', control.syncModelToInputs ); - control.listenTo( control.model, 'change', control.syncModelToPreviewProps ); - control.listenTo( control.model, 'change', control.render ); - - // Update the title. - control.$el.on( 'input change', '.title', function updateTitle() { - control.model.set({ - title: $.trim( $( this ).val() ) - }); - }); - - // Update link_url attribute. - control.$el.on( 'input change', '.link', function updateLinkUrl() { - var linkUrl = $.trim( $( this ).val() ), linkType = 'custom'; - if ( control.selectedAttachment.get( 'linkUrl' ) === linkUrl || control.selectedAttachment.get( 'link' ) === linkUrl ) { - linkType = 'post'; - } else if ( control.selectedAttachment.get( 'url' ) === linkUrl ) { - linkType = 'file'; - } - control.model.set( { - link_url: linkUrl, - link_type: linkType - }); - - // Update display settings for the next time the user opens to select from the media library. - control.displaySettings.set( { - link: linkType, - linkUrl: linkUrl - }); - }); - - /* - * Copy current display settings from the widget model to serve as basis - * of customized display settings for the current media frame session. - * Changes to display settings will be synced into this model, and - * when a new selection is made, the settings from this will be synced - * into that AttachmentDisplay's model to persist the setting changes. - */ - control.displaySettings = new Backbone.Model( _.pick( - control.mapModelToMediaFrameProps( - _.extend( control.model.defaults(), control.model.toJSON() ) - ), - _.keys( wp.media.view.settings.defaultProps ) - ) ); - }, - - /** - * Update the selected attachment if necessary. - * - * @returns {void} - */ - updateSelectedAttachment: function updateSelectedAttachment() { - var control = this, attachment; - - if ( 0 === control.model.get( 'attachment_id' ) ) { - control.selectedAttachment.clear(); - control.model.set( 'error', false ); - } else if ( control.model.get( 'attachment_id' ) !== control.selectedAttachment.get( 'id' ) ) { - attachment = new wp.media.model.Attachment({ - id: control.model.get( 'attachment_id' ) - }); - attachment.fetch() - .done( function done() { - control.model.set( 'error', false ); - control.selectedAttachment.set( attachment.toJSON() ); - }) - .fail( function fail() { - control.model.set( 'error', 'missing_attachment' ); - }); - } - }, - - /** - * Sync the model attributes to the hidden inputs, and update previewTemplateProps. - * - * @returns {void} - */ - syncModelToPreviewProps: function syncModelToPreviewProps() { - var control = this; - control.previewTemplateProps.set( control.mapModelToPreviewTemplateProps() ); - }, - - /** - * Sync the model attributes to the hidden inputs, and update previewTemplateProps. - * - * @returns {void} - */ - syncModelToInputs: function syncModelToInputs() { - var control = this; - control.syncContainer.find( '.media-widget-instance-property' ).each( function() { - var input = $( this ), value, propertyName; - propertyName = input.data( 'property' ); - value = control.model.get( propertyName ); - if ( _.isUndefined( value ) ) { - return; - } - - if ( 'array' === control.model.schema[ propertyName ].type && _.isArray( value ) ) { - value = value.join( ',' ); - } else if ( 'boolean' === control.model.schema[ propertyName ].type ) { - value = value ? '1' : ''; // Because in PHP, strval( true ) === '1' && strval( false ) === ''. - } else { - value = String( value ); - } - - if ( input.val() !== value ) { - input.val( value ); - input.trigger( 'change' ); - } - }); - }, - - /** - * Get template. - * - * @returns {Function} Template. - */ - template: function template() { - var control = this; - if ( ! $( '#tmpl-widget-media-' + control.id_base + '-control' ).length ) { - throw new Error( 'Missing widget control template for ' + control.id_base ); - } - return wp.template( 'widget-media-' + control.id_base + '-control' ); - }, - - /** - * Render template. - * - * @returns {void} - */ - render: function render() { - var control = this, titleInput; - - if ( ! control.templateRendered ) { - control.$el.html( control.template()( control.model.toJSON() ) ); - control.renderPreview(); // Hereafter it will re-render when control.selectedAttachment changes. - control.templateRendered = true; - } - - titleInput = control.$el.find( '.title' ); - if ( ! titleInput.is( document.activeElement ) ) { - titleInput.val( control.model.get( 'title' ) ); - } - - control.$el.toggleClass( 'selected', control.isSelected() ); - }, - - /** - * Render media preview. - * - * @abstract - * @returns {void} - */ - renderPreview: function renderPreview() { - throw new Error( 'renderPreview must be implemented' ); - }, - - /** - * Whether a media item is selected. - * - * @returns {boolean} Whether selected and no error. - */ - isSelected: function isSelected() { - var control = this; - - if ( control.model.get( 'error' ) ) { - return false; - } - - return Boolean( control.model.get( 'attachment_id' ) || control.model.get( 'url' ) ); - }, - - /** - * Handle click on link to Media Library to open modal, such as the link that appears when in the missing attachment error notice. - * - * @param {jQuery.Event} event - Event. - * @returns {void} - */ - handleMediaLibraryLinkClick: function handleMediaLibraryLinkClick( event ) { - var control = this; - event.preventDefault(); - control.selectMedia(); - }, - - /** - * Open the media select frame to chose an item. - * - * @returns {void} - */ - selectMedia: function selectMedia() { - var control = this, selection, mediaFrame, defaultSync, mediaFrameProps, selectionModels = []; - - if ( control.isSelected() && 0 !== control.model.get( 'attachment_id' ) ) { - selectionModels.push( control.selectedAttachment ); - } - - selection = new wp.media.model.Selection( selectionModels, { multiple: false } ); - - mediaFrameProps = control.mapModelToMediaFrameProps( control.model.toJSON() ); - if ( mediaFrameProps.size ) { - control.displaySettings.set( 'size', mediaFrameProps.size ); - } - - mediaFrame = new component.MediaFrameSelect({ - title: control.l10n.add_media, - frame: 'post', - text: control.l10n.add_to_widget, - selection: selection, - mimeType: control.mime_type, - selectedDisplaySettings: control.displaySettings, - showDisplaySettings: control.showDisplaySettings, - metadata: mediaFrameProps, - state: control.isSelected() && 0 === control.model.get( 'attachment_id' ) ? 'embed' : 'insert', - invalidEmbedTypeError: control.l10n.unsupported_file_type - }); - wp.media.frame = mediaFrame; // See wp.media(). - - // Handle selection of a media item. - mediaFrame.on( 'insert', function onInsert() { - var attachment = {}, state = mediaFrame.state(); - - // Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview. - if ( 'embed' === state.get( 'id' ) ) { - _.extend( attachment, { id: 0 }, state.props.toJSON() ); - } else { - _.extend( attachment, state.get( 'selection' ).first().toJSON() ); - } - - control.selectedAttachment.set( attachment ); - control.model.set( 'error', false ); - - // Update widget instance. - control.model.set( control.getModelPropsFromMediaFrame( mediaFrame ) ); - }); - - // Disable syncing of attachment changes back to server (except for deletions). See <https://core.trac.wordpress.org/ticket/40403>. - defaultSync = wp.media.model.Attachment.prototype.sync; - wp.media.model.Attachment.prototype.sync = function( method ) { - if ( 'delete' === method ) { - return defaultSync.apply( this, arguments ); - } else { - return $.Deferred().rejectWith( this ).promise(); - } - }; - mediaFrame.on( 'close', function onClose() { - wp.media.model.Attachment.prototype.sync = defaultSync; - }); - - mediaFrame.$el.addClass( 'media-widget' ); - mediaFrame.open(); - - // Clear the selected attachment when it is deleted in the media select frame. - if ( selection ) { - selection.on( 'destroy', function onDestroy( attachment ) { - if ( control.model.get( 'attachment_id' ) === attachment.get( 'id' ) ) { - control.model.set({ - attachment_id: 0, - url: '' - }); - } - }); - } - - /* - * Make sure focus is set inside of modal so that hitting Esc will close - * the modal and not inadvertently cause the widget to collapse in the customizer. - */ - mediaFrame.$el.find( '.media-frame-menu .media-menu-item.active' ).focus(); - }, - - /** - * Get the instance props from the media selection frame. - * - * @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame. - * @returns {Object} Props. - */ - getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) { - var control = this, state, mediaFrameProps, modelProps; - - state = mediaFrame.state(); - if ( 'insert' === state.get( 'id' ) ) { - mediaFrameProps = state.get( 'selection' ).first().toJSON(); - mediaFrameProps.postUrl = mediaFrameProps.link; - - if ( control.showDisplaySettings ) { - _.extend( - mediaFrameProps, - mediaFrame.content.get( '.attachments-browser' ).sidebar.get( 'display' ).model.toJSON() - ); - } - if ( mediaFrameProps.sizes && mediaFrameProps.size && mediaFrameProps.sizes[ mediaFrameProps.size ] ) { - mediaFrameProps.url = mediaFrameProps.sizes[ mediaFrameProps.size ].url; - } - } else if ( 'embed' === state.get( 'id' ) ) { - mediaFrameProps = _.extend( - state.props.toJSON(), - { attachment_id: 0 }, // Because some media frames use `attachment_id` not `id`. - control.model.getEmbedResetProps() - ); - } else { - throw new Error( 'Unexpected state: ' + state.get( 'id' ) ); - } - - if ( mediaFrameProps.id ) { - mediaFrameProps.attachment_id = mediaFrameProps.id; - } - - modelProps = control.mapMediaToModelProps( mediaFrameProps ); - - // Clear the extension prop so sources will be reset for video and audio media. - _.each( wp.media.view.settings.embedExts, function( ext ) { - if ( ext in control.model.schema && modelProps.url !== modelProps[ ext ] ) { - modelProps[ ext ] = ''; - } - }); - - return modelProps; - }, - - /** - * Map media frame props to model props. - * - * @param {Object} mediaFrameProps - Media frame props. - * @returns {Object} Model props. - */ - mapMediaToModelProps: function mapMediaToModelProps( mediaFrameProps ) { - var control = this, mediaFramePropToModelPropMap = {}, modelProps = {}, extension; - _.each( control.model.schema, function( fieldSchema, modelProp ) { - - // Ignore widget title attribute. - if ( 'title' === modelProp ) { - return; - } - mediaFramePropToModelPropMap[ fieldSchema.media_prop || modelProp ] = modelProp; - }); - - _.each( mediaFrameProps, function( value, mediaProp ) { - var propName = mediaFramePropToModelPropMap[ mediaProp ] || mediaProp; - if ( control.model.schema[ propName ] ) { - modelProps[ propName ] = value; - } - }); - - if ( 'custom' === mediaFrameProps.size ) { - modelProps.width = mediaFrameProps.customWidth; - modelProps.height = mediaFrameProps.customHeight; - } - - if ( 'post' === mediaFrameProps.link ) { - modelProps.link_url = mediaFrameProps.postUrl || mediaFrameProps.linkUrl; - } else if ( 'file' === mediaFrameProps.link ) { - modelProps.link_url = mediaFrameProps.url; - } - - // Because some media frames use `id` instead of `attachment_id`. - if ( ! mediaFrameProps.attachment_id && mediaFrameProps.id ) { - modelProps.attachment_id = mediaFrameProps.id; - } - - if ( mediaFrameProps.url ) { - extension = mediaFrameProps.url.replace( /#.*$/, '' ).replace( /\?.*$/, '' ).split( '.' ).pop().toLowerCase(); - if ( extension in control.model.schema ) { - modelProps[ extension ] = mediaFrameProps.url; - } - } - - // Always omit the titles derived from mediaFrameProps. - return _.omit( modelProps, 'title' ); - }, - - /** - * Map model props to media frame props. - * - * @param {Object} modelProps - Model props. - * @returns {Object} Media frame props. - */ - mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { - var control = this, mediaFrameProps = {}; - - _.each( modelProps, function( value, modelProp ) { - var fieldSchema = control.model.schema[ modelProp ] || {}; - mediaFrameProps[ fieldSchema.media_prop || modelProp ] = value; - }); - - // Some media frames use attachment_id. - mediaFrameProps.attachment_id = mediaFrameProps.id; - - if ( 'custom' === mediaFrameProps.size ) { - mediaFrameProps.customWidth = control.model.get( 'width' ); - mediaFrameProps.customHeight = control.model.get( 'height' ); - } - - return mediaFrameProps; - }, - - /** - * Map model props to previewTemplateProps. - * - * @returns {Object} Preview Template Props. - */ - mapModelToPreviewTemplateProps: function mapModelToPreviewTemplateProps() { - var control = this, previewTemplateProps = {}; - _.each( control.model.schema, function( value, prop ) { - if ( ! value.hasOwnProperty( 'should_preview_update' ) || value.should_preview_update ) { - previewTemplateProps[ prop ] = control.model.get( prop ); - } - }); - - // Templates need to be aware of the error. - previewTemplateProps.error = control.model.get( 'error' ); - return previewTemplateProps; - }, - - /** - * Open the media frame to modify the selected item. - * - * @abstract - * @returns {void} - */ - editMedia: function editMedia() { - throw new Error( 'editMedia not implemented' ); - } - }); - - /** - * Media widget model. - * - * @class wp.mediaWidgets.MediaWidgetModel - * @augments Backbone.Model - */ - component.MediaWidgetModel = Backbone.Model.extend(/** @lends wp.mediaWidgets.MediaWidgetModel.prototype */{ - - /** - * Id attribute. - * - * @type {string} - */ - idAttribute: 'widget_id', - - /** - * Instance schema. - * - * This adheres to JSON Schema and subclasses should have their schema - * exported from PHP to JS such as is done in WP_Widget_Media_Image::enqueue_admin_scripts(). - * - * @type {Object.<string, Object>} - */ - schema: { - title: { - type: 'string', - 'default': '' - }, - attachment_id: { - type: 'integer', - 'default': 0 - }, - url: { - type: 'string', - 'default': '' - } - }, - - /** - * Get default attribute values. - * - * @returns {Object} Mapping of property names to their default values. - */ - defaults: function() { - var defaults = {}; - _.each( this.schema, function( fieldSchema, field ) { - defaults[ field ] = fieldSchema['default']; - }); - return defaults; - }, - - /** - * Set attribute value(s). - * - * This is a wrapped version of Backbone.Model#set() which allows us to - * cast the attribute values from the hidden inputs' string values into - * the appropriate data types (integers or booleans). - * - * @param {string|Object} key - Attribute name or attribute pairs. - * @param {mixed|Object} [val] - Attribute value or options object. - * @param {Object} [options] - Options when attribute name and value are passed separately. - * @returns {wp.mediaWidgets.MediaWidgetModel} This model. - */ - set: function set( key, val, options ) { - var model = this, attrs, opts, castedAttrs; // eslint-disable-line consistent-this - if ( null === key ) { - return model; - } - if ( 'object' === typeof key ) { - attrs = key; - opts = val; - } else { - attrs = {}; - attrs[ key ] = val; - opts = options; - } - - castedAttrs = {}; - _.each( attrs, function( value, name ) { - var type; - if ( ! model.schema[ name ] ) { - castedAttrs[ name ] = value; - return; - } - type = model.schema[ name ].type; - if ( 'array' === type ) { - castedAttrs[ name ] = value; - if ( ! _.isArray( castedAttrs[ name ] ) ) { - castedAttrs[ name ] = castedAttrs[ name ].split( /,/ ); // Good enough for parsing an ID list. - } - if ( model.schema[ name ].items && 'integer' === model.schema[ name ].items.type ) { - castedAttrs[ name ] = _.filter( - _.map( castedAttrs[ name ], function( id ) { - return parseInt( id, 10 ); - }, - function( id ) { - return 'number' === typeof id; - } - ) ); - } - } else if ( 'integer' === type ) { - castedAttrs[ name ] = parseInt( value, 10 ); - } else if ( 'boolean' === type ) { - castedAttrs[ name ] = ! ( ! value || '0' === value || 'false' === value ); - } else { - castedAttrs[ name ] = value; - } - }); - - return Backbone.Model.prototype.set.call( this, castedAttrs, opts ); - }, - - /** - * Get props which are merged on top of the model when an embed is chosen (as opposed to an attachment). - * - * @returns {Object} Reset/override props. - */ - getEmbedResetProps: function getEmbedResetProps() { - return { - id: 0 - }; - } - }); - - /** - * Collection of all widget model instances. - * - * @memberOf wp.mediaWidgets - * - * @type {Backbone.Collection} - */ - component.modelCollection = new ( Backbone.Collection.extend( { - model: component.MediaWidgetModel - }) )(); - - /** - * Mapping of widget ID to instances of MediaWidgetControl subclasses. - * - * @memberOf wp.mediaWidgets - * - * @type {Object.<string, wp.mediaWidgets.MediaWidgetControl>} - */ - component.widgetControls = {}; - - /** - * Handle widget being added or initialized for the first time at the widget-added event. - * - * @memberOf wp.mediaWidgets - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * - * @returns {void} - */ - component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) { - var fieldContainer, syncContainer, widgetForm, idBase, ControlConstructor, ModelConstructor, modelAttributes, widgetControl, widgetModel, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen. - idBase = widgetForm.find( '> .id_base' ).val(); - widgetId = widgetForm.find( '> .widget-id' ).val(); - - // Prevent initializing already-added widgets. - if ( component.widgetControls[ widgetId ] ) { - return; - } - - ControlConstructor = component.controlConstructors[ idBase ]; - if ( ! ControlConstructor ) { - return; - } - - ModelConstructor = component.modelConstructors[ idBase ] || component.MediaWidgetModel; - - /* - * Create a container element for the widget control (Backbone.View). - * This is inserted into the DOM immediately before the .widget-content - * element because the contents of this element are essentially "managed" - * by PHP, where each widget update cause the entire element to be emptied - * and replaced with the rendered output of WP_Widget::form() which is - * sent back in Ajax request made to save/update the widget instance. - * To prevent a "flash of replaced DOM elements and re-initialized JS - * components", the JS template is rendered outside of the normal form - * container. - */ - fieldContainer = $( '<div></div>' ); - syncContainer = widgetContainer.find( '.widget-content:first' ); - syncContainer.before( fieldContainer ); - - /* - * Sync the widget instance model attributes onto the hidden inputs that widgets currently use to store the state. - * In the future, when widgets are JS-driven, the underlying widget instance data should be exposed as a model - * from the start, without having to sync with hidden fields. See <https://core.trac.wordpress.org/ticket/33507>. - */ - modelAttributes = {}; - syncContainer.find( '.media-widget-instance-property' ).each( function() { - var input = $( this ); - modelAttributes[ input.data( 'property' ) ] = input.val(); - }); - modelAttributes.widget_id = widgetId; - - widgetModel = new ModelConstructor( modelAttributes ); - - widgetControl = new ControlConstructor({ - el: fieldContainer, - syncContainer: syncContainer, - model: widgetModel - }); - - /* - * Render the widget once the widget parent's container finishes animating, - * as the widget-added event fires with a slideDown of the container. - * This ensures that the container's dimensions are fixed so that ME.js - * can initialize with the proper dimensions. - */ - renderWhenAnimationDone = function() { - if ( ! widgetContainer.hasClass( 'open' ) ) { - setTimeout( renderWhenAnimationDone, animatedCheckDelay ); - } else { - widgetControl.render(); - } - }; - renderWhenAnimationDone(); - - /* - * Note that the model and control currently won't ever get garbage-collected - * when a widget gets removed/deleted because there is no widget-removed event. - */ - component.modelCollection.add( [ widgetModel ] ); - component.widgetControls[ widgetModel.get( 'widget_id' ) ] = widgetControl; - }; - - /** - * Setup widget in accessibility mode. - * - * @memberOf wp.mediaWidgets - * - * @returns {void} - */ - component.setupAccessibleMode = function setupAccessibleMode() { - var widgetForm, widgetId, idBase, widgetControl, ControlConstructor, ModelConstructor, modelAttributes, fieldContainer, syncContainer; - widgetForm = $( '.editwidget > form' ); - if ( 0 === widgetForm.length ) { - return; - } - - idBase = widgetForm.find( '> .widget-control-actions > .id_base' ).val(); - - ControlConstructor = component.controlConstructors[ idBase ]; - if ( ! ControlConstructor ) { - return; - } - - widgetId = widgetForm.find( '> .widget-control-actions > .widget-id' ).val(); - - ModelConstructor = component.modelConstructors[ idBase ] || component.MediaWidgetModel; - fieldContainer = $( '<div></div>' ); - syncContainer = widgetForm.find( '> .widget-inside' ); - syncContainer.before( fieldContainer ); - - modelAttributes = {}; - syncContainer.find( '.media-widget-instance-property' ).each( function() { - var input = $( this ); - modelAttributes[ input.data( 'property' ) ] = input.val(); - }); - modelAttributes.widget_id = widgetId; - - widgetControl = new ControlConstructor({ - el: fieldContainer, - syncContainer: syncContainer, - model: new ModelConstructor( modelAttributes ) - }); - - component.modelCollection.add( [ widgetControl.model ] ); - component.widgetControls[ widgetControl.model.get( 'widget_id' ) ] = widgetControl; - - widgetControl.render(); - }; - - /** - * Sync widget instance data sanitized from server back onto widget model. - * - * This gets called via the 'widget-updated' event when saving a widget from - * the widgets admin screen and also via the 'widget-synced' event when making - * a change to a widget in the customizer. - * - * @memberOf wp.mediaWidgets - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * - * @returns {void} - */ - component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) { - var widgetForm, widgetContent, widgetId, widgetControl, attributes = {}; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); - widgetId = widgetForm.find( '> .widget-id' ).val(); - - widgetControl = component.widgetControls[ widgetId ]; - if ( ! widgetControl ) { - return; - } - - // Make sure the server-sanitized values get synced back into the model. - widgetContent = widgetForm.find( '> .widget-content' ); - widgetContent.find( '.media-widget-instance-property' ).each( function() { - var property = $( this ).data( 'property' ); - attributes[ property ] = $( this ).val(); - }); - - // Suspend syncing model back to inputs when syncing from inputs to model, preventing infinite loop. - widgetControl.stopListening( widgetControl.model, 'change', widgetControl.syncModelToInputs ); - widgetControl.model.set( attributes ); - widgetControl.listenTo( widgetControl.model, 'change', widgetControl.syncModelToInputs ); - }; - - /** - * Initialize functionality. - * - * This function exists to prevent the JS file from having to boot itself. - * When WordPress enqueues this script, it should have an inline script - * attached which calls wp.mediaWidgets.init(). - * - * @memberOf wp.mediaWidgets - * - * @returns {void} - */ - component.init = function init() { - var $document = $( document ); - $document.on( 'widget-added', component.handleWidgetAdded ); - $document.on( 'widget-synced widget-updated', component.handleWidgetUpdated ); - - /* - * Manually trigger widget-added events for media widgets on the admin - * screen once they are expanded. The widget-added event is not triggered - * for each pre-existing widget on the widgets admin screen like it is - * on the customizer. Likewise, the customizer only triggers widget-added - * when the widget is expanded to just-in-time construct the widget form - * when it is actually going to be displayed. So the following implements - * the same for the widgets admin screen, to invoke the widget-added - * handler when a pre-existing media widget is expanded. - */ - $( function initializeExistingWidgetContainers() { - var widgetContainers; - if ( 'widgets' !== window.pagenow ) { - return; - } - widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' ); - widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() { - var widgetContainer = $( this ); - component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer ); - }); - - // Accessibility mode. - $( window ).on( 'load', function() { - component.setupAccessibleMode(); - }); - }); - }; - - return component; -})( jQuery ); diff --git a/srcs/wordpress/wp-admin/js/widgets/media-widgets.min.js b/srcs/wordpress/wp-admin/js/widgets/media-widgets.min.js deleted file mode 100644 index 48b5d2f..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/media-widgets.min.js +++ /dev/null @@ -1 +0,0 @@ -wp.mediaWidgets=function(h){"use strict";var g={controlConstructors:{},modelConstructors:{}};return g.PersistentDisplaySettingsLibrary=wp.media.controller.Library.extend({initialize:function(e){_.bindAll(this,"handleDisplaySettingChange"),wp.media.controller.Library.prototype.initialize.call(this,e)},handleDisplaySettingChange:function(e){this.get("selectedDisplaySettings").set(e.attributes)},display:function(e){var t,i=this.get("selectedDisplaySettings");return(t=wp.media.controller.Library.prototype.display.call(this,e)).off("change",this.handleDisplaySettingChange),t.set(i.attributes),"custom"===i.get("link_type")&&(t.linkUrl=i.get("link_url")),t.on("change",this.handleDisplaySettingChange),t}}),g.MediaEmbedView=wp.media.view.Embed.extend({initialize:function(e){var t,i=this;wp.media.view.Embed.prototype.initialize.call(i,e),"image"!==i.controller.options.mimeType&&(t=i.controller.states.get("embed")).off("scan",t.scanImage,t)},refresh:function(){var e;e="image"===this.controller.options.mimeType?wp.media.view.EmbedImage:wp.media.view.EmbedLink.extend({setAddToWidgetButtonDisabled:function(e){this.views.parent.views.parent.views.get(".media-frame-toolbar")[0].$el.find(".media-button-select").prop("disabled",e)},setErrorNotice:function(e){var t;t=this.views.parent.$el.find("> .notice:first-child"),e?(t.length||((t=h('<div class="media-widget-embed-notice notice notice-error notice-alt"></div>')).hide(),this.views.parent.$el.prepend(t)),t.empty(),t.append(h("<p>",{html:e})),t.slideDown("fast")):t.length&&t.slideUp("fast")},updateoEmbed:function(){var e,t=this;if(!(e=t.model.get("url")))return t.setErrorNotice(""),void t.setAddToWidgetButtonDisabled(!0);e.match(/^(http|https):\/\/.+\//)||(t.controller.$el.find("#embed-url-field").addClass("invalid"),t.setAddToWidgetButtonDisabled(!0)),wp.media.view.EmbedLink.prototype.updateoEmbed.call(t)},fetch:function(){var t,e,i,n,d,o,a=this;if(d=a.model.get("url"),a.dfd&&"pending"===a.dfd.state()&&a.dfd.abort(),t=function(e){a.renderoEmbed({data:{body:e}}),a.controller.$el.find("#embed-url-field").removeClass("invalid"),a.setErrorNotice(""),a.setAddToWidgetButtonDisabled(!1)},(n=document.createElement("a")).href=d,e=n.pathname.toLowerCase().match(/\.(\w+)$/))return i=e[1],void(wp.media.view.settings.embedMimes[i]?0!==wp.media.view.settings.embedMimes[i].indexOf(a.controller.options.mimeType)?a.renderFail():t("\x3c!--success--\x3e"):a.renderFail());(o=/https?:\/\/www\.youtube\.com\/embed\/([^/]+)/.exec(d))&&(d="https://www.youtube.com/watch?v="+o[1],a.model.attributes.url=d),a.dfd=wp.apiRequest({url:wp.media.view.settings.oEmbedProxyUrl,data:{url:d,maxwidth:a.model.get("width"),maxheight:a.model.get("height"),discover:!1},type:"GET",dataType:"json",context:a}),a.dfd.done(function(e){a.controller.options.mimeType===e.type?t(e.html):a.renderFail()}),a.dfd.fail(_.bind(a.renderFail,a))},renderFail:function(){var e=this;e.controller.$el.find("#embed-url-field").addClass("invalid"),e.setErrorNotice(e.controller.options.invalidEmbedTypeError||"ERROR"),e.setAddToWidgetButtonDisabled(!0)}}),this.settings(new e({controller:this.controller,model:this.model.props,priority:40}))}}),g.MediaFrameSelect=wp.media.view.MediaFrame.Post.extend({createStates:function(){var t=this.options.mimeType,i=[];_.each(wp.media.view.settings.embedMimes,function(e){0===e.indexOf(t)&&i.push(e)}),0<i.length&&(t=i),this.states.add([new g.PersistentDisplaySettingsLibrary({id:"insert",title:this.options.title,selection:this.options.selection,priority:20,toolbar:"main-insert",filterable:"dates",library:wp.media.query({type:t}),multiple:!1,editable:!0,selectedDisplaySettings:this.options.selectedDisplaySettings,displaySettings:!!_.isUndefined(this.options.showDisplaySettings)||this.options.showDisplaySettings,displayUserSettings:!1}),new wp.media.controller.EditImage({model:this.options.editImage}),new wp.media.controller.Embed({metadata:this.options.metadata,type:"image"===this.options.mimeType?"image":"link",invalidEmbedTypeError:this.options.invalidEmbedTypeError})])},mainInsertToolbar:function(e){var i=this;e.set("insert",{style:"primary",priority:80,text:i.options.text,requires:{selection:!0},click:function(){var e=i.state(),t=e.get("selection");i.close(),e.trigger("insert",t).reset()}})},mainEmbedToolbar:function(e){e.view=new wp.media.view.Toolbar.Embed({controller:this,text:this.options.text,event:"insert"})},embedContent:function(){var e=new g.MediaEmbedView({controller:this,model:this.state()}).render();this.content.set(e)}}),g.MediaWidgetControl=Backbone.View.extend({l10n:{add_to_widget:"{{add_to_widget}}",add_media:"{{add_media}}"},id_base:"",mime_type:"",events:{"click .notice-missing-attachment a":"handleMediaLibraryLinkClick","click .select-media":"selectMedia","click .placeholder":"selectMedia","click .edit-media":"editMedia"},showDisplaySettings:!0,initialize:function(e){var i=this;if(Backbone.View.prototype.initialize.call(i,e),!(i.model instanceof g.MediaWidgetModel))throw new Error("Missing options.model");if(!e.el)throw new Error("Missing options.el");if(!e.syncContainer)throw new Error("Missing options.syncContainer");if(i.syncContainer=e.syncContainer,i.$el.addClass("media-widget-control"),_.bindAll(i,"syncModelToInputs","render","updateSelectedAttachment","renderPreview"),!i.id_base&&(_.find(g.controlConstructors,function(e,t){return i instanceof e&&(i.id_base=t,!0)}),!i.id_base))throw new Error("Missing id_base.");i.previewTemplateProps=new Backbone.Model(i.mapModelToPreviewTemplateProps()),i.selectedAttachment=new wp.media.model.Attachment,i.renderPreview=_.debounce(i.renderPreview),i.listenTo(i.previewTemplateProps,"change",i.renderPreview),i.model.on("change:attachment_id",i.updateSelectedAttachment),i.model.on("change:url",i.updateSelectedAttachment),i.updateSelectedAttachment(),i.listenTo(i.model,"change",i.syncModelToInputs),i.listenTo(i.model,"change",i.syncModelToPreviewProps),i.listenTo(i.model,"change",i.render),i.$el.on("input change",".title",function(){i.model.set({title:h.trim(h(this).val())})}),i.$el.on("input change",".link",function(){var e=h.trim(h(this).val()),t="custom";i.selectedAttachment.get("linkUrl")===e||i.selectedAttachment.get("link")===e?t="post":i.selectedAttachment.get("url")===e&&(t="file"),i.model.set({link_url:e,link_type:t}),i.displaySettings.set({link:t,linkUrl:e})}),i.displaySettings=new Backbone.Model(_.pick(i.mapModelToMediaFrameProps(_.extend(i.model.defaults(),i.model.toJSON())),_.keys(wp.media.view.settings.defaultProps)))},updateSelectedAttachment:function(){var e,t=this;0===t.model.get("attachment_id")?(t.selectedAttachment.clear(),t.model.set("error",!1)):t.model.get("attachment_id")!==t.selectedAttachment.get("id")&&(e=new wp.media.model.Attachment({id:t.model.get("attachment_id")})).fetch().done(function(){t.model.set("error",!1),t.selectedAttachment.set(e.toJSON())}).fail(function(){t.model.set("error","missing_attachment")})},syncModelToPreviewProps:function(){this.previewTemplateProps.set(this.mapModelToPreviewTemplateProps())},syncModelToInputs:function(){var n=this;n.syncContainer.find(".media-widget-instance-property").each(function(){var e,t,i=h(this);t=i.data("property"),e=n.model.get(t),_.isUndefined(e)||(e="array"===n.model.schema[t].type&&_.isArray(e)?e.join(","):"boolean"===n.model.schema[t].type?e?"1":"":String(e),i.val()!==e&&(i.val(e),i.trigger("change")))})},template:function(){if(!h("#tmpl-widget-media-"+this.id_base+"-control").length)throw new Error("Missing widget control template for "+this.id_base);return wp.template("widget-media-"+this.id_base+"-control")},render:function(){var e,t=this;t.templateRendered||(t.$el.html(t.template()(t.model.toJSON())),t.renderPreview(),t.templateRendered=!0),(e=t.$el.find(".title")).is(document.activeElement)||e.val(t.model.get("title")),t.$el.toggleClass("selected",t.isSelected())},renderPreview:function(){throw new Error("renderPreview must be implemented")},isSelected:function(){return!this.model.get("error")&&Boolean(this.model.get("attachment_id")||this.model.get("url"))},handleMediaLibraryLinkClick:function(e){e.preventDefault(),this.selectMedia()},selectMedia:function(){var e,i,t,n,d=this,o=[];d.isSelected()&&0!==d.model.get("attachment_id")&&o.push(d.selectedAttachment),e=new wp.media.model.Selection(o,{multiple:!1}),(n=d.mapModelToMediaFrameProps(d.model.toJSON())).size&&d.displaySettings.set("size",n.size),i=new g.MediaFrameSelect({title:d.l10n.add_media,frame:"post",text:d.l10n.add_to_widget,selection:e,mimeType:d.mime_type,selectedDisplaySettings:d.displaySettings,showDisplaySettings:d.showDisplaySettings,metadata:n,state:d.isSelected()&&0===d.model.get("attachment_id")?"embed":"insert",invalidEmbedTypeError:d.l10n.unsupported_file_type}),(wp.media.frame=i).on("insert",function(){var e={},t=i.state();"embed"===t.get("id")?_.extend(e,{id:0},t.props.toJSON()):_.extend(e,t.get("selection").first().toJSON()),d.selectedAttachment.set(e),d.model.set("error",!1),d.model.set(d.getModelPropsFromMediaFrame(i))}),t=wp.media.model.Attachment.prototype.sync,wp.media.model.Attachment.prototype.sync=function(e){return"delete"===e?t.apply(this,arguments):h.Deferred().rejectWith(this).promise()},i.on("close",function(){wp.media.model.Attachment.prototype.sync=t}),i.$el.addClass("media-widget"),i.open(),e&&e.on("destroy",function(e){d.model.get("attachment_id")===e.get("id")&&d.model.set({attachment_id:0,url:""})}),i.$el.find(".media-frame-menu .media-menu-item.active").focus()},getModelPropsFromMediaFrame:function(e){var t,i,n,d=this;if("insert"===(t=e.state()).get("id"))(i=t.get("selection").first().toJSON()).postUrl=i.link,d.showDisplaySettings&&_.extend(i,e.content.get(".attachments-browser").sidebar.get("display").model.toJSON()),i.sizes&&i.size&&i.sizes[i.size]&&(i.url=i.sizes[i.size].url);else{if("embed"!==t.get("id"))throw new Error("Unexpected state: "+t.get("id"));i=_.extend(t.props.toJSON(),{attachment_id:0},d.model.getEmbedResetProps())}return i.id&&(i.attachment_id=i.id),n=d.mapMediaToModelProps(i),_.each(wp.media.view.settings.embedExts,function(e){e in d.model.schema&&n.url!==n[e]&&(n[e]="")}),n},mapMediaToModelProps:function(e){var t,n=this,d={},o={};return _.each(n.model.schema,function(e,t){"title"!==t&&(d[e.media_prop||t]=t)}),_.each(e,function(e,t){var i=d[t]||t;n.model.schema[i]&&(o[i]=e)}),"custom"===e.size&&(o.width=e.customWidth,o.height=e.customHeight),"post"===e.link?o.link_url=e.postUrl||e.linkUrl:"file"===e.link&&(o.link_url=e.url),!e.attachment_id&&e.id&&(o.attachment_id=e.id),e.url&&(t=e.url.replace(/#.*$/,"").replace(/\?.*$/,"").split(".").pop().toLowerCase())in n.model.schema&&(o[t]=e.url),_.omit(o,"title")},mapModelToMediaFrameProps:function(e){var n=this,d={};return _.each(e,function(e,t){var i=n.model.schema[t]||{};d[i.media_prop||t]=e}),d.attachment_id=d.id,"custom"===d.size&&(d.customWidth=n.model.get("width"),d.customHeight=n.model.get("height")),d},mapModelToPreviewTemplateProps:function(){var i=this,n={};return _.each(i.model.schema,function(e,t){e.hasOwnProperty("should_preview_update")&&!e.should_preview_update||(n[t]=i.model.get(t))}),n.error=i.model.get("error"),n},editMedia:function(){throw new Error("editMedia not implemented")}}),g.MediaWidgetModel=Backbone.Model.extend({idAttribute:"widget_id",schema:{title:{type:"string",default:""},attachment_id:{type:"integer",default:0},url:{type:"string",default:""}},defaults:function(){var i={};return _.each(this.schema,function(e,t){i[t]=e.default}),i},set:function(e,t,i){var n,d,o,a=this;return null===e?a:(d="object"==typeof e?(n=e,t):((n={})[e]=t,i),o={},_.each(n,function(e,t){var i;a.schema[t]?"array"===(i=a.schema[t].type)?(o[t]=e,_.isArray(o[t])||(o[t]=o[t].split(/,/)),a.schema[t].items&&"integer"===a.schema[t].items.type&&(o[t]=_.filter(_.map(o[t],function(e){return parseInt(e,10)},function(e){return"number"==typeof e})))):o[t]="integer"===i?parseInt(e,10):"boolean"===i?!(!e||"0"===e||"false"===e):e:o[t]=e}),Backbone.Model.prototype.set.call(this,o,d))},getEmbedResetProps:function(){return{id:0}}}),g.modelCollection=new(Backbone.Collection.extend({model:g.MediaWidgetModel})),g.widgetControls={},g.handleWidgetAdded=function(e,t){var i,n,d,o,a,r,s,l,c,m,p;o=(d=t.find("> .widget-inside > .form, > .widget-inside > form")).find("> .id_base").val(),m=d.find("> .widget-id").val(),g.widgetControls[m]||(a=g.controlConstructors[o])&&(r=g.modelConstructors[o]||g.MediaWidgetModel,i=h("<div></div>"),(n=t.find(".widget-content:first")).before(i),s={},n.find(".media-widget-instance-property").each(function(){var e=h(this);s[e.data("property")]=e.val()}),s.widget_id=m,c=new r(s),l=new a({el:i,syncContainer:n,model:c}),(p=function(){t.hasClass("open")?l.render():setTimeout(p,50)})(),g.modelCollection.add([c]),g.widgetControls[c.get("widget_id")]=l)},g.setupAccessibleMode=function(){var e,t,i,n,d,o,a,r,s;0!==(e=h(".editwidget > form")).length&&(i=e.find("> .widget-control-actions > .id_base").val(),(d=g.controlConstructors[i])&&(t=e.find("> .widget-control-actions > .widget-id").val(),o=g.modelConstructors[i]||g.MediaWidgetModel,r=h("<div></div>"),(s=e.find("> .widget-inside")).before(r),a={},s.find(".media-widget-instance-property").each(function(){var e=h(this);a[e.data("property")]=e.val()}),a.widget_id=t,n=new d({el:r,syncContainer:s,model:new o(a)}),g.modelCollection.add([n.model]),(g.widgetControls[n.model.get("widget_id")]=n).render()))},g.handleWidgetUpdated=function(e,t){var i,n,d,o={};n=(i=t.find("> .widget-inside > .form, > .widget-inside > form")).find("> .widget-id").val(),(d=g.widgetControls[n])&&(i.find("> .widget-content").find(".media-widget-instance-property").each(function(){var e=h(this).data("property");o[e]=h(this).val()}),d.stopListening(d.model,"change",d.syncModelToInputs),d.model.set(o),d.listenTo(d.model,"change",d.syncModelToInputs))},g.init=function(){var e=h(document);e.on("widget-added",g.handleWidgetAdded),e.on("widget-synced widget-updated",g.handleWidgetUpdated),h(function(){"widgets"===window.pagenow&&(h(".widgets-holder-wrap:not(#available-widgets)").find("div.widget").one("click.toggle-widget-expanded",function(){var e=h(this);g.handleWidgetAdded(new jQuery.Event("widget-added"),e)}),h(window).on("load",function(){g.setupAccessibleMode()}))})},g}(jQuery);
\ No newline at end of file diff --git a/srcs/wordpress/wp-admin/js/widgets/text-widgets.js b/srcs/wordpress/wp-admin/js/widgets/text-widgets.js deleted file mode 100644 index 184e724..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/text-widgets.js +++ /dev/null @@ -1,552 +0,0 @@ -/** - * @output wp-admin/js/widgets/text-widgets.js - */ - -/* global tinymce, switchEditors */ -/* eslint consistent-this: [ "error", "control" ] */ - -/** - * @namespace wp.textWidgets - */ -wp.textWidgets = ( function( $ ) { - 'use strict'; - - var component = { - dismissedPointers: [], - idBases: [ 'text' ] - }; - - component.TextWidgetControl = Backbone.View.extend(/** @lends wp.textWidgets.TextWidgetControl.prototype */{ - - /** - * View events. - * - * @type {Object} - */ - events: {}, - - /** - * Text widget control. - * - * @constructs wp.textWidgets.TextWidgetControl - * @augments Backbone.View - * @abstract - * - * @param {Object} options - Options. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. - * - * @returns {void} - */ - initialize: function initialize( options ) { - var control = this; - - if ( ! options.el ) { - throw new Error( 'Missing options.el' ); - } - if ( ! options.syncContainer ) { - throw new Error( 'Missing options.syncContainer' ); - } - - Backbone.View.prototype.initialize.call( control, options ); - control.syncContainer = options.syncContainer; - - control.$el.addClass( 'text-widget-fields' ); - control.$el.html( wp.template( 'widget-text-control-fields' ) ); - - control.customHtmlWidgetPointer = control.$el.find( '.wp-pointer.custom-html-widget-pointer' ); - if ( control.customHtmlWidgetPointer.length ) { - control.customHtmlWidgetPointer.find( '.close' ).on( 'click', function( event ) { - event.preventDefault(); - control.customHtmlWidgetPointer.hide(); - $( '#' + control.fields.text.attr( 'id' ) + '-html' ).focus(); - control.dismissPointers( [ 'text_widget_custom_html' ] ); - }); - control.customHtmlWidgetPointer.find( '.add-widget' ).on( 'click', function( event ) { - event.preventDefault(); - control.customHtmlWidgetPointer.hide(); - control.openAvailableWidgetsPanel(); - }); - } - - control.pasteHtmlPointer = control.$el.find( '.wp-pointer.paste-html-pointer' ); - if ( control.pasteHtmlPointer.length ) { - control.pasteHtmlPointer.find( '.close' ).on( 'click', function( event ) { - event.preventDefault(); - control.pasteHtmlPointer.hide(); - control.editor.focus(); - control.dismissPointers( [ 'text_widget_custom_html', 'text_widget_paste_html' ] ); - }); - } - - control.fields = { - title: control.$el.find( '.title' ), - text: control.$el.find( '.text' ) - }; - - // Sync input fields to hidden sync fields which actually get sent to the server. - _.each( control.fields, function( fieldInput, fieldName ) { - fieldInput.on( 'input change', function updateSyncField() { - var syncInput = control.syncContainer.find( '.sync-input.' + fieldName ); - if ( syncInput.val() !== fieldInput.val() ) { - syncInput.val( fieldInput.val() ); - syncInput.trigger( 'change' ); - } - }); - - // Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event. - fieldInput.val( control.syncContainer.find( '.sync-input.' + fieldName ).val() ); - }); - }, - - /** - * Dismiss pointers for Custom HTML widget. - * - * @since 4.8.1 - * - * @param {Array} pointers Pointer IDs to dismiss. - * @returns {void} - */ - dismissPointers: function dismissPointers( pointers ) { - _.each( pointers, function( pointer ) { - wp.ajax.post( 'dismiss-wp-pointer', { - pointer: pointer - }); - component.dismissedPointers.push( pointer ); - }); - }, - - /** - * Open available widgets panel. - * - * @since 4.8.1 - * @returns {void} - */ - openAvailableWidgetsPanel: function openAvailableWidgetsPanel() { - var sidebarControl; - wp.customize.section.each( function( section ) { - if ( section.extended( wp.customize.Widgets.SidebarSection ) && section.expanded() ) { - sidebarControl = wp.customize.control( 'sidebars_widgets[' + section.params.sidebarId + ']' ); - } - }); - if ( ! sidebarControl ) { - return; - } - setTimeout( function() { // Timeout to prevent click event from causing panel to immediately collapse. - wp.customize.Widgets.availableWidgetsPanel.open( sidebarControl ); - wp.customize.Widgets.availableWidgetsPanel.$search.val( 'HTML' ).trigger( 'keyup' ); - }); - }, - - /** - * Update input fields from the sync fields. - * - * This function is called at the widget-updated and widget-synced events. - * A field will only be updated if it is not currently focused, to avoid - * overwriting content that the user is entering. - * - * @returns {void} - */ - updateFields: function updateFields() { - var control = this, syncInput; - - if ( ! control.fields.title.is( document.activeElement ) ) { - syncInput = control.syncContainer.find( '.sync-input.title' ); - control.fields.title.val( syncInput.val() ); - } - - syncInput = control.syncContainer.find( '.sync-input.text' ); - if ( control.fields.text.is( ':visible' ) ) { - if ( ! control.fields.text.is( document.activeElement ) ) { - control.fields.text.val( syncInput.val() ); - } - } else if ( control.editor && ! control.editorFocused && syncInput.val() !== control.fields.text.val() ) { - control.editor.setContent( wp.editor.autop( syncInput.val() ) ); - } - }, - - /** - * Initialize editor. - * - * @returns {void} - */ - initializeEditor: function initializeEditor() { - var control = this, changeDebounceDelay = 1000, id, textarea, triggerChangeIfDirty, restoreTextMode = false, needsTextareaChangeTrigger = false, previousValue; - textarea = control.fields.text; - id = textarea.attr( 'id' ); - previousValue = textarea.val(); - - /** - * Trigger change if dirty. - * - * @returns {void} - */ - triggerChangeIfDirty = function() { - var updateWidgetBuffer = 300; // See wp.customize.Widgets.WidgetControl._setupUpdateUI() which uses 250ms for updateWidgetDebounced. - if ( control.editor.isDirty() ) { - - /* - * Account for race condition in customizer where user clicks Save & Publish while - * focus was just previously given to the editor. Since updates to the editor - * are debounced at 1 second and since widget input changes are only synced to - * settings after 250ms, the customizer needs to be put into the processing - * state during the time between the change event is triggered and updateWidget - * logic starts. Note that the debounced update-widget request should be able - * to be removed with the removal of the update-widget request entirely once - * widgets are able to mutate their own instance props directly in JS without - * having to make server round-trips to call the respective WP_Widget::update() - * callbacks. See <https://core.trac.wordpress.org/ticket/33507>. - */ - if ( wp.customize && wp.customize.state ) { - wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() + 1 ); - _.delay( function() { - wp.customize.state( 'processing' ).set( wp.customize.state( 'processing' ).get() - 1 ); - }, updateWidgetBuffer ); - } - - if ( ! control.editor.isHidden() ) { - control.editor.save(); - } - } - - // Trigger change on textarea when it has changed so the widget can enter a dirty state. - if ( needsTextareaChangeTrigger && previousValue !== textarea.val() ) { - textarea.trigger( 'change' ); - needsTextareaChangeTrigger = false; - previousValue = textarea.val(); - } - }; - - // Just-in-time force-update the hidden input fields. - control.syncContainer.closest( '.widget' ).find( '[name=savewidget]:first' ).on( 'click', function onClickSaveButton() { - triggerChangeIfDirty(); - }); - - /** - * Build (or re-build) the visual editor. - * - * @returns {void} - */ - function buildEditor() { - var editor, onInit, showPointerElement; - - // Abort building if the textarea is gone, likely due to the widget having been deleted entirely. - if ( ! document.getElementById( id ) ) { - return; - } - - // The user has disabled TinyMCE. - if ( typeof window.tinymce === 'undefined' ) { - wp.editor.initialize( id, { - quicktags: true, - mediaButtons: true - }); - - return; - } - - // Destroy any existing editor so that it can be re-initialized after a widget-updated event. - if ( tinymce.get( id ) ) { - restoreTextMode = tinymce.get( id ).isHidden(); - wp.editor.remove( id ); - } - - // Add or enable the `wpview` plugin. - $( document ).one( 'wp-before-tinymce-init.text-widget-init', function( event, init ) { - // If somebody has removed all plugins, they must have a good reason. - // Keep it that way. - if ( ! init.plugins ) { - return; - } else if ( ! /\bwpview\b/.test( init.plugins ) ) { - init.plugins += ',wpview'; - } - } ); - - wp.editor.initialize( id, { - tinymce: { - wpautop: true - }, - quicktags: true, - mediaButtons: true - }); - - /** - * Show a pointer, focus on dismiss, and speak the contents for a11y. - * - * @param {jQuery} pointerElement Pointer element. - * @returns {void} - */ - showPointerElement = function( pointerElement ) { - pointerElement.show(); - pointerElement.find( '.close' ).focus(); - wp.a11y.speak( pointerElement.find( 'h3, p' ).map( function() { - return $( this ).text(); - } ).get().join( '\n\n' ) ); - }; - - editor = window.tinymce.get( id ); - if ( ! editor ) { - throw new Error( 'Failed to initialize editor' ); - } - onInit = function() { - - // When a widget is moved in the DOM the dynamically-created TinyMCE iframe will be destroyed and has to be re-built. - $( editor.getWin() ).on( 'unload', function() { - _.defer( buildEditor ); - }); - - // If a prior mce instance was replaced, and it was in text mode, toggle to text mode. - if ( restoreTextMode ) { - switchEditors.go( id, 'html' ); - } - - // Show the pointer. - $( '#' + id + '-html' ).on( 'click', function() { - control.pasteHtmlPointer.hide(); // Hide the HTML pasting pointer. - - if ( -1 !== component.dismissedPointers.indexOf( 'text_widget_custom_html' ) ) { - return; - } - showPointerElement( control.customHtmlWidgetPointer ); - }); - - // Hide the pointer when switching tabs. - $( '#' + id + '-tmce' ).on( 'click', function() { - control.customHtmlWidgetPointer.hide(); - }); - - // Show pointer when pasting HTML. - editor.on( 'pastepreprocess', function( event ) { - var content = event.content; - if ( -1 !== component.dismissedPointers.indexOf( 'text_widget_paste_html' ) || ! content || ! /<\w+.*?>/.test( content ) ) { - return; - } - - // Show the pointer after a slight delay so the user sees what they pasted. - _.delay( function() { - showPointerElement( control.pasteHtmlPointer ); - }, 250 ); - }); - }; - - if ( editor.initialized ) { - onInit(); - } else { - editor.on( 'init', onInit ); - } - - control.editorFocused = false; - - editor.on( 'focus', function onEditorFocus() { - control.editorFocused = true; - }); - editor.on( 'paste', function onEditorPaste() { - editor.setDirty( true ); // Because pasting doesn't currently set the dirty state. - triggerChangeIfDirty(); - }); - editor.on( 'NodeChange', function onNodeChange() { - needsTextareaChangeTrigger = true; - }); - editor.on( 'NodeChange', _.debounce( triggerChangeIfDirty, changeDebounceDelay ) ); - editor.on( 'blur hide', function onEditorBlur() { - control.editorFocused = false; - triggerChangeIfDirty(); - }); - - control.editor = editor; - } - - buildEditor(); - } - }); - - /** - * Mapping of widget ID to instances of TextWidgetControl subclasses. - * - * @memberOf wp.textWidgets - * - * @type {Object.<string, wp.textWidgets.TextWidgetControl>} - */ - component.widgetControls = {}; - - /** - * Handle widget being added or initialized for the first time at the widget-added event. - * - * @memberOf wp.textWidgets - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * - * @returns {void} - */ - component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) { - var widgetForm, idBase, widgetControl, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone, fieldContainer, syncContainer; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen. - - idBase = widgetForm.find( '> .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - // Prevent initializing already-added widgets. - widgetId = widgetForm.find( '.widget-id' ).val(); - if ( component.widgetControls[ widgetId ] ) { - return; - } - - // Bypass using TinyMCE when widget is in legacy mode. - if ( ! widgetForm.find( '.visual' ).val() ) { - return; - } - - /* - * Create a container element for the widget control fields. - * This is inserted into the DOM immediately before the .widget-content - * element because the contents of this element are essentially "managed" - * by PHP, where each widget update cause the entire element to be emptied - * and replaced with the rendered output of WP_Widget::form() which is - * sent back in Ajax request made to save/update the widget instance. - * To prevent a "flash of replaced DOM elements and re-initialized JS - * components", the JS template is rendered outside of the normal form - * container. - */ - fieldContainer = $( '<div></div>' ); - syncContainer = widgetContainer.find( '.widget-content:first' ); - syncContainer.before( fieldContainer ); - - widgetControl = new component.TextWidgetControl({ - el: fieldContainer, - syncContainer: syncContainer - }); - - component.widgetControls[ widgetId ] = widgetControl; - - /* - * Render the widget once the widget parent's container finishes animating, - * as the widget-added event fires with a slideDown of the container. - * This ensures that the textarea is visible and an iframe can be embedded - * with TinyMCE being able to set contenteditable on it. - */ - renderWhenAnimationDone = function() { - if ( ! widgetContainer.hasClass( 'open' ) ) { - setTimeout( renderWhenAnimationDone, animatedCheckDelay ); - } else { - widgetControl.initializeEditor(); - } - }; - renderWhenAnimationDone(); - }; - - /** - * Setup widget in accessibility mode. - * - * @memberOf wp.textWidgets - * - * @returns {void} - */ - component.setupAccessibleMode = function setupAccessibleMode() { - var widgetForm, idBase, widgetControl, fieldContainer, syncContainer; - widgetForm = $( '.editwidget > form' ); - if ( 0 === widgetForm.length ) { - return; - } - - idBase = widgetForm.find( '> .widget-control-actions > .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - // Bypass using TinyMCE when widget is in legacy mode. - if ( ! widgetForm.find( '.visual' ).val() ) { - return; - } - - fieldContainer = $( '<div></div>' ); - syncContainer = widgetForm.find( '> .widget-inside' ); - syncContainer.before( fieldContainer ); - - widgetControl = new component.TextWidgetControl({ - el: fieldContainer, - syncContainer: syncContainer - }); - - widgetControl.initializeEditor(); - }; - - /** - * Sync widget instance data sanitized from server back onto widget model. - * - * This gets called via the 'widget-updated' event when saving a widget from - * the widgets admin screen and also via the 'widget-synced' event when making - * a change to a widget in the customizer. - * - * @memberOf wp.textWidgets - * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. - * @returns {void} - */ - component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) { - var widgetForm, widgetId, widgetControl, idBase; - widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); - - idBase = widgetForm.find( '> .id_base' ).val(); - if ( -1 === component.idBases.indexOf( idBase ) ) { - return; - } - - widgetId = widgetForm.find( '> .widget-id' ).val(); - widgetControl = component.widgetControls[ widgetId ]; - if ( ! widgetControl ) { - return; - } - - widgetControl.updateFields(); - }; - - /** - * Initialize functionality. - * - * This function exists to prevent the JS file from having to boot itself. - * When WordPress enqueues this script, it should have an inline script - * attached which calls wp.textWidgets.init(). - * - * @memberOf wp.textWidgets - * - * @returns {void} - */ - component.init = function init() { - var $document = $( document ); - $document.on( 'widget-added', component.handleWidgetAdded ); - $document.on( 'widget-synced widget-updated', component.handleWidgetUpdated ); - - /* - * Manually trigger widget-added events for media widgets on the admin - * screen once they are expanded. The widget-added event is not triggered - * for each pre-existing widget on the widgets admin screen like it is - * on the customizer. Likewise, the customizer only triggers widget-added - * when the widget is expanded to just-in-time construct the widget form - * when it is actually going to be displayed. So the following implements - * the same for the widgets admin screen, to invoke the widget-added - * handler when a pre-existing media widget is expanded. - */ - $( function initializeExistingWidgetContainers() { - var widgetContainers; - if ( 'widgets' !== window.pagenow ) { - return; - } - widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' ); - widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() { - var widgetContainer = $( this ); - component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer ); - }); - - // Accessibility mode. - $( window ).on( 'load', function() { - component.setupAccessibleMode(); - }); - }); - }; - - return component; -})( jQuery ); diff --git a/srcs/wordpress/wp-admin/js/widgets/text-widgets.min.js b/srcs/wordpress/wp-admin/js/widgets/text-widgets.min.js deleted file mode 100644 index e886495..0000000 --- a/srcs/wordpress/wp-admin/js/widgets/text-widgets.min.js +++ /dev/null @@ -1 +0,0 @@ -wp.textWidgets=function(r){"use strict";var u={dismissedPointers:[],idBases:["text"]};return u.TextWidgetControl=Backbone.View.extend({events:{},initialize:function(t){var n=this;if(!t.el)throw new Error("Missing options.el");if(!t.syncContainer)throw new Error("Missing options.syncContainer");Backbone.View.prototype.initialize.call(n,t),n.syncContainer=t.syncContainer,n.$el.addClass("text-widget-fields"),n.$el.html(wp.template("widget-text-control-fields")),n.customHtmlWidgetPointer=n.$el.find(".wp-pointer.custom-html-widget-pointer"),n.customHtmlWidgetPointer.length&&(n.customHtmlWidgetPointer.find(".close").on("click",function(t){t.preventDefault(),n.customHtmlWidgetPointer.hide(),r("#"+n.fields.text.attr("id")+"-html").focus(),n.dismissPointers(["text_widget_custom_html"])}),n.customHtmlWidgetPointer.find(".add-widget").on("click",function(t){t.preventDefault(),n.customHtmlWidgetPointer.hide(),n.openAvailableWidgetsPanel()})),n.pasteHtmlPointer=n.$el.find(".wp-pointer.paste-html-pointer"),n.pasteHtmlPointer.length&&n.pasteHtmlPointer.find(".close").on("click",function(t){t.preventDefault(),n.pasteHtmlPointer.hide(),n.editor.focus(),n.dismissPointers(["text_widget_custom_html","text_widget_paste_html"])}),n.fields={title:n.$el.find(".title"),text:n.$el.find(".text")},_.each(n.fields,function(e,i){e.on("input change",function(){var t=n.syncContainer.find(".sync-input."+i);t.val()!==e.val()&&(t.val(e.val()),t.trigger("change"))}),e.val(n.syncContainer.find(".sync-input."+i).val())})},dismissPointers:function(t){_.each(t,function(t){wp.ajax.post("dismiss-wp-pointer",{pointer:t}),u.dismissedPointers.push(t)})},openAvailableWidgetsPanel:function(){var e;wp.customize.section.each(function(t){t.extended(wp.customize.Widgets.SidebarSection)&&t.expanded()&&(e=wp.customize.control("sidebars_widgets["+t.params.sidebarId+"]"))}),e&&setTimeout(function(){wp.customize.Widgets.availableWidgetsPanel.open(e),wp.customize.Widgets.availableWidgetsPanel.$search.val("HTML").trigger("keyup")})},updateFields:function(){var t,e=this;e.fields.title.is(document.activeElement)||(t=e.syncContainer.find(".sync-input.title"),e.fields.title.val(t.val())),t=e.syncContainer.find(".sync-input.text"),e.fields.text.is(":visible")?e.fields.text.is(document.activeElement)||e.fields.text.val(t.val()):e.editor&&!e.editorFocused&&t.val()!==e.fields.text.val()&&e.editor.setContent(wp.editor.autop(t.val()))},initializeEditor:function(){var d,t,o,e,s=this,a=1e3,l=!1,c=!1;t=s.fields.text,d=t.attr("id"),e=t.val(),o=function(){s.editor.isDirty()&&(wp.customize&&wp.customize.state&&(wp.customize.state("processing").set(wp.customize.state("processing").get()+1),_.delay(function(){wp.customize.state("processing").set(wp.customize.state("processing").get()-1)},300)),s.editor.isHidden()||s.editor.save()),c&&e!==t.val()&&(t.trigger("change"),c=!1,e=t.val())},s.syncContainer.closest(".widget").find("[name=savewidget]:first").on("click",function(){o()}),function t(){var e,i,n;if(document.getElementById(d))if(void 0!==window.tinymce){if(tinymce.get(d)&&(l=tinymce.get(d).isHidden(),wp.editor.remove(d)),r(document).one("wp-before-tinymce-init.text-widget-init",function(t,e){e.plugins&&(/\bwpview\b/.test(e.plugins)||(e.plugins+=",wpview"))}),wp.editor.initialize(d,{tinymce:{wpautop:!0},quicktags:!0,mediaButtons:!0}),n=function(t){t.show(),t.find(".close").focus(),wp.a11y.speak(t.find("h3, p").map(function(){return r(this).text()}).get().join("\n\n"))},!(e=window.tinymce.get(d)))throw new Error("Failed to initialize editor");i=function(){r(e.getWin()).on("unload",function(){_.defer(t)}),l&&switchEditors.go(d,"html"),r("#"+d+"-html").on("click",function(){s.pasteHtmlPointer.hide(),-1===u.dismissedPointers.indexOf("text_widget_custom_html")&&n(s.customHtmlWidgetPointer)}),r("#"+d+"-tmce").on("click",function(){s.customHtmlWidgetPointer.hide()}),e.on("pastepreprocess",function(t){var e=t.content;-1===u.dismissedPointers.indexOf("text_widget_paste_html")&&e&&/<\w+.*?>/.test(e)&&_.delay(function(){n(s.pasteHtmlPointer)},250)})},e.initialized?i():e.on("init",i),s.editorFocused=!1,e.on("focus",function(){s.editorFocused=!0}),e.on("paste",function(){e.setDirty(!0),o()}),e.on("NodeChange",function(){c=!0}),e.on("NodeChange",_.debounce(o,a)),e.on("blur hide",function(){s.editorFocused=!1,o()}),s.editor=e}else wp.editor.initialize(d,{quicktags:!0,mediaButtons:!0})}()}}),u.widgetControls={},u.handleWidgetAdded=function(t,e){var i,n,d,o,s,a,l;n=(i=e.find("> .widget-inside > .form, > .widget-inside > form")).find("> .id_base").val(),-1!==u.idBases.indexOf(n)&&(o=i.find(".widget-id").val(),u.widgetControls[o]||i.find(".visual").val()&&(a=r("<div></div>"),(l=e.find(".widget-content:first")).before(a),d=new u.TextWidgetControl({el:a,syncContainer:l}),u.widgetControls[o]=d,(s=function(){e.hasClass("open")?d.initializeEditor():setTimeout(s,50)})()))},u.setupAccessibleMode=function(){var t,e,i,n;0!==(t=r(".editwidget > form")).length&&(e=t.find("> .widget-control-actions > .id_base").val(),-1!==u.idBases.indexOf(e)&&t.find(".visual").val()&&(i=r("<div></div>"),(n=t.find("> .widget-inside")).before(i),new u.TextWidgetControl({el:i,syncContainer:n}).initializeEditor()))},u.handleWidgetUpdated=function(t,e){var i,n,d,o;o=(i=e.find("> .widget-inside > .form, > .widget-inside > form")).find("> .id_base").val(),-1!==u.idBases.indexOf(o)&&(n=i.find("> .widget-id").val(),(d=u.widgetControls[n])&&d.updateFields())},u.init=function(){var t=r(document);t.on("widget-added",u.handleWidgetAdded),t.on("widget-synced widget-updated",u.handleWidgetUpdated),r(function(){"widgets"===window.pagenow&&(r(".widgets-holder-wrap:not(#available-widgets)").find("div.widget").one("click.toggle-widget-expanded",function(){var t=r(this);u.handleWidgetAdded(new jQuery.Event("widget-added"),t)}),r(window).on("load",function(){u.setupAccessibleMode()}))})},u}(jQuery);
\ No newline at end of file |
