khaihihi
This commit is contained in:
94
wp-admin/js/accordion.js
Normal file
94
wp-admin/js/accordion.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Accordion-folding functionality.
|
||||
*
|
||||
* Markup with the appropriate classes will be automatically hidden,
|
||||
* with one section opening at a time when its title is clicked.
|
||||
* Use the following markup structure for accordion behavior:
|
||||
*
|
||||
* <div class="accordion-container">
|
||||
* <div class="accordion-section open">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="accordion-section">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="accordion-section">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* </div>
|
||||
*
|
||||
* Note that any appropriate tags may be used, as long as the above classes are present.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @output wp-admin/js/accordion.js
|
||||
*/
|
||||
|
||||
( function( $ ){
|
||||
|
||||
$( document ).ready( function () {
|
||||
|
||||
// Expand/Collapse accordion sections on click.
|
||||
$( '.accordion-container' ).on( 'click keydown', '.accordion-section-title', function( e ) {
|
||||
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault(); // Keep this AFTER the key filter above
|
||||
|
||||
accordionSwitch( $( this ) );
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Close the current accordion section and open a new one.
|
||||
*
|
||||
* @param {Object} el Title element of the accordion section to toggle.
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function accordionSwitch ( el ) {
|
||||
var section = el.closest( '.accordion-section' ),
|
||||
sectionToggleControl = section.find( '[aria-expanded]' ).first(),
|
||||
container = section.closest( '.accordion-container' ),
|
||||
siblings = container.find( '.open' ),
|
||||
siblingsToggleControl = siblings.find( '[aria-expanded]' ).first(),
|
||||
content = section.find( '.accordion-section-content' );
|
||||
|
||||
// This section has no content and cannot be expanded.
|
||||
if ( section.hasClass( 'cannot-expand' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a class to the container to let us know something is happening inside.
|
||||
// This helps in cases such as hiding a scrollbar while animations are executing.
|
||||
container.addClass( 'opening' );
|
||||
|
||||
if ( section.hasClass( 'open' ) ) {
|
||||
section.toggleClass( 'open' );
|
||||
content.toggle( true ).slideToggle( 150 );
|
||||
} else {
|
||||
siblingsToggleControl.attr( 'aria-expanded', 'false' );
|
||||
siblings.removeClass( 'open' );
|
||||
siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
|
||||
content.toggle( false ).slideToggle( 150 );
|
||||
section.toggleClass( 'open' );
|
||||
}
|
||||
|
||||
// We have to wait for the animations to finish
|
||||
setTimeout(function(){
|
||||
container.removeClass( 'opening' );
|
||||
}, 150);
|
||||
|
||||
// If there's an element with an aria-expanded attribute, assume it's a toggle control and toggle the aria-expanded value.
|
||||
if ( sectionToggleControl ) {
|
||||
sectionToggleControl.attr( 'aria-expanded', String( sectionToggleControl.attr( 'aria-expanded' ) === 'false' ) );
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
1
wp-admin/js/accordion.min.js
vendored
Normal file
1
wp-admin/js/accordion.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e(document).ready(function(){e(".accordion-container").on("click keydown",".accordion-section-title",function(n){"keydown"===n.type&&13!==n.which||(n.preventDefault(),function(n){var e=n.closest(".accordion-section"),o=e.find("[aria-expanded]").first(),a=e.closest(".accordion-container"),i=a.find(".open"),t=i.find("[aria-expanded]").first(),s=e.find(".accordion-section-content");if(e.hasClass("cannot-expand"))return;a.addClass("opening"),e.hasClass("open")?(e.toggleClass("open"),s.toggle(!0).slideToggle(150)):(t.attr("aria-expanded","false"),i.removeClass("open"),i.find(".accordion-section-content").show().slideUp(150),s.toggle(!1).slideToggle(150),e.toggleClass("open"));setTimeout(function(){a.removeClass("opening")},150),o&&o.attr("aria-expanded",String("false"===o.attr("aria-expanded")))}(e(this)))})})}(jQuery);
|
||||
342
wp-admin/js/code-editor.js
Normal file
342
wp-admin/js/code-editor.js
Normal file
@@ -0,0 +1,342 @@
|
||||
/**
|
||||
* @output wp-admin/js/code-editor.js
|
||||
*/
|
||||
|
||||
if ( 'undefined' === typeof window.wp ) {
|
||||
/**
|
||||
* @namespace wp
|
||||
*/
|
||||
window.wp = {};
|
||||
}
|
||||
if ( 'undefined' === typeof window.wp.codeEditor ) {
|
||||
/**
|
||||
* @namespace wp.codeEditor
|
||||
*/
|
||||
window.wp.codeEditor = {};
|
||||
}
|
||||
|
||||
( function( $, wp ) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Default settings for code editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @type {object}
|
||||
*/
|
||||
wp.codeEditor.defaultSettings = {
|
||||
codemirror: {},
|
||||
csslint: {},
|
||||
htmlhint: {},
|
||||
jshint: {},
|
||||
onTabNext: function() {},
|
||||
onTabPrevious: function() {},
|
||||
onChangeLintingErrors: function() {},
|
||||
onUpdateErrorNotice: function() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure linting.
|
||||
*
|
||||
* @param {CodeMirror} editor - Editor.
|
||||
* @param {object} settings - Code editor settings.
|
||||
* @param {object} settings.codeMirror - Settings for CodeMirror.
|
||||
* @param {Function} settings.onChangeLintingErrors - Callback for when there are changes to linting errors.
|
||||
* @param {Function} settings.onUpdateErrorNotice - Callback to update error notice.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function configureLinting( editor, settings ) { // eslint-disable-line complexity
|
||||
var currentErrorAnnotations = [], previouslyShownErrorAnnotations = [];
|
||||
|
||||
/**
|
||||
* Call the onUpdateErrorNotice if there are new errors to show.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function updateErrorNotice() {
|
||||
if ( settings.onUpdateErrorNotice && ! _.isEqual( currentErrorAnnotations, previouslyShownErrorAnnotations ) ) {
|
||||
settings.onUpdateErrorNotice( currentErrorAnnotations, editor );
|
||||
previouslyShownErrorAnnotations = currentErrorAnnotations;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lint options.
|
||||
*
|
||||
* @returns {object} Lint options.
|
||||
*/
|
||||
function getLintOptions() { // eslint-disable-line complexity
|
||||
var options = editor.getOption( 'lint' );
|
||||
|
||||
if ( ! options ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( true === options ) {
|
||||
options = {};
|
||||
} else if ( _.isObject( options ) ) {
|
||||
options = $.extend( {}, options );
|
||||
}
|
||||
|
||||
// Note that rules must be sent in the "deprecated" lint.options property to prevent linter from complaining about unrecognized options. See <https://github.com/codemirror/CodeMirror/pull/4944>.
|
||||
if ( ! options.options ) {
|
||||
options.options = {};
|
||||
}
|
||||
|
||||
// Configure JSHint.
|
||||
if ( 'javascript' === settings.codemirror.mode && settings.jshint ) {
|
||||
$.extend( options.options, settings.jshint );
|
||||
}
|
||||
|
||||
// Configure CSSLint.
|
||||
if ( 'css' === settings.codemirror.mode && settings.csslint ) {
|
||||
$.extend( options.options, settings.csslint );
|
||||
}
|
||||
|
||||
// Configure HTMLHint.
|
||||
if ( 'htmlmixed' === settings.codemirror.mode && settings.htmlhint ) {
|
||||
options.options.rules = $.extend( {}, settings.htmlhint );
|
||||
|
||||
if ( settings.jshint ) {
|
||||
options.options.rules.jshint = settings.jshint;
|
||||
}
|
||||
if ( settings.csslint ) {
|
||||
options.options.rules.csslint = settings.csslint;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the onUpdateLinting CodeMirror event to route to onChangeLintingErrors and onUpdateErrorNotice.
|
||||
options.onUpdateLinting = (function( onUpdateLintingOverridden ) {
|
||||
return function( annotations, annotationsSorted, cm ) {
|
||||
var errorAnnotations = _.filter( annotations, function( annotation ) {
|
||||
return 'error' === annotation.severity;
|
||||
} );
|
||||
|
||||
if ( onUpdateLintingOverridden ) {
|
||||
onUpdateLintingOverridden.apply( annotations, annotationsSorted, cm );
|
||||
}
|
||||
|
||||
// Skip if there are no changes to the errors.
|
||||
if ( _.isEqual( errorAnnotations, currentErrorAnnotations ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentErrorAnnotations = errorAnnotations;
|
||||
|
||||
if ( settings.onChangeLintingErrors ) {
|
||||
settings.onChangeLintingErrors( errorAnnotations, annotations, annotationsSorted, cm );
|
||||
}
|
||||
|
||||
/*
|
||||
* Update notifications when the editor is not focused to prevent error message
|
||||
* from overwhelming the user during input, unless there are now no errors or there
|
||||
* were previously errors shown. In these cases, update immediately so they can know
|
||||
* that they fixed the errors.
|
||||
*/
|
||||
if ( ! editor.state.focused || 0 === currentErrorAnnotations.length || previouslyShownErrorAnnotations.length > 0 ) {
|
||||
updateErrorNotice();
|
||||
}
|
||||
};
|
||||
})( options.onUpdateLinting );
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
editor.setOption( 'lint', getLintOptions() );
|
||||
|
||||
// Keep lint options populated.
|
||||
editor.on( 'optionChange', function( cm, option ) {
|
||||
var options, gutters, gutterName = 'CodeMirror-lint-markers';
|
||||
if ( 'lint' !== option ) {
|
||||
return;
|
||||
}
|
||||
gutters = editor.getOption( 'gutters' ) || [];
|
||||
options = editor.getOption( 'lint' );
|
||||
if ( true === options ) {
|
||||
if ( ! _.contains( gutters, gutterName ) ) {
|
||||
editor.setOption( 'gutters', [ gutterName ].concat( gutters ) );
|
||||
}
|
||||
editor.setOption( 'lint', getLintOptions() ); // Expand to include linting options.
|
||||
} else if ( ! options ) {
|
||||
editor.setOption( 'gutters', _.without( gutters, gutterName ) );
|
||||
}
|
||||
|
||||
// Force update on error notice to show or hide.
|
||||
if ( editor.getOption( 'lint' ) ) {
|
||||
editor.performLint();
|
||||
} else {
|
||||
currentErrorAnnotations = [];
|
||||
updateErrorNotice();
|
||||
}
|
||||
} );
|
||||
|
||||
// Update error notice when leaving the editor.
|
||||
editor.on( 'blur', updateErrorNotice );
|
||||
|
||||
// Work around hint selection with mouse causing focus to leave editor.
|
||||
editor.on( 'startCompletion', function() {
|
||||
editor.off( 'blur', updateErrorNotice );
|
||||
} );
|
||||
editor.on( 'endCompletion', function() {
|
||||
var editorRefocusWait = 500;
|
||||
editor.on( 'blur', updateErrorNotice );
|
||||
|
||||
// Wait for editor to possibly get re-focused after selection.
|
||||
_.delay( function() {
|
||||
if ( ! editor.state.focused ) {
|
||||
updateErrorNotice();
|
||||
}
|
||||
}, editorRefocusWait );
|
||||
});
|
||||
|
||||
/*
|
||||
* Make sure setting validities are set if the user tries to click Publish
|
||||
* while an autocomplete dropdown is still open. The Customizer will block
|
||||
* saving when a setting has an error notifications on it. This is only
|
||||
* necessary for mouse interactions because keyboards will have already
|
||||
* blurred the field and cause onUpdateErrorNotice to have already been
|
||||
* called.
|
||||
*/
|
||||
$( document.body ).on( 'mousedown', function( event ) {
|
||||
if ( editor.state.focused && ! $.contains( editor.display.wrapper, event.target ) && ! $( event.target ).hasClass( 'CodeMirror-hint' ) ) {
|
||||
updateErrorNotice();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure tabbing.
|
||||
*
|
||||
* @param {CodeMirror} codemirror - Editor.
|
||||
* @param {object} settings - Code editor settings.
|
||||
* @param {object} settings.codeMirror - Settings for CodeMirror.
|
||||
* @param {Function} settings.onTabNext - Callback to handle tabbing to the next tabbable element.
|
||||
* @param {Function} settings.onTabPrevious - Callback to handle tabbing to the previous tabbable element.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function configureTabbing( codemirror, settings ) {
|
||||
var $textarea = $( codemirror.getTextArea() );
|
||||
|
||||
codemirror.on( 'blur', function() {
|
||||
$textarea.data( 'next-tab-blurs', false );
|
||||
});
|
||||
codemirror.on( 'keydown', function onKeydown( editor, event ) {
|
||||
var tabKeyCode = 9, escKeyCode = 27;
|
||||
|
||||
// Take note of the ESC keypress so that the next TAB can focus outside the editor.
|
||||
if ( escKeyCode === event.keyCode ) {
|
||||
$textarea.data( 'next-tab-blurs', true );
|
||||
return;
|
||||
}
|
||||
|
||||
// Short-circuit if tab key is not being pressed or the tab key press should move focus.
|
||||
if ( tabKeyCode !== event.keyCode || ! $textarea.data( 'next-tab-blurs' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus on previous or next focusable item.
|
||||
if ( event.shiftKey ) {
|
||||
settings.onTabPrevious( codemirror, event );
|
||||
} else {
|
||||
settings.onTabNext( codemirror, event );
|
||||
}
|
||||
|
||||
// Reset tab state.
|
||||
$textarea.data( 'next-tab-blurs', false );
|
||||
|
||||
// Prevent tab character from being added.
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} wp.codeEditor~CodeEditorInstance
|
||||
* @property {object} settings - The code editor settings.
|
||||
* @property {CodeMirror} codemirror - The CodeMirror instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize Code Editor (CodeMirror) for an existing textarea.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {string|jQuery|Element} textarea - The HTML id, jQuery object, or DOM Element for the textarea that is used for the editor.
|
||||
* @param {object} [settings] - Settings to override defaults.
|
||||
* @param {Function} [settings.onChangeLintingErrors] - Callback for when the linting errors have changed.
|
||||
* @param {Function} [settings.onUpdateErrorNotice] - Callback for when error notice should be displayed.
|
||||
* @param {Function} [settings.onTabPrevious] - Callback to handle tabbing to the previous tabbable element.
|
||||
* @param {Function} [settings.onTabNext] - Callback to handle tabbing to the next tabbable element.
|
||||
* @param {object} [settings.codemirror] - Options for CodeMirror.
|
||||
* @param {object} [settings.csslint] - Rules for CSSLint.
|
||||
* @param {object} [settings.htmlhint] - Rules for HTMLHint.
|
||||
* @param {object} [settings.jshint] - Rules for JSHint.
|
||||
*
|
||||
* @returns {CodeEditorInstance} Instance.
|
||||
*/
|
||||
wp.codeEditor.initialize = function initialize( textarea, settings ) {
|
||||
var $textarea, codemirror, instanceSettings, instance;
|
||||
if ( 'string' === typeof textarea ) {
|
||||
$textarea = $( '#' + textarea );
|
||||
} else {
|
||||
$textarea = $( textarea );
|
||||
}
|
||||
|
||||
instanceSettings = $.extend( {}, wp.codeEditor.defaultSettings, settings );
|
||||
instanceSettings.codemirror = $.extend( {}, instanceSettings.codemirror );
|
||||
|
||||
codemirror = wp.CodeMirror.fromTextArea( $textarea[0], instanceSettings.codemirror );
|
||||
|
||||
configureLinting( codemirror, instanceSettings );
|
||||
|
||||
instance = {
|
||||
settings: instanceSettings,
|
||||
codemirror: codemirror
|
||||
};
|
||||
|
||||
if ( codemirror.showHint ) {
|
||||
codemirror.on( 'keyup', function( editor, event ) { // eslint-disable-line complexity
|
||||
var shouldAutocomplete, isAlphaKey = /^[a-zA-Z]$/.test( event.key ), lineBeforeCursor, innerMode, token;
|
||||
if ( codemirror.state.completionActive && isAlphaKey ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent autocompletion in string literals or comments.
|
||||
token = codemirror.getTokenAt( codemirror.getCursor() );
|
||||
if ( 'string' === token.type || 'comment' === token.type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
innerMode = wp.CodeMirror.innerMode( codemirror.getMode(), token.state ).mode.name;
|
||||
lineBeforeCursor = codemirror.doc.getLine( codemirror.doc.getCursor().line ).substr( 0, codemirror.doc.getCursor().ch );
|
||||
if ( 'html' === innerMode || 'xml' === innerMode ) {
|
||||
shouldAutocomplete =
|
||||
'<' === event.key ||
|
||||
'/' === event.key && 'tag' === token.type ||
|
||||
isAlphaKey && 'tag' === token.type ||
|
||||
isAlphaKey && 'attribute' === token.type ||
|
||||
'=' === token.string && token.state.htmlState && token.state.htmlState.tagName;
|
||||
} else if ( 'css' === innerMode ) {
|
||||
shouldAutocomplete =
|
||||
isAlphaKey ||
|
||||
':' === event.key ||
|
||||
' ' === event.key && /:\s+$/.test( lineBeforeCursor );
|
||||
} else if ( 'javascript' === innerMode ) {
|
||||
shouldAutocomplete = isAlphaKey || '.' === event.key;
|
||||
} else if ( 'clike' === innerMode && 'php' === codemirror.options.mode ) {
|
||||
shouldAutocomplete = 'keyword' === token.type || 'variable' === token.type;
|
||||
}
|
||||
if ( shouldAutocomplete ) {
|
||||
codemirror.showHint( { completeSingle: false } );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Facilitate tabbing out of the editor.
|
||||
configureTabbing( codemirror, settings );
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
})( window.jQuery, window.wp );
|
||||
1
wp-admin/js/code-editor.min.js
vendored
Normal file
1
wp-admin/js/code-editor.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
void 0===window.wp&&(window.wp={}),void 0===window.wp.codeEditor&&(window.wp.codeEditor={}),function(l,d){"use strict";d.codeEditor.defaultSettings={codemirror:{},csslint:{},htmlhint:{},jshint:{},onTabNext:function(){},onTabPrevious:function(){},onChangeLintingErrors:function(){},onUpdateErrorNotice:function(){}},d.codeEditor.initialize=function(t,n){var e,a,o,i;return e=l("string"==typeof t?"#"+t:t),(o=l.extend({},d.codeEditor.defaultSettings,n)).codemirror=l.extend({},o.codemirror),function(r,s){var a=[],d=[];function c(){s.onUpdateErrorNotice&&!_.isEqual(a,d)&&(s.onUpdateErrorNotice(a,r),d=a)}function u(){var i,t=r.getOption("lint");return!!t&&(!0===t?t={}:_.isObject(t)&&(t=l.extend({},t)),t.options||(t.options={}),"javascript"===s.codemirror.mode&&s.jshint&&l.extend(t.options,s.jshint),"css"===s.codemirror.mode&&s.csslint&&l.extend(t.options,s.csslint),"htmlmixed"===s.codemirror.mode&&s.htmlhint&&(t.options.rules=l.extend({},s.htmlhint),s.jshint&&(t.options.rules.jshint=s.jshint),s.csslint&&(t.options.rules.csslint=s.csslint)),t.onUpdateLinting=(i=t.onUpdateLinting,function(t,n,e){var o=_.filter(t,function(t){return"error"===t.severity});i&&i.apply(t,n,e),_.isEqual(o,a)||(a=o,s.onChangeLintingErrors&&s.onChangeLintingErrors(o,t,n,e),(!r.state.focused||0===a.length||0<d.length)&&c())}),t)}r.setOption("lint",u()),r.on("optionChange",function(t,n){var e,o,i="CodeMirror-lint-markers";"lint"===n&&(o=r.getOption("gutters")||[],!0===(e=r.getOption("lint"))?(_.contains(o,i)||r.setOption("gutters",[i].concat(o)),r.setOption("lint",u())):e||r.setOption("gutters",_.without(o,i)),r.getOption("lint")?r.performLint():(a=[],c()))}),r.on("blur",c),r.on("startCompletion",function(){r.off("blur",c)}),r.on("endCompletion",function(){r.on("blur",c),_.delay(function(){r.state.focused||c()},500)}),l(document.body).on("mousedown",function(t){!r.state.focused||l.contains(r.display.wrapper,t.target)||l(t.target).hasClass("CodeMirror-hint")||c()})}(a=d.CodeMirror.fromTextArea(e[0],o.codemirror),o),i={settings:o,codemirror:a},a.showHint&&a.on("keyup",function(t,n){var e,o,i,r,s=/^[a-zA-Z]$/.test(n.key);a.state.completionActive&&s||"string"!==(r=a.getTokenAt(a.getCursor())).type&&"comment"!==r.type&&(i=d.CodeMirror.innerMode(a.getMode(),r.state).mode.name,o=a.doc.getLine(a.doc.getCursor().line).substr(0,a.doc.getCursor().ch),"html"===i||"xml"===i?e="<"===n.key||"/"===n.key&&"tag"===r.type||s&&"tag"===r.type||s&&"attribute"===r.type||"="===r.string&&r.state.htmlState&&r.state.htmlState.tagName:"css"===i?e=s||":"===n.key||" "===n.key&&/:\s+$/.test(o):"javascript"===i?e=s||"."===n.key:"clike"===i&&"php"===a.options.mode&&(e="keyword"===r.type||"variable"===r.type),e&&a.showHint({completeSingle:!1}))}),function(e,o){var i=l(e.getTextArea());e.on("blur",function(){i.data("next-tab-blurs",!1)}),e.on("keydown",function(t,n){27!==n.keyCode?9===n.keyCode&&i.data("next-tab-blurs")&&(n.shiftKey?o.onTabPrevious(e,n):o.onTabNext(e,n),i.data("next-tab-blurs",!1),n.preventDefault()):i.data("next-tab-blurs",!0)})}(a,n),i}}(window.jQuery,window.wp);
|
||||
359
wp-admin/js/color-picker.js
Normal file
359
wp-admin/js/color-picker.js
Normal file
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* @output wp-admin/js/color-picker.js
|
||||
*/
|
||||
|
||||
/* global wpColorPickerL10n */
|
||||
( function( $, undef ) {
|
||||
|
||||
var ColorPicker,
|
||||
_before = '<button type="button" class="button wp-color-result" aria-expanded="false"><span class="wp-color-result-text"></span></button>',
|
||||
_after = '<div class="wp-picker-holder" />',
|
||||
_wrap = '<div class="wp-picker-container" />',
|
||||
_button = '<input type="button" class="button button-small" />',
|
||||
_wrappingLabel = '<label></label>',
|
||||
_wrappingLabelText = '<span class="screen-reader-text"></span>';
|
||||
|
||||
/**
|
||||
* Creates a jQuery UI color picker that is used in the theme customizer.
|
||||
*
|
||||
* @class $.widget.wp.wpColorPicker
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
ColorPicker = /** @lends $.widget.wp.wpColorPicker.prototype */{
|
||||
options: {
|
||||
defaultColor: false,
|
||||
change: false,
|
||||
clear: false,
|
||||
hide: true,
|
||||
palettes: true,
|
||||
width: 255,
|
||||
mode: 'hsv',
|
||||
type: 'full',
|
||||
slider: 'horizontal'
|
||||
},
|
||||
/**
|
||||
* Creates a color picker that only allows you to adjust the hue.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_createHueOnly: function() {
|
||||
var self = this,
|
||||
el = self.element,
|
||||
color;
|
||||
|
||||
el.hide();
|
||||
|
||||
// Set the saturation to the maximum level.
|
||||
color = 'hsl(' + el.val() + ', 100, 50)';
|
||||
|
||||
// Create an instance of the color picker, using the hsl mode.
|
||||
el.iris( {
|
||||
mode: 'hsl',
|
||||
type: 'hue',
|
||||
hide: false,
|
||||
color: color,
|
||||
/**
|
||||
* Handles the onChange event if one has been defined in the options.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
* @param {HTMLElement} ui The HTMLElement containing the color picker.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
change: function( event, ui ) {
|
||||
if ( $.isFunction( self.options.change ) ) {
|
||||
self.options.change.call( this, event, ui );
|
||||
}
|
||||
},
|
||||
width: self.options.width,
|
||||
slider: self.options.slider
|
||||
} );
|
||||
},
|
||||
/**
|
||||
* Creates the color picker, sets default values, css classes and wraps it all in HTML.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_create: function() {
|
||||
// Return early if Iris support is missing.
|
||||
if ( ! $.support.iris ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this,
|
||||
el = self.element;
|
||||
|
||||
// Override default options with options bound to the element.
|
||||
$.extend( self.options, el.data() );
|
||||
|
||||
// Create a color picker which only allows adjustments to the hue.
|
||||
if ( self.options.type === 'hue' ) {
|
||||
return self._createHueOnly();
|
||||
}
|
||||
|
||||
// Bind the close event.
|
||||
self.close = $.proxy( self.close, self );
|
||||
|
||||
self.initialValue = el.val();
|
||||
|
||||
// Add a CSS class to the input field.
|
||||
el.addClass( 'wp-color-picker' );
|
||||
|
||||
/*
|
||||
* Check if there's already a wrapping label, e.g. in the Customizer.
|
||||
* If there's no label, add a default one to match the Customizer template.
|
||||
*/
|
||||
if ( ! el.parent( 'label' ).length ) {
|
||||
// Wrap the input field in the default label.
|
||||
el.wrap( _wrappingLabel );
|
||||
// Insert the default label text.
|
||||
self.wrappingLabelText = $( _wrappingLabelText )
|
||||
.insertBefore( el )
|
||||
.text( wpColorPickerL10n.defaultLabel );
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, either it's the standalone version or the Customizer
|
||||
* one, we have a wrapping label to use as hook in the DOM, let's store it.
|
||||
*/
|
||||
self.wrappingLabel = el.parent();
|
||||
|
||||
// Wrap the label in the main wrapper.
|
||||
self.wrappingLabel.wrap( _wrap );
|
||||
// Store a reference to the main wrapper.
|
||||
self.wrap = self.wrappingLabel.parent();
|
||||
// Set up the toggle button and insert it before the wrapping label.
|
||||
self.toggler = $( _before )
|
||||
.insertBefore( self.wrappingLabel )
|
||||
.css( { backgroundColor: self.initialValue } );
|
||||
// Set the toggle button span element text.
|
||||
self.toggler.find( '.wp-color-result-text' ).text( wpColorPickerL10n.pick );
|
||||
// Set up the Iris container and insert it after the wrapping label.
|
||||
self.pickerContainer = $( _after ).insertAfter( self.wrappingLabel );
|
||||
// Store a reference to the Clear/Default button.
|
||||
self.button = $( _button );
|
||||
|
||||
// Set up the Clear/Default button.
|
||||
if ( self.options.defaultColor ) {
|
||||
self.button
|
||||
.addClass( 'wp-picker-default' )
|
||||
.val( wpColorPickerL10n.defaultString )
|
||||
.attr( 'aria-label', wpColorPickerL10n.defaultAriaLabel );
|
||||
} else {
|
||||
self.button
|
||||
.addClass( 'wp-picker-clear' )
|
||||
.val( wpColorPickerL10n.clear )
|
||||
.attr( 'aria-label', wpColorPickerL10n.clearAriaLabel );
|
||||
}
|
||||
|
||||
// Wrap the wrapping label in its wrapper and append the Clear/Default button.
|
||||
self.wrappingLabel
|
||||
.wrap( '<span class="wp-picker-input-wrap hidden" />' )
|
||||
.after( self.button );
|
||||
|
||||
/*
|
||||
* The input wrapper now contains the label+input+Clear/Default button.
|
||||
* Store a reference to the input wrapper: we'll use this to toggle
|
||||
* the controls visibility.
|
||||
*/
|
||||
self.inputWrapper = el.closest( '.wp-picker-input-wrap' );
|
||||
|
||||
el.iris( {
|
||||
target: self.pickerContainer,
|
||||
hide: self.options.hide,
|
||||
width: self.options.width,
|
||||
mode: self.options.mode,
|
||||
palettes: self.options.palettes,
|
||||
/**
|
||||
* Handles the onChange event if one has been defined in the options and additionally
|
||||
* sets the background color for the toggler element.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
* @param {HTMLElement} ui The HTMLElement containing the color picker.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
change: function( event, ui ) {
|
||||
self.toggler.css( { backgroundColor: ui.color.toString() } );
|
||||
|
||||
if ( $.isFunction( self.options.change ) ) {
|
||||
self.options.change.call( this, event, ui );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
el.val( self.initialValue );
|
||||
self._addListeners();
|
||||
|
||||
// Force the color picker to always be closed on initial load.
|
||||
if ( ! self.options.hide ) {
|
||||
self.toggler.click();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Binds event listeners to the color picker.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_addListeners: function() {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Prevent any clicks inside this widget from leaking to the top and closing it.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returs {void}
|
||||
*/
|
||||
self.wrap.on( 'click.wpcolorpicker', function( event ) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Open or close the color picker depending on the class.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
self.toggler.click( function(){
|
||||
if ( self.toggler.hasClass( 'wp-picker-open' ) ) {
|
||||
self.close();
|
||||
} else {
|
||||
self.open();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if value is empty when changing the color in the color picker.
|
||||
* If so, the background color is cleared.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
self.element.change( function( event ) {
|
||||
var me = $( this ),
|
||||
val = me.val();
|
||||
|
||||
if ( val === '' || val === '#' ) {
|
||||
self.toggler.css( 'backgroundColor', '' );
|
||||
// Fire clear callback if we have one.
|
||||
if ( $.isFunction( self.options.clear ) ) {
|
||||
self.options.clear.call( this, event );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Enables the user to either clear the color in the color picker or revert back to the default color.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
self.button.click( function( event ) {
|
||||
var me = $( this );
|
||||
if ( me.hasClass( 'wp-picker-clear' ) ) {
|
||||
self.element.val( '' );
|
||||
self.toggler.css( 'backgroundColor', '' );
|
||||
if ( $.isFunction( self.options.clear ) ) {
|
||||
self.options.clear.call( this, event );
|
||||
}
|
||||
} else if ( me.hasClass( 'wp-picker-default' ) ) {
|
||||
self.element.val( self.options.defaultColor ).change();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Opens the color picker dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
open: function() {
|
||||
this.element.iris( 'toggle' );
|
||||
this.inputWrapper.removeClass( 'hidden' );
|
||||
this.wrap.addClass( 'wp-picker-active' );
|
||||
this.toggler
|
||||
.addClass( 'wp-picker-open' )
|
||||
.attr( 'aria-expanded', 'true' );
|
||||
$( 'body' ).trigger( 'click.wpcolorpicker' ).on( 'click.wpcolorpicker', this.close );
|
||||
},
|
||||
/**
|
||||
* Closes the color picker dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
close: function() {
|
||||
this.element.iris( 'toggle' );
|
||||
this.inputWrapper.addClass( 'hidden' );
|
||||
this.wrap.removeClass( 'wp-picker-active' );
|
||||
this.toggler
|
||||
.removeClass( 'wp-picker-open' )
|
||||
.attr( 'aria-expanded', 'false' );
|
||||
$( 'body' ).off( 'click.wpcolorpicker', this.close );
|
||||
},
|
||||
/**
|
||||
* Returns the iris object if no new color is provided. If a new color is provided, it sets the new color.
|
||||
*
|
||||
* @param newColor {string|*} The new color to use. Can be undefined.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {string} The element's color
|
||||
*/
|
||||
color: function( newColor ) {
|
||||
if ( newColor === undef ) {
|
||||
return this.element.iris( 'option', 'color' );
|
||||
}
|
||||
this.element.iris( 'option', 'color', newColor );
|
||||
},
|
||||
/**
|
||||
* Returns the iris object if no new default color is provided.
|
||||
* If a new default color is provided, it sets the new default color.
|
||||
*
|
||||
* @param newDefaultColor {string|*} The new default color to use. Can be undefined.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {boolean|string} The element's color.
|
||||
*/
|
||||
defaultColor: function( newDefaultColor ) {
|
||||
if ( newDefaultColor === undef ) {
|
||||
return this.options.defaultColor;
|
||||
}
|
||||
|
||||
this.options.defaultColor = newDefaultColor;
|
||||
}
|
||||
};
|
||||
|
||||
// Register the color picker as a widget.
|
||||
$.widget( 'wp.wpColorPicker', ColorPicker );
|
||||
}( jQuery ) );
|
||||
1
wp-admin/js/color-picker.min.js
vendored
Normal file
1
wp-admin/js/color-picker.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(i,t){var e;e={options:{defaultColor:!1,change:!1,clear:!1,hide:!0,palettes:!0,width:255,mode:"hsv",type:"full",slider:"horizontal"},_createHueOnly:function(){var e,o=this,t=o.element;t.hide(),e="hsl("+t.val()+", 100, 50)",t.iris({mode:"hsl",type:"hue",hide:!1,color:e,change:function(e,t){i.isFunction(o.options.change)&&o.options.change.call(this,e,t)},width:o.options.width,slider:o.options.slider})},_create:function(){if(i.support.iris){var o=this,e=o.element;if(i.extend(o.options,e.data()),"hue"===o.options.type)return o._createHueOnly();o.close=i.proxy(o.close,o),o.initialValue=e.val(),e.addClass("wp-color-picker"),e.parent("label").length||(e.wrap("<label></label>"),o.wrappingLabelText=i('<span class="screen-reader-text"></span>').insertBefore(e).text(wpColorPickerL10n.defaultLabel)),o.wrappingLabel=e.parent(),o.wrappingLabel.wrap('<div class="wp-picker-container" />'),o.wrap=o.wrappingLabel.parent(),o.toggler=i('<button type="button" class="button wp-color-result" aria-expanded="false"><span class="wp-color-result-text"></span></button>').insertBefore(o.wrappingLabel).css({backgroundColor:o.initialValue}),o.toggler.find(".wp-color-result-text").text(wpColorPickerL10n.pick),o.pickerContainer=i('<div class="wp-picker-holder" />').insertAfter(o.wrappingLabel),o.button=i('<input type="button" class="button button-small" />'),o.options.defaultColor?o.button.addClass("wp-picker-default").val(wpColorPickerL10n.defaultString).attr("aria-label",wpColorPickerL10n.defaultAriaLabel):o.button.addClass("wp-picker-clear").val(wpColorPickerL10n.clear).attr("aria-label",wpColorPickerL10n.clearAriaLabel),o.wrappingLabel.wrap('<span class="wp-picker-input-wrap hidden" />').after(o.button),o.inputWrapper=e.closest(".wp-picker-input-wrap"),e.iris({target:o.pickerContainer,hide:o.options.hide,width:o.options.width,mode:o.options.mode,palettes:o.options.palettes,change:function(e,t){o.toggler.css({backgroundColor:t.color.toString()}),i.isFunction(o.options.change)&&o.options.change.call(this,e,t)}}),e.val(o.initialValue),o._addListeners(),o.options.hide||o.toggler.click()}},_addListeners:function(){var o=this;o.wrap.on("click.wpcolorpicker",function(e){e.stopPropagation()}),o.toggler.click(function(){o.toggler.hasClass("wp-picker-open")?o.close():o.open()}),o.element.change(function(e){var t=i(this).val();""!==t&&"#"!==t||(o.toggler.css("backgroundColor",""),i.isFunction(o.options.clear)&&o.options.clear.call(this,e))}),o.button.click(function(e){var t=i(this);t.hasClass("wp-picker-clear")?(o.element.val(""),o.toggler.css("backgroundColor",""),i.isFunction(o.options.clear)&&o.options.clear.call(this,e)):t.hasClass("wp-picker-default")&&o.element.val(o.options.defaultColor).change()})},open:function(){this.element.iris("toggle"),this.inputWrapper.removeClass("hidden"),this.wrap.addClass("wp-picker-active"),this.toggler.addClass("wp-picker-open").attr("aria-expanded","true"),i("body").trigger("click.wpcolorpicker").on("click.wpcolorpicker",this.close)},close:function(){this.element.iris("toggle"),this.inputWrapper.addClass("hidden"),this.wrap.removeClass("wp-picker-active"),this.toggler.removeClass("wp-picker-open").attr("aria-expanded","false"),i("body").off("click.wpcolorpicker",this.close)},color:function(e){if(e===t)return this.element.iris("option","color");this.element.iris("option","color",e)},defaultColor:function(e){if(e===t)return this.options.defaultColor;this.options.defaultColor=e}},i.widget("wp.wpColorPicker",e)}(jQuery);
|
||||
101
wp-admin/js/comment.js
Normal file
101
wp-admin/js/comment.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @output wp-admin/js/comment.js
|
||||
*/
|
||||
|
||||
/* global postboxes, commentL10n */
|
||||
|
||||
/**
|
||||
* Binds to the document ready event.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param {jQuery} $ The jQuery object.
|
||||
*/
|
||||
jQuery(document).ready( function($) {
|
||||
|
||||
postboxes.add_postbox_toggles('comment');
|
||||
|
||||
var $timestampdiv = $('#timestampdiv'),
|
||||
$timestamp = $( '#timestamp' ),
|
||||
stamp = $timestamp.html(),
|
||||
$timestampwrap = $timestampdiv.find( '.timestamp-wrap' ),
|
||||
$edittimestamp = $timestampdiv.siblings( 'a.edit-timestamp' );
|
||||
|
||||
/**
|
||||
* Adds event that opens the time stamp form if the form is hidden.
|
||||
*
|
||||
* @listens $edittimestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
$edittimestamp.click( function( event ) {
|
||||
if ( $timestampdiv.is( ':hidden' ) ) {
|
||||
// Slide down the form and set focus on the first field.
|
||||
$timestampdiv.slideDown( 'fast', function() {
|
||||
$( 'input, select', $timestampwrap ).first().focus();
|
||||
} );
|
||||
$(this).hide();
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Resets the time stamp values when the cancel button is clicked.
|
||||
*
|
||||
* @listens .cancel-timestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
$timestampdiv.find('.cancel-timestamp').click( function( event ) {
|
||||
// Move focus back to the Edit link.
|
||||
$edittimestamp.show().focus();
|
||||
$timestampdiv.slideUp( 'fast' );
|
||||
$('#mm').val($('#hidden_mm').val());
|
||||
$('#jj').val($('#hidden_jj').val());
|
||||
$('#aa').val($('#hidden_aa').val());
|
||||
$('#hh').val($('#hidden_hh').val());
|
||||
$('#mn').val($('#hidden_mn').val());
|
||||
$timestamp.html( stamp );
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the time stamp values when the ok button is clicked.
|
||||
*
|
||||
* @listens .save-timestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
$timestampdiv.find('.save-timestamp').click( function( event ) { // crazyhorse - multiple ok cancels
|
||||
var aa = $('#aa').val(), mm = $('#mm').val(), jj = $('#jj').val(), hh = $('#hh').val(), mn = $('#mn').val(),
|
||||
newD = new Date( aa, mm - 1, jj, hh, mn );
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( newD.getFullYear() != aa || (1 + newD.getMonth()) != mm || newD.getDate() != jj || newD.getMinutes() != mn ) {
|
||||
$timestampwrap.addClass( 'form-invalid' );
|
||||
return;
|
||||
} else {
|
||||
$timestampwrap.removeClass( 'form-invalid' );
|
||||
}
|
||||
|
||||
$timestamp.html(
|
||||
commentL10n.submittedOn + ' <b>' +
|
||||
commentL10n.dateFormat
|
||||
.replace( '%1$s', $( 'option[value="' + mm + '"]', '#mm' ).attr( 'data-text' ) )
|
||||
.replace( '%2$s', parseInt( jj, 10 ) )
|
||||
.replace( '%3$s', aa )
|
||||
.replace( '%4$s', ( '00' + hh ).slice( -2 ) )
|
||||
.replace( '%5$s', ( '00' + mn ).slice( -2 ) ) +
|
||||
'</b> '
|
||||
);
|
||||
|
||||
// Move focus back to the Edit link.
|
||||
$edittimestamp.show().focus();
|
||||
$timestampdiv.slideUp( 'fast' );
|
||||
});
|
||||
});
|
||||
1
wp-admin/js/comment.min.js
vendored
Normal file
1
wp-admin/js/comment.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(m){postboxes.add_postbox_toggles("comment");var d=m("#timestampdiv"),c=m("#timestamp"),a=c.html(),o=d.find(".timestamp-wrap"),v=d.siblings("a.edit-timestamp");v.click(function(e){d.is(":hidden")&&(d.slideDown("fast",function(){m("input, select",o).first().focus()}),m(this).hide()),e.preventDefault()}),d.find(".cancel-timestamp").click(function(e){v.show().focus(),d.slideUp("fast"),m("#mm").val(m("#hidden_mm").val()),m("#jj").val(m("#hidden_jj").val()),m("#aa").val(m("#hidden_aa").val()),m("#hh").val(m("#hidden_hh").val()),m("#mn").val(m("#hidden_mn").val()),c.html(a),e.preventDefault()}),d.find(".save-timestamp").click(function(e){var a=m("#aa").val(),t=m("#mm").val(),l=m("#jj").val(),i=m("#hh").val(),n=m("#mn").val(),s=new Date(a,t-1,l,i,n);e.preventDefault(),s.getFullYear()==a&&1+s.getMonth()==t&&s.getDate()==l&&s.getMinutes()==n?(o.removeClass("form-invalid"),c.html(commentL10n.submittedOn+" <b>"+commentL10n.dateFormat.replace("%1$s",m('option[value="'+t+'"]',"#mm").attr("data-text")).replace("%2$s",parseInt(l,10)).replace("%3$s",a).replace("%4$s",("00"+i).slice(-2)).replace("%5$s",("00"+n).slice(-2))+"</b> "),v.show().focus(),d.slideUp("fast")):o.addClass("form-invalid")})});
|
||||
1648
wp-admin/js/common.js
Normal file
1648
wp-admin/js/common.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/common.min.js
vendored
Normal file
1
wp-admin/js/common.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
145
wp-admin/js/custom-background.js
Normal file
145
wp-admin/js/custom-background.js
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @output wp-admin/js/custom-background.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Registers all events for customizing the background.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
var frame,
|
||||
bgImage = $( '#custom-background-image' );
|
||||
|
||||
/**
|
||||
* Instantiates the WordPress color picker and binds the change and clear events.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#background-color').wpColorPicker({
|
||||
change: function( event, ui ) {
|
||||
bgImage.css('background-color', ui.color.toString());
|
||||
},
|
||||
clear: function() {
|
||||
bgImage.css('background-color', '');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background size CSS property whenever the background size input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'select[name="background-size"]' ).change( function() {
|
||||
bgImage.css( 'background-size', $( this ).val() );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background position CSS property whenever the background position input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-position"]' ).change( function() {
|
||||
bgImage.css( 'background-position', $( this ).val() );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background repeat CSS property whenever the background repeat input has changed.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-repeat"]' ).change( function() {
|
||||
bgImage.css( 'background-repeat', $( this ).is( ':checked' ) ? 'repeat' : 'no-repeat' );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background attachment CSS property whenever the background attachment input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-attachment"]' ).change( function() {
|
||||
bgImage.css( 'background-attachment', $( this ).is( ':checked' ) ? 'scroll' : 'fixed' );
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds the event for opening the WP Media dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#choose-from-library-link').click( function( event ) {
|
||||
var $el = $(this);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media.frames.customBackground = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: $el.data('choose'),
|
||||
|
||||
// Tell the modal to show only images.
|
||||
library: {
|
||||
type: 'image'
|
||||
},
|
||||
|
||||
// Customize the submit button.
|
||||
button: {
|
||||
// Set the text of the button.
|
||||
text: $el.data('update'),
|
||||
/*
|
||||
* Tell the button not to close the modal, since we're
|
||||
* going to refresh the page when the image is selected.
|
||||
*/
|
||||
close: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* When an image is selected, run a callback.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
frame.on( 'select', function() {
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get('selection').first();
|
||||
|
||||
// Run an AJAX request to set the background image.
|
||||
$.post( ajaxurl, {
|
||||
action: 'set-background-image',
|
||||
attachment_id: attachment.id,
|
||||
size: 'full'
|
||||
}).done( function() {
|
||||
// When the request completes, reload the window.
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
// Finally, open the modal.
|
||||
frame.open();
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
1
wp-admin/js/custom-background.min.js
vendored
Normal file
1
wp-admin/js/custom-background.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e(document).ready(function(){var o,t=e("#custom-background-image");e("#background-color").wpColorPicker({change:function(n,c){t.css("background-color",c.color.toString())},clear:function(){t.css("background-color","")}}),e('select[name="background-size"]').change(function(){t.css("background-size",e(this).val())}),e('input[name="background-position"]').change(function(){t.css("background-position",e(this).val())}),e('input[name="background-repeat"]').change(function(){t.css("background-repeat",e(this).is(":checked")?"repeat":"no-repeat")}),e('input[name="background-attachment"]').change(function(){t.css("background-attachment",e(this).is(":checked")?"scroll":"fixed")}),e("#choose-from-library-link").click(function(n){var c=e(this);n.preventDefault(),o||(o=wp.media.frames.customBackground=wp.media({title:c.data("choose"),library:{type:"image"},button:{text:c.data("update"),close:!1}})).on("select",function(){var n=o.state().get("selection").first();e.post(ajaxurl,{action:"set-background-image",attachment_id:n.id,size:"full"}).done(function(){window.location.reload()})}),o.open()})})}(jQuery);
|
||||
88
wp-admin/js/custom-header.js
Normal file
88
wp-admin/js/custom-header.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @output wp-admin/js/custom-header.js
|
||||
*/
|
||||
|
||||
/* global isRtl */
|
||||
|
||||
/**
|
||||
* Initializes the custom header selection page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @deprecated 4.1.0 The page this is used on is never linked to from the UI.
|
||||
* Setting a custom header is completely handled by the Customizer.
|
||||
*/
|
||||
(function($) {
|
||||
var frame;
|
||||
|
||||
$( function() {
|
||||
// Fetch available headers.
|
||||
var $headers = $('.available-headers');
|
||||
|
||||
// Apply jQuery.masonry once the images have loaded.
|
||||
$headers.imagesLoaded( function() {
|
||||
$headers.masonry({
|
||||
itemSelector: '.default-header',
|
||||
isRTL: !! ( 'undefined' != typeof isRtl && isRtl )
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Opens the 'choose from library' frame and creates it if it doesn't exist.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @deprecated 4.1.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#choose-from-library-link').click( function( event ) {
|
||||
var $el = $(this);
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media.frames.customHeader = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: $el.data('choose'),
|
||||
|
||||
// Tell the modal to show only images.
|
||||
library: {
|
||||
type: 'image'
|
||||
},
|
||||
|
||||
// Customize the submit button.
|
||||
button: {
|
||||
// Set the text of the button.
|
||||
text: $el.data('update'),
|
||||
// Tell the button not to close the modal, since we're
|
||||
// going to refresh the page when the image is selected.
|
||||
close: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates the window location to include the selected attachment.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @deprecated 4.1.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
frame.on( 'select', function() {
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get('selection').first(),
|
||||
link = $el.data('updateLink');
|
||||
|
||||
// Tell the browser to navigate to the crop step.
|
||||
window.location = link + '&file=' + attachment.id;
|
||||
});
|
||||
|
||||
frame.open();
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
||||
9270
wp-admin/js/customize-controls.js
Normal file
9270
wp-admin/js/customize-controls.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/customize-controls.min.js
vendored
Normal file
1
wp-admin/js/customize-controls.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3463
wp-admin/js/customize-nav-menus.js
Normal file
3463
wp-admin/js/customize-nav-menus.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/customize-nav-menus.min.js
vendored
Normal file
1
wp-admin/js/customize-nav-menus.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2368
wp-admin/js/customize-widgets.js
Normal file
2368
wp-admin/js/customize-widgets.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/customize-widgets.min.js
vendored
Normal file
1
wp-admin/js/customize-widgets.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
593
wp-admin/js/dashboard.js
Normal file
593
wp-admin/js/dashboard.js
Normal file
@@ -0,0 +1,593 @@
|
||||
/**
|
||||
* @output wp-admin/js/dashboard.js
|
||||
*/
|
||||
|
||||
/* global pagenow, ajaxurl, postboxes, wpActiveEditor:true, ajaxWidgets */
|
||||
/* global ajaxPopulateWidgets, quickPressLoad, */
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Initializes the dashboard widget functionality.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
jQuery(document).ready( function($) {
|
||||
var welcomePanel = $( '#welcome-panel' ),
|
||||
welcomePanelHide = $('#wp_welcome_panel-hide'),
|
||||
updateWelcomePanel;
|
||||
|
||||
/**
|
||||
* Saves the visibility of the welcome panel.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param {boolean} visible Should it be visible or not.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
updateWelcomePanel = function( visible ) {
|
||||
$.post( ajaxurl, {
|
||||
action: 'update-welcome-panel',
|
||||
visible: visible,
|
||||
welcomepanelnonce: $( '#welcomepanelnonce' ).val()
|
||||
});
|
||||
};
|
||||
|
||||
// Unhide the welcome panel if the Welcome Option checkbox is checked.
|
||||
if ( welcomePanel.hasClass('hidden') && welcomePanelHide.prop('checked') ) {
|
||||
welcomePanel.removeClass('hidden');
|
||||
}
|
||||
|
||||
// Hide the welcome panel when the dismiss button or close button is clicked.
|
||||
$('.welcome-panel-close, .welcome-panel-dismiss a', welcomePanel).click( function(e) {
|
||||
e.preventDefault();
|
||||
welcomePanel.addClass('hidden');
|
||||
updateWelcomePanel( 0 );
|
||||
$('#wp_welcome_panel-hide').prop('checked', false);
|
||||
});
|
||||
|
||||
// Set welcome panel visibility based on Welcome Option checkbox value.
|
||||
welcomePanelHide.click( function() {
|
||||
welcomePanel.toggleClass('hidden', ! this.checked );
|
||||
updateWelcomePanel( this.checked ? 1 : 0 );
|
||||
});
|
||||
|
||||
/**
|
||||
* These widgets can be populated via ajax.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @type {string[]}
|
||||
*
|
||||
* @global
|
||||
*/
|
||||
window.ajaxWidgets = ['dashboard_primary'];
|
||||
|
||||
/**
|
||||
* Triggers widget updates via AJAX.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @param {string} el Optional. Widget to fetch or none to update all.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
window.ajaxPopulateWidgets = function(el) {
|
||||
/**
|
||||
* Fetch the latest representation of the widget via Ajax and show it.
|
||||
*
|
||||
* @param {number} i Number of half-seconds to use as the timeout.
|
||||
* @param {string} id ID of the element which is going to be checked for changes.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function show(i, id) {
|
||||
var p, e = $('#' + id + ' div.inside:visible').find('.widget-loading');
|
||||
// If the element is found in the dom, queue to load latest representation.
|
||||
if ( e.length ) {
|
||||
p = e.parent();
|
||||
setTimeout( function(){
|
||||
// Request the widget content.
|
||||
p.load( ajaxurl + '?action=dashboard-widgets&widget=' + id + '&pagenow=' + pagenow, '', function() {
|
||||
// Hide the parent and slide it out for visual fancyness.
|
||||
p.hide().slideDown('normal', function(){
|
||||
$(this).css('display', '');
|
||||
});
|
||||
});
|
||||
}, i * 500 );
|
||||
}
|
||||
}
|
||||
|
||||
// If we have received a specific element to fetch, check if it is valid.
|
||||
if ( el ) {
|
||||
el = el.toString();
|
||||
// If the element is available as AJAX widget, show it.
|
||||
if ( $.inArray(el, ajaxWidgets) !== -1 ) {
|
||||
// Show element without any delay.
|
||||
show(0, el);
|
||||
}
|
||||
} else {
|
||||
// Walk through all ajaxWidgets, loading them after each other.
|
||||
$.each( ajaxWidgets, show );
|
||||
}
|
||||
};
|
||||
|
||||
// Initially populate ajax widgets.
|
||||
ajaxPopulateWidgets();
|
||||
|
||||
// Register ajax widgets as postbox toggles.
|
||||
postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );
|
||||
|
||||
/**
|
||||
* Control the Quick Press (Quick Draft) widget.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
window.quickPressLoad = function() {
|
||||
var act = $('#quickpost-action'), t;
|
||||
|
||||
// Enable the submit buttons.
|
||||
$( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );
|
||||
|
||||
t = $('#quick-press').submit( function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
// Show a spinner.
|
||||
$('#dashboard_quick_press #publishing-action .spinner').show();
|
||||
|
||||
// Disable the submit button to prevent duplicate submissions.
|
||||
$('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);
|
||||
|
||||
// Post the entered data to save it.
|
||||
$.post( t.attr( 'action' ), t.serializeArray(), function( data ) {
|
||||
// Replace the form, and prepend the published post.
|
||||
$('#dashboard_quick_press .inside').html( data );
|
||||
$('#quick-press').removeClass('initial-form');
|
||||
quickPressLoad();
|
||||
highlightLatestPost();
|
||||
|
||||
// Focus the title to allow for quickly drafting another post.
|
||||
$('#title').focus();
|
||||
});
|
||||
|
||||
/**
|
||||
* Highlights the latest post for one second.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function highlightLatestPost () {
|
||||
var latestPost = $('.drafts ul li').first();
|
||||
latestPost.css('background', '#fffbe5');
|
||||
setTimeout(function () {
|
||||
latestPost.css('background', 'none');
|
||||
}, 1000);
|
||||
}
|
||||
} );
|
||||
|
||||
// Change the QuickPost action to the publish value.
|
||||
$('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );
|
||||
|
||||
$('#quick-press').on( 'click focusin', function() {
|
||||
wpActiveEditor = 'content';
|
||||
});
|
||||
|
||||
autoResizeTextarea();
|
||||
};
|
||||
window.quickPressLoad();
|
||||
|
||||
// Enable the dragging functionality of the widgets.
|
||||
$( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );
|
||||
|
||||
/**
|
||||
* Adjust the height of the textarea based on the content.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function autoResizeTextarea() {
|
||||
// When IE8 or older is used to render this document, exit.
|
||||
if ( document.documentMode && document.documentMode < 9 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a hidden div. We'll copy over the text from the textarea to measure its height.
|
||||
$('body').append( '<div class="quick-draft-textarea-clone" style="display: none;"></div>' );
|
||||
|
||||
var clone = $('.quick-draft-textarea-clone'),
|
||||
editor = $('#content'),
|
||||
editorHeight = editor.height(),
|
||||
/*
|
||||
* 100px roughly accounts for browser chrome and allows the
|
||||
* save draft button to show on-screen at the same time.
|
||||
*/
|
||||
editorMaxHeight = $(window).height() - 100;
|
||||
|
||||
/*
|
||||
* Match up textarea and clone div as much as possible.
|
||||
* Padding cannot be reliably retrieved using shorthand in all browsers.
|
||||
*/
|
||||
clone.css({
|
||||
'font-family': editor.css('font-family'),
|
||||
'font-size': editor.css('font-size'),
|
||||
'line-height': editor.css('line-height'),
|
||||
'padding-bottom': editor.css('paddingBottom'),
|
||||
'padding-left': editor.css('paddingLeft'),
|
||||
'padding-right': editor.css('paddingRight'),
|
||||
'padding-top': editor.css('paddingTop'),
|
||||
'white-space': 'pre-wrap',
|
||||
'word-wrap': 'break-word',
|
||||
'display': 'none'
|
||||
});
|
||||
|
||||
// The 'propertychange' is used in IE < 9.
|
||||
editor.on('focus input propertychange', function() {
|
||||
var $this = $(this),
|
||||
// Add a non-breaking space to ensure that the height of a trailing newline is
|
||||
// included.
|
||||
textareaContent = $this.val() + ' ',
|
||||
// Add 2px to compensate for border-top & border-bottom.
|
||||
cloneHeight = clone.css('width', $this.css('width')).text(textareaContent).outerHeight() + 2;
|
||||
|
||||
// Default to show a vertical scrollbar, if needed.
|
||||
editor.css('overflow-y', 'auto');
|
||||
|
||||
// Only change the height if it has changed and both heights are below the max.
|
||||
if ( cloneHeight === editorHeight || ( cloneHeight >= editorMaxHeight && editorHeight >= editorMaxHeight ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow editor to exceed the height of the window.
|
||||
* This is also bound in CSS to a max-height of 1300px to be extra safe.
|
||||
*/
|
||||
if ( cloneHeight > editorMaxHeight ) {
|
||||
editorHeight = editorMaxHeight;
|
||||
} else {
|
||||
editorHeight = cloneHeight;
|
||||
}
|
||||
|
||||
// Disable scrollbars because we adjust the height to the content.
|
||||
editor.css('overflow', 'hidden');
|
||||
|
||||
$this.css('height', editorHeight + 'px');
|
||||
});
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
jQuery( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var communityEventsData = window.communityEventsData || {},
|
||||
app;
|
||||
|
||||
/**
|
||||
* Global Community Events namespace.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @memberOf wp
|
||||
* @namespace wp.communityEvents
|
||||
*/
|
||||
app = window.wp.communityEvents = /** @lends wp.communityEvents */{
|
||||
initialized: false,
|
||||
model: null,
|
||||
|
||||
/**
|
||||
* Initializes the wp.communityEvents object.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
init: function() {
|
||||
if ( app.initialized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $container = $( '#community-events' );
|
||||
|
||||
/*
|
||||
* When JavaScript is disabled, the errors container is shown, so
|
||||
* that "This widget requires JavaScript" message can be seen.
|
||||
*
|
||||
* When JS is enabled, the container is hidden at first, and then
|
||||
* revealed during the template rendering, if there actually are
|
||||
* errors to show.
|
||||
*
|
||||
* The display indicator switches from `hide-if-js` to `aria-hidden`
|
||||
* here in order to maintain consistency with all the other fields
|
||||
* that key off of `aria-hidden` to determine their visibility.
|
||||
* `aria-hidden` can't be used initially, because there would be no
|
||||
* way to set it to false when JavaScript is disabled, which would
|
||||
* prevent people from seeing the "This widget requires JavaScript"
|
||||
* message.
|
||||
*/
|
||||
$( '.community-events-errors' )
|
||||
.attr( 'aria-hidden', 'true' )
|
||||
.removeClass( 'hide-if-js' );
|
||||
|
||||
$container.on( 'click', '.community-events-toggle-location, .community-events-cancel', app.toggleLocationForm );
|
||||
|
||||
/**
|
||||
* Filters events based on entered location.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$container.on( 'submit', '.community-events-form', function( event ) {
|
||||
var location = $.trim( $( '#community-events-location' ).val() );
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
/*
|
||||
* Don't trigger a search if the search field is empty or the
|
||||
* search term was made of only spaces before being trimmed.
|
||||
*/
|
||||
if ( ! location ) {
|
||||
return;
|
||||
}
|
||||
|
||||
app.getEvents({
|
||||
location: location
|
||||
});
|
||||
});
|
||||
|
||||
if ( communityEventsData && communityEventsData.cache && communityEventsData.cache.location && communityEventsData.cache.events ) {
|
||||
app.renderEventsTemplate( communityEventsData.cache, 'app' );
|
||||
} else {
|
||||
app.getEvents();
|
||||
}
|
||||
|
||||
app.initialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the Edit Location form.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param {event|string} action 'show' or 'hide' to specify a state;
|
||||
* or an event object to flip between states.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
toggleLocationForm: function( action ) {
|
||||
var $toggleButton = $( '.community-events-toggle-location' ),
|
||||
$cancelButton = $( '.community-events-cancel' ),
|
||||
$form = $( '.community-events-form' ),
|
||||
$target = $();
|
||||
|
||||
if ( 'object' === typeof action ) {
|
||||
// The action is the event object: get the clicked element.
|
||||
$target = $( action.target );
|
||||
/*
|
||||
* Strict comparison doesn't work in this case because sometimes
|
||||
* we explicitly pass a string as value of aria-expanded and
|
||||
* sometimes a boolean as the result of an evaluation.
|
||||
*/
|
||||
action = 'true' == $toggleButton.attr( 'aria-expanded' ) ? 'hide' : 'show';
|
||||
}
|
||||
|
||||
if ( 'hide' === action ) {
|
||||
$toggleButton.attr( 'aria-expanded', 'false' );
|
||||
$cancelButton.attr( 'aria-expanded', 'false' );
|
||||
$form.attr( 'aria-hidden', 'true' );
|
||||
/*
|
||||
* If the Cancel button has been clicked, bring the focus back
|
||||
* to the toggle button so users relying on screen readers don't
|
||||
* lose their place.
|
||||
*/
|
||||
if ( $target.hasClass( 'community-events-cancel' ) ) {
|
||||
$toggleButton.focus();
|
||||
}
|
||||
} else {
|
||||
$toggleButton.attr( 'aria-expanded', 'true' );
|
||||
$cancelButton.attr( 'aria-expanded', 'true' );
|
||||
$form.attr( 'aria-hidden', 'false' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends REST API requests to fetch events for the widget.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param {Object} requestParams REST API Request parameters object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
getEvents: function( requestParams ) {
|
||||
var initiatedBy,
|
||||
app = this,
|
||||
$spinner = $( '.community-events-form' ).children( '.spinner' );
|
||||
|
||||
requestParams = requestParams || {};
|
||||
requestParams._wpnonce = communityEventsData.nonce;
|
||||
requestParams.timezone = window.Intl ? window.Intl.DateTimeFormat().resolvedOptions().timeZone : '';
|
||||
|
||||
initiatedBy = requestParams.location ? 'user' : 'app';
|
||||
|
||||
$spinner.addClass( 'is-active' );
|
||||
|
||||
wp.ajax.post( 'get-community-events', requestParams )
|
||||
.always( function() {
|
||||
$spinner.removeClass( 'is-active' );
|
||||
})
|
||||
|
||||
.done( function( response ) {
|
||||
if ( 'no_location_available' === response.error ) {
|
||||
if ( requestParams.location ) {
|
||||
response.unknownCity = requestParams.location;
|
||||
} else {
|
||||
/*
|
||||
* No location was passed, which means that this was an automatic query
|
||||
* based on IP, locale, and timezone. Since the user didn't initiate it,
|
||||
* it should fail silently. Otherwise, the error could confuse and/or
|
||||
* annoy them.
|
||||
*/
|
||||
delete response.error;
|
||||
}
|
||||
}
|
||||
app.renderEventsTemplate( response, initiatedBy );
|
||||
})
|
||||
|
||||
.fail( function() {
|
||||
app.renderEventsTemplate({
|
||||
'location' : false,
|
||||
'error' : true
|
||||
}, initiatedBy );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the template for the Events section of the Events & News widget.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param {Object} templateParams The various parameters that will get passed to wp.template.
|
||||
* @param {string} initiatedBy 'user' to indicate that this was triggered manually by the user;
|
||||
* 'app' to indicate it was triggered automatically by the app itself.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
renderEventsTemplate: function( templateParams, initiatedBy ) {
|
||||
var template,
|
||||
elementVisibility,
|
||||
l10nPlaceholder = /%(?:\d\$)?s/g, // Match `%s`, `%1$s`, `%2$s`, etc.
|
||||
$toggleButton = $( '.community-events-toggle-location' ),
|
||||
$locationMessage = $( '#community-events-location-message' ),
|
||||
$results = $( '.community-events-results' );
|
||||
|
||||
/*
|
||||
* Hide all toggleable elements by default, to keep the logic simple.
|
||||
* Otherwise, each block below would have to turn hide everything that
|
||||
* could have been shown at an earlier point.
|
||||
*
|
||||
* The exception to that is that the .community-events container is hidden
|
||||
* when the page is first loaded, because the content isn't ready yet,
|
||||
* but once we've reached this point, it should always be shown.
|
||||
*/
|
||||
elementVisibility = {
|
||||
'.community-events' : true,
|
||||
'.community-events-loading' : false,
|
||||
'.community-events-errors' : false,
|
||||
'.community-events-error-occurred' : false,
|
||||
'.community-events-could-not-locate' : false,
|
||||
'#community-events-location-message' : false,
|
||||
'.community-events-toggle-location' : false,
|
||||
'.community-events-results' : false
|
||||
};
|
||||
|
||||
/*
|
||||
* Determine which templates should be rendered and which elements
|
||||
* should be displayed.
|
||||
*/
|
||||
if ( templateParams.location.ip ) {
|
||||
/*
|
||||
* If the API determined the location by geolocating an IP, it will
|
||||
* provide events, but not a specific location.
|
||||
*/
|
||||
$locationMessage.text( communityEventsData.l10n.attend_event_near_generic );
|
||||
|
||||
if ( templateParams.events.length ) {
|
||||
template = wp.template( 'community-events-event-list' );
|
||||
$results.html( template( templateParams ) );
|
||||
} else {
|
||||
template = wp.template( 'community-events-no-upcoming-events' );
|
||||
$results.html( template( templateParams ) );
|
||||
}
|
||||
|
||||
elementVisibility['#community-events-location-message'] = true;
|
||||
elementVisibility['.community-events-toggle-location'] = true;
|
||||
elementVisibility['.community-events-results'] = true;
|
||||
|
||||
} else if ( templateParams.location.description ) {
|
||||
template = wp.template( 'community-events-attend-event-near' );
|
||||
$locationMessage.html( template( templateParams ) );
|
||||
|
||||
if ( templateParams.events.length ) {
|
||||
template = wp.template( 'community-events-event-list' );
|
||||
$results.html( template( templateParams ) );
|
||||
} else {
|
||||
template = wp.template( 'community-events-no-upcoming-events' );
|
||||
$results.html( template( templateParams ) );
|
||||
}
|
||||
|
||||
if ( 'user' === initiatedBy ) {
|
||||
wp.a11y.speak( communityEventsData.l10n.city_updated.replace( l10nPlaceholder, templateParams.location.description ), 'assertive' );
|
||||
}
|
||||
|
||||
elementVisibility['#community-events-location-message'] = true;
|
||||
elementVisibility['.community-events-toggle-location'] = true;
|
||||
elementVisibility['.community-events-results'] = true;
|
||||
|
||||
} else if ( templateParams.unknownCity ) {
|
||||
template = wp.template( 'community-events-could-not-locate' );
|
||||
$( '.community-events-could-not-locate' ).html( template( templateParams ) );
|
||||
wp.a11y.speak( communityEventsData.l10n.could_not_locate_city.replace( l10nPlaceholder, templateParams.unknownCity ) );
|
||||
|
||||
elementVisibility['.community-events-errors'] = true;
|
||||
elementVisibility['.community-events-could-not-locate'] = true;
|
||||
|
||||
} else if ( templateParams.error && 'user' === initiatedBy ) {
|
||||
/*
|
||||
* Errors messages are only shown for requests that were initiated
|
||||
* by the user, not for ones that were initiated by the app itself.
|
||||
* Showing error messages for an event that user isn't aware of
|
||||
* could be confusing or unnecessarily distracting.
|
||||
*/
|
||||
wp.a11y.speak( communityEventsData.l10n.error_occurred_please_try_again );
|
||||
|
||||
elementVisibility['.community-events-errors'] = true;
|
||||
elementVisibility['.community-events-error-occurred'] = true;
|
||||
} else {
|
||||
$locationMessage.text( communityEventsData.l10n.enter_closest_city );
|
||||
|
||||
elementVisibility['#community-events-location-message'] = true;
|
||||
elementVisibility['.community-events-toggle-location'] = true;
|
||||
}
|
||||
|
||||
// Set the visibility of toggleable elements.
|
||||
_.each( elementVisibility, function( isVisible, element ) {
|
||||
$( element ).attr( 'aria-hidden', ! isVisible );
|
||||
});
|
||||
|
||||
$toggleButton.attr( 'aria-expanded', elementVisibility['.community-events-toggle-location'] );
|
||||
|
||||
if ( templateParams.location && ( templateParams.location.ip || templateParams.location.latitude ) ) {
|
||||
// Hide the form when there's a valid location.
|
||||
app.toggleLocationForm( 'hide' );
|
||||
|
||||
if ( 'user' === initiatedBy ) {
|
||||
/*
|
||||
* When the form is programmatically hidden after a user search,
|
||||
* bring the focus back to the toggle button so users relying
|
||||
* on screen readers don't lose their place.
|
||||
*/
|
||||
$toggleButton.focus();
|
||||
}
|
||||
} else {
|
||||
app.toggleLocationForm( 'show' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ( $( '#dashboard_primary' ).is( ':visible' ) ) {
|
||||
app.init();
|
||||
} else {
|
||||
$( document ).on( 'postbox-toggled', function( event, postbox ) {
|
||||
var $postbox = $( postbox );
|
||||
|
||||
if ( 'dashboard_primary' === $postbox.attr( 'id' ) && $postbox.is( ':visible' ) ) {
|
||||
app.init();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
1
wp-admin/js/dashboard.min.js
vendored
Normal file
1
wp-admin/js/dashboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1342
wp-admin/js/edit-comments.js
Normal file
1342
wp-admin/js/edit-comments.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/edit-comments.min.js
vendored
Normal file
1
wp-admin/js/edit-comments.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1616
wp-admin/js/editor-expand.js
Normal file
1616
wp-admin/js/editor-expand.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/editor-expand.min.js
vendored
Normal file
1
wp-admin/js/editor-expand.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1414
wp-admin/js/editor.js
Normal file
1414
wp-admin/js/editor.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/editor.min.js
vendored
Normal file
1
wp-admin/js/editor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
276
wp-admin/js/farbtastic.js
Normal file
276
wp-admin/js/farbtastic.js
Normal file
@@ -0,0 +1,276 @@
|
||||
/*!
|
||||
* Farbtastic: jQuery color picker plug-in v1.3u
|
||||
*
|
||||
* Licensed under the GPL license:
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.fn.farbtastic = function (options) {
|
||||
$.farbtastic(this, options);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.farbtastic = function (container, callback) {
|
||||
var container = $(container).get(0);
|
||||
return container.farbtastic || (container.farbtastic = new $._farbtastic(container, callback));
|
||||
};
|
||||
|
||||
$._farbtastic = function (container, callback) {
|
||||
// Store farbtastic object
|
||||
var fb = this;
|
||||
|
||||
// Insert markup
|
||||
$(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
|
||||
var e = $('.farbtastic', container);
|
||||
fb.wheel = $('.wheel', container).get(0);
|
||||
// Dimensions
|
||||
fb.radius = 84;
|
||||
fb.square = 100;
|
||||
fb.width = 194;
|
||||
|
||||
// Fix background PNGs in IE6
|
||||
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
|
||||
$('*', e).each(function () {
|
||||
if (this.currentStyle.backgroundImage != 'none') {
|
||||
var image = this.currentStyle.backgroundImage;
|
||||
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
|
||||
$(this).css({
|
||||
'backgroundImage': 'none',
|
||||
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the given element(s) or callback.
|
||||
*/
|
||||
fb.linkTo = function (callback) {
|
||||
// Unbind previous nodes
|
||||
if (typeof fb.callback == 'object') {
|
||||
$(fb.callback).unbind('keyup', fb.updateValue);
|
||||
}
|
||||
|
||||
// Reset color
|
||||
fb.color = null;
|
||||
|
||||
// Bind callback or elements
|
||||
if (typeof callback == 'function') {
|
||||
fb.callback = callback;
|
||||
}
|
||||
else if (typeof callback == 'object' || typeof callback == 'string') {
|
||||
fb.callback = $(callback);
|
||||
fb.callback.bind('keyup', fb.updateValue);
|
||||
if (fb.callback.get(0).value) {
|
||||
fb.setColor(fb.callback.get(0).value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
fb.updateValue = function (event) {
|
||||
if (this.value && this.value != fb.color) {
|
||||
fb.setColor(this.value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Change color with HTML syntax #123456
|
||||
*/
|
||||
fb.setColor = function (color) {
|
||||
var unpack = fb.unpack(color);
|
||||
if (fb.color != color && unpack) {
|
||||
fb.color = color;
|
||||
fb.rgb = unpack;
|
||||
fb.hsl = fb.RGBToHSL(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change color with HSL triplet [0..1, 0..1, 0..1]
|
||||
*/
|
||||
fb.setHSL = function (hsl) {
|
||||
fb.hsl = hsl;
|
||||
fb.rgb = fb.HSLToRGB(hsl);
|
||||
fb.color = fb.pack(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
return this;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Retrieve the coordinates of the given event relative to the center
|
||||
* of the widget.
|
||||
*/
|
||||
fb.widgetCoords = function (event) {
|
||||
var offset = $(fb.wheel).offset();
|
||||
return { x: (event.pageX - offset.left) - fb.width / 2, y: (event.pageY - offset.top) - fb.width / 2 };
|
||||
};
|
||||
|
||||
/**
|
||||
* Mousedown handler
|
||||
*/
|
||||
fb.mousedown = function (event) {
|
||||
// Capture mouse
|
||||
if (!document.dragging) {
|
||||
$(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
|
||||
document.dragging = true;
|
||||
}
|
||||
|
||||
// Check which area is being dragged
|
||||
var pos = fb.widgetCoords(event);
|
||||
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
|
||||
|
||||
// Process
|
||||
fb.mousemove(event);
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mousemove handler
|
||||
*/
|
||||
fb.mousemove = function (event) {
|
||||
// Get coordinates relative to color picker center
|
||||
var pos = fb.widgetCoords(event);
|
||||
|
||||
// Set new HSL parameters
|
||||
if (fb.circleDrag) {
|
||||
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
|
||||
if (hue < 0) hue += 1;
|
||||
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
|
||||
}
|
||||
else {
|
||||
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
|
||||
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
|
||||
fb.setHSL([fb.hsl[0], sat, lum]);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mouseup handler
|
||||
*/
|
||||
fb.mouseup = function () {
|
||||
// Uncapture mouse
|
||||
$(document).unbind('mousemove', fb.mousemove);
|
||||
$(document).unbind('mouseup', fb.mouseup);
|
||||
document.dragging = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the markers and styles
|
||||
*/
|
||||
fb.updateDisplay = function () {
|
||||
// Markers
|
||||
var angle = fb.hsl[0] * 6.28;
|
||||
$('.h-marker', e).css({
|
||||
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
|
||||
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
$('.sl-marker', e).css({
|
||||
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
|
||||
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
// Saturation/Luminance gradient
|
||||
$('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
|
||||
|
||||
// Linked elements or callback
|
||||
if (typeof fb.callback == 'object') {
|
||||
// Set background/foreground color
|
||||
$(fb.callback).css({
|
||||
backgroundColor: fb.color,
|
||||
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
|
||||
});
|
||||
|
||||
// Change linked value
|
||||
$(fb.callback).each(function() {
|
||||
if (this.value && this.value != fb.color) {
|
||||
this.value = fb.color;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (typeof fb.callback == 'function') {
|
||||
fb.callback.call(fb, fb.color);
|
||||
}
|
||||
};
|
||||
|
||||
/* Various color utility functions */
|
||||
fb.pack = function (rgb) {
|
||||
var r = Math.round(rgb[0] * 255);
|
||||
var g = Math.round(rgb[1] * 255);
|
||||
var b = Math.round(rgb[2] * 255);
|
||||
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
|
||||
(g < 16 ? '0' : '') + g.toString(16) +
|
||||
(b < 16 ? '0' : '') + b.toString(16);
|
||||
};
|
||||
|
||||
fb.unpack = function (color) {
|
||||
if (color.length == 7) {
|
||||
return [parseInt('0x' + color.substring(1, 3)) / 255,
|
||||
parseInt('0x' + color.substring(3, 5)) / 255,
|
||||
parseInt('0x' + color.substring(5, 7)) / 255];
|
||||
}
|
||||
else if (color.length == 4) {
|
||||
return [parseInt('0x' + color.substring(1, 2)) / 15,
|
||||
parseInt('0x' + color.substring(2, 3)) / 15,
|
||||
parseInt('0x' + color.substring(3, 4)) / 15];
|
||||
}
|
||||
};
|
||||
|
||||
fb.HSLToRGB = function (hsl) {
|
||||
var m1, m2, r, g, b;
|
||||
var h = hsl[0], s = hsl[1], l = hsl[2];
|
||||
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
|
||||
m1 = l * 2 - m2;
|
||||
return [this.hueToRGB(m1, m2, h+0.33333),
|
||||
this.hueToRGB(m1, m2, h),
|
||||
this.hueToRGB(m1, m2, h-0.33333)];
|
||||
};
|
||||
|
||||
fb.hueToRGB = function (m1, m2, h) {
|
||||
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
|
||||
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
|
||||
if (h * 2 < 1) return m2;
|
||||
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
|
||||
return m1;
|
||||
};
|
||||
|
||||
fb.RGBToHSL = function (rgb) {
|
||||
var min, max, delta, h, s, l;
|
||||
var r = rgb[0], g = rgb[1], b = rgb[2];
|
||||
min = Math.min(r, Math.min(g, b));
|
||||
max = Math.max(r, Math.max(g, b));
|
||||
delta = max - min;
|
||||
l = (min + max) / 2;
|
||||
s = 0;
|
||||
if (l > 0 && l < 1) {
|
||||
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
|
||||
}
|
||||
h = 0;
|
||||
if (delta > 0) {
|
||||
if (max == r && max != g) h += (g - b) / delta;
|
||||
if (max == g && max != b) h += (2 + (b - r) / delta);
|
||||
if (max == b && max != r) h += (4 + (r - g) / delta);
|
||||
h /= 6;
|
||||
}
|
||||
return [h, s, l];
|
||||
};
|
||||
|
||||
// Install mousedown handler (the others are set on the document on-demand)
|
||||
$('*', e).mousedown(fb.mousedown);
|
||||
|
||||
// Init color
|
||||
fb.setColor('#000000');
|
||||
|
||||
// Set linked elements/callback
|
||||
if (callback) {
|
||||
fb.linkTo(callback);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
241
wp-admin/js/gallery.js
Normal file
241
wp-admin/js/gallery.js
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @output wp-admin/js/gallery.js
|
||||
*/
|
||||
|
||||
/* global unescape, getUserSetting, setUserSetting, wpgallery, tinymce */
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
var gallerySortable, gallerySortableInit, sortIt, clearAll, w, desc = false;
|
||||
|
||||
gallerySortableInit = function() {
|
||||
gallerySortable = $('#media-items').sortable( {
|
||||
items: 'div.media-item',
|
||||
placeholder: 'sorthelper',
|
||||
axis: 'y',
|
||||
distance: 2,
|
||||
handle: 'div.filename',
|
||||
stop: function() {
|
||||
// When an update has occurred, adjust the order for each item
|
||||
var all = $('#media-items').sortable('toArray'), len = all.length;
|
||||
$.each(all, function(i, id) {
|
||||
var order = desc ? (len - i) : (1 + i);
|
||||
$('#' + id + ' .menu_order input').val(order);
|
||||
});
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
sortIt = function() {
|
||||
var all = $('.menu_order_input'), len = all.length;
|
||||
all.each(function(i){
|
||||
var order = desc ? (len - i) : (1 + i);
|
||||
$(this).val(order);
|
||||
});
|
||||
};
|
||||
|
||||
clearAll = function(c) {
|
||||
c = c || 0;
|
||||
$('.menu_order_input').each( function() {
|
||||
if ( this.value === '0' || c ) {
|
||||
this.value = '';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$('#asc').click( function( e ) {
|
||||
e.preventDefault();
|
||||
desc = false;
|
||||
sortIt();
|
||||
});
|
||||
$('#desc').click( function( e ) {
|
||||
e.preventDefault();
|
||||
desc = true;
|
||||
sortIt();
|
||||
});
|
||||
$('#clear').click( function( e ) {
|
||||
e.preventDefault();
|
||||
clearAll(1);
|
||||
});
|
||||
$('#showall').click( function( e ) {
|
||||
e.preventDefault();
|
||||
$('#sort-buttons span a').toggle();
|
||||
$('a.describe-toggle-on').hide();
|
||||
$('a.describe-toggle-off, table.slidetoggle').show();
|
||||
$('img.pinkynail').toggle(false);
|
||||
});
|
||||
$('#hideall').click( function( e ) {
|
||||
e.preventDefault();
|
||||
$('#sort-buttons span a').toggle();
|
||||
$('a.describe-toggle-on').show();
|
||||
$('a.describe-toggle-off, table.slidetoggle').hide();
|
||||
$('img.pinkynail').toggle(true);
|
||||
});
|
||||
|
||||
// initialize sortable
|
||||
gallerySortableInit();
|
||||
clearAll();
|
||||
|
||||
if ( $('#media-items>*').length > 1 ) {
|
||||
w = wpgallery.getWin();
|
||||
|
||||
$('#save-all, #gallery-settings').show();
|
||||
if ( typeof w.tinyMCE !== 'undefined' && w.tinyMCE.activeEditor && ! w.tinyMCE.activeEditor.isHidden() ) {
|
||||
wpgallery.mcemode = true;
|
||||
wpgallery.init();
|
||||
} else {
|
||||
$('#insert-gallery').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(window).unload( function () { window.tinymce = window.tinyMCE = window.wpgallery = null; } ); // Cleanup
|
||||
|
||||
/* gallery settings */
|
||||
window.tinymce = null;
|
||||
|
||||
window.wpgallery = {
|
||||
mcemode : false,
|
||||
editor : {},
|
||||
dom : {},
|
||||
is_update : false,
|
||||
el : {},
|
||||
|
||||
I : function(e) {
|
||||
return document.getElementById(e);
|
||||
},
|
||||
|
||||
init: function() {
|
||||
var t = this, li, q, i, it, w = t.getWin();
|
||||
|
||||
if ( ! t.mcemode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
li = ('' + document.location.search).replace(/^\?/, '').split('&');
|
||||
q = {};
|
||||
for (i=0; i<li.length; i++) {
|
||||
it = li[i].split('=');
|
||||
q[unescape(it[0])] = unescape(it[1]);
|
||||
}
|
||||
|
||||
if ( q.mce_rdomain ) {
|
||||
document.domain = q.mce_rdomain;
|
||||
}
|
||||
|
||||
// Find window & API
|
||||
window.tinymce = w.tinymce;
|
||||
window.tinyMCE = w.tinyMCE;
|
||||
t.editor = tinymce.EditorManager.activeEditor;
|
||||
|
||||
t.setup();
|
||||
},
|
||||
|
||||
getWin : function() {
|
||||
return window.dialogArguments || opener || parent || top;
|
||||
},
|
||||
|
||||
setup : function() {
|
||||
var t = this, a, ed = t.editor, g, columns, link, order, orderby;
|
||||
if ( ! t.mcemode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
t.el = ed.selection.getNode();
|
||||
|
||||
if ( t.el.nodeName !== 'IMG' || ! ed.dom.hasClass(t.el, 'wpGallery') ) {
|
||||
if ( ( g = ed.dom.select('img.wpGallery') ) && g[0] ) {
|
||||
t.el = g[0];
|
||||
} else {
|
||||
if ( getUserSetting('galfile') === '1' ) {
|
||||
t.I('linkto-file').checked = 'checked';
|
||||
}
|
||||
if ( getUserSetting('galdesc') === '1' ) {
|
||||
t.I('order-desc').checked = 'checked';
|
||||
}
|
||||
if ( getUserSetting('galcols') ) {
|
||||
t.I('columns').value = getUserSetting('galcols');
|
||||
}
|
||||
if ( getUserSetting('galord') ) {
|
||||
t.I('orderby').value = getUserSetting('galord');
|
||||
}
|
||||
jQuery('#insert-gallery').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
a = ed.dom.getAttrib(t.el, 'title');
|
||||
a = ed.dom.decode(a);
|
||||
|
||||
if ( a ) {
|
||||
jQuery('#update-gallery').show();
|
||||
t.is_update = true;
|
||||
|
||||
columns = a.match(/columns=['"]([0-9]+)['"]/);
|
||||
link = a.match(/link=['"]([^'"]+)['"]/i);
|
||||
order = a.match(/order=['"]([^'"]+)['"]/i);
|
||||
orderby = a.match(/orderby=['"]([^'"]+)['"]/i);
|
||||
|
||||
if ( link && link[1] ) {
|
||||
t.I('linkto-file').checked = 'checked';
|
||||
}
|
||||
if ( order && order[1] ) {
|
||||
t.I('order-desc').checked = 'checked';
|
||||
}
|
||||
if ( columns && columns[1] ) {
|
||||
t.I('columns').value = '' + columns[1];
|
||||
}
|
||||
if ( orderby && orderby[1] ) {
|
||||
t.I('orderby').value = orderby[1];
|
||||
}
|
||||
} else {
|
||||
jQuery('#insert-gallery').show();
|
||||
}
|
||||
},
|
||||
|
||||
update : function() {
|
||||
var t = this, ed = t.editor, all = '', s;
|
||||
|
||||
if ( ! t.mcemode || ! t.is_update ) {
|
||||
s = '[gallery' + t.getSettings() + ']';
|
||||
t.getWin().send_to_editor(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( t.el.nodeName !== 'IMG' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
all = ed.dom.decode( ed.dom.getAttrib( t.el, 'title' ) );
|
||||
all = all.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi, '');
|
||||
all += t.getSettings();
|
||||
|
||||
ed.dom.setAttrib(t.el, 'title', all);
|
||||
t.getWin().tb_remove();
|
||||
},
|
||||
|
||||
getSettings : function() {
|
||||
var I = this.I, s = '';
|
||||
|
||||
if ( I('linkto-file').checked ) {
|
||||
s += ' link="file"';
|
||||
setUserSetting('galfile', '1');
|
||||
}
|
||||
|
||||
if ( I('order-desc').checked ) {
|
||||
s += ' order="DESC"';
|
||||
setUserSetting('galdesc', '1');
|
||||
}
|
||||
|
||||
if ( I('columns').value !== 3 ) {
|
||||
s += ' columns="' + I('columns').value + '"';
|
||||
setUserSetting('galcols', I('columns').value);
|
||||
}
|
||||
|
||||
if ( I('orderby').value !== 'menu_order' ) {
|
||||
s += ' orderby="' + I('orderby').value + '"';
|
||||
setUserSetting('galord', I('orderby').value);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
1
wp-admin/js/gallery.min.js
vendored
Normal file
1
wp-admin/js/gallery.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(l){var e,t,i,n,o=!1;e=function(){l("#media-items").sortable({items:"div.media-item",placeholder:"sorthelper",axis:"y",distance:2,handle:"div.filename",stop:function(){var e=l("#media-items").sortable("toArray"),n=e.length;l.each(e,function(e,t){var i=o?n-e:1+e;l("#"+t+" .menu_order input").val(i)})}})},t=function(){var e=l(".menu_order_input"),i=e.length;e.each(function(e){var t=o?i-e:1+e;l(this).val(t)})},i=function(e){e=e||0,l(".menu_order_input").each(function(){"0"!==this.value&&!e||(this.value="")})},l("#asc").click(function(e){e.preventDefault(),o=!1,t()}),l("#desc").click(function(e){e.preventDefault(),o=!0,t()}),l("#clear").click(function(e){e.preventDefault(),i(1)}),l("#showall").click(function(e){e.preventDefault(),l("#sort-buttons span a").toggle(),l("a.describe-toggle-on").hide(),l("a.describe-toggle-off, table.slidetoggle").show(),l("img.pinkynail").toggle(!1)}),l("#hideall").click(function(e){e.preventDefault(),l("#sort-buttons span a").toggle(),l("a.describe-toggle-on").show(),l("a.describe-toggle-off, table.slidetoggle").hide(),l("img.pinkynail").toggle(!0)}),e(),i(),1<l("#media-items>*").length&&(n=wpgallery.getWin(),l("#save-all, #gallery-settings").show(),void 0!==n.tinyMCE&&n.tinyMCE.activeEditor&&!n.tinyMCE.activeEditor.isHidden()?(wpgallery.mcemode=!0,wpgallery.init()):l("#insert-gallery").show())}),jQuery(window).unload(function(){window.tinymce=window.tinyMCE=window.wpgallery=null}),window.tinymce=null,window.wpgallery={mcemode:!1,editor:{},dom:{},is_update:!1,el:{},I:function(e){return document.getElementById(e)},init:function(){var e,t,i,n,l=this,o=l.getWin();if(l.mcemode){for(e=(""+document.location.search).replace(/^\?/,"").split("&"),t={},i=0;i<e.length;i++)n=e[i].split("="),t[unescape(n[0])]=unescape(n[1]);t.mce_rdomain&&(document.domain=t.mce_rdomain),window.tinymce=o.tinymce,window.tinyMCE=o.tinyMCE,l.editor=tinymce.EditorManager.activeEditor,l.setup()}},getWin:function(){return window.dialogArguments||opener||parent||top},setup:function(){var e,t,i,n,l,o,r=this,a=r.editor;if(r.mcemode){if(r.el=a.selection.getNode(),"IMG"!==r.el.nodeName||!a.dom.hasClass(r.el,"wpGallery")){if(!(t=a.dom.select("img.wpGallery"))||!t[0])return"1"===getUserSetting("galfile")&&(r.I("linkto-file").checked="checked"),"1"===getUserSetting("galdesc")&&(r.I("order-desc").checked="checked"),getUserSetting("galcols")&&(r.I("columns").value=getUserSetting("galcols")),getUserSetting("galord")&&(r.I("orderby").value=getUserSetting("galord")),void jQuery("#insert-gallery").show();r.el=t[0]}e=a.dom.getAttrib(r.el,"title"),(e=a.dom.decode(e))?(jQuery("#update-gallery").show(),r.is_update=!0,i=e.match(/columns=['"]([0-9]+)['"]/),n=e.match(/link=['"]([^'"]+)['"]/i),l=e.match(/order=['"]([^'"]+)['"]/i),o=e.match(/orderby=['"]([^'"]+)['"]/i),n&&n[1]&&(r.I("linkto-file").checked="checked"),l&&l[1]&&(r.I("order-desc").checked="checked"),i&&i[1]&&(r.I("columns").value=""+i[1]),o&&o[1]&&(r.I("orderby").value=o[1])):jQuery("#insert-gallery").show()}},update:function(){var e,t=this,i=t.editor,n="";if(!t.mcemode||!t.is_update)return e="[gallery"+t.getSettings()+"]",void t.getWin().send_to_editor(e);"IMG"===t.el.nodeName&&(n=(n=i.dom.decode(i.dom.getAttrib(t.el,"title"))).replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi,""),n+=t.getSettings(),i.dom.setAttrib(t.el,"title",n),t.getWin().tb_remove())},getSettings:function(){var e=this.I,t="";return e("linkto-file").checked&&(t+=' link="file"',setUserSetting("galfile","1")),e("order-desc").checked&&(t+=' order="DESC"',setUserSetting("galdesc","1")),3!==e("columns").value&&(t+=' columns="'+e("columns").value+'"',setUserSetting("galcols",e("columns").value)),"menu_order"!==e("orderby").value&&(t+=' orderby="'+e("orderby").value+'"',setUserSetting("galord",e("orderby").value)),t}};
|
||||
1126
wp-admin/js/image-edit.js
Normal file
1126
wp-admin/js/image-edit.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/image-edit.min.js
vendored
Normal file
1
wp-admin/js/image-edit.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
555
wp-admin/js/inline-edit-post.js
Normal file
555
wp-admin/js/inline-edit-post.js
Normal file
@@ -0,0 +1,555 @@
|
||||
/**
|
||||
* This file contains the functions needed for the inline editing of posts.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @output wp-admin/js/inline-edit-post.js
|
||||
*/
|
||||
|
||||
/* global inlineEditL10n, ajaxurl, typenow, inlineEditPost */
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Manages the quick edit and bulk edit windows for editing posts or pages.
|
||||
*
|
||||
* @namespace inlineEditPost
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @type {Object}
|
||||
*
|
||||
* @property {string} type The type of inline editor.
|
||||
* @property {string} what The prefix before the post id.
|
||||
*
|
||||
*/
|
||||
( function( $, wp ) {
|
||||
|
||||
window.inlineEditPost = {
|
||||
|
||||
/**
|
||||
* Initializes the inline and bulk post editor.
|
||||
*
|
||||
* Binds event handlers to the escape key to close the inline editor
|
||||
* and to the save and close buttons. Changes DOM to be ready for inline
|
||||
* editing. Adds event handler to bulk edit.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function(){
|
||||
var t = this, qeRow = $('#inline-edit'), bulkRow = $('#bulk-edit');
|
||||
|
||||
t.type = $('table.widefat').hasClass('pages') ? 'page' : 'post';
|
||||
// Post id prefix.
|
||||
t.what = '#post-';
|
||||
|
||||
/**
|
||||
* Binds the escape key to revert the changes and close the quick editor.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
qeRow.keyup(function(e){
|
||||
// Revert changes if escape key is pressed.
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditPost.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds the escape key to revert the changes and close the bulk editor.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
bulkRow.keyup(function(e){
|
||||
// Revert changes if escape key is pressed.
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditPost.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reverts changes and close the quick editor if the cancel button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
$( '.cancel', qeRow ).click( function() {
|
||||
return inlineEditPost.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves changes in the quick editor if the save(named: update) button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of save.
|
||||
*/
|
||||
$( '.save', qeRow ).click( function() {
|
||||
return inlineEditPost.save(this);
|
||||
});
|
||||
|
||||
/**
|
||||
* If enter is pressed, and the target is not the cancel button, save the post.
|
||||
*
|
||||
* @returns {boolean} The result of save.
|
||||
*/
|
||||
$('td', qeRow).keydown(function(e){
|
||||
if ( e.which === 13 && ! $( e.target ).hasClass( 'cancel' ) ) {
|
||||
return inlineEditPost.save(this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reverts changes and close the bulk editor if the cancel button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
$( '.cancel', bulkRow ).click( function() {
|
||||
return inlineEditPost.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Disables the password input field when the private post checkbox is checked.
|
||||
*/
|
||||
$('#inline-edit .inline-edit-private input[value="private"]').click( function(){
|
||||
var pw = $('input.inline-edit-password-input');
|
||||
if ( $(this).prop('checked') ) {
|
||||
pw.val('').prop('disabled', true);
|
||||
} else {
|
||||
pw.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds click event to the .editinline button which opens the quick editor.
|
||||
*/
|
||||
$( '#the-list' ).on( 'click', '.editinline', function() {
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
inlineEditPost.edit( this );
|
||||
});
|
||||
|
||||
$('#bulk-edit').find('fieldset:first').after(
|
||||
$('#inline-edit fieldset.inline-edit-categories').clone()
|
||||
).siblings( 'fieldset:last' ).prepend(
|
||||
$('#inline-edit label.inline-edit-tags').clone()
|
||||
);
|
||||
|
||||
$('select[name="_status"] option[value="future"]', bulkRow).remove();
|
||||
|
||||
/**
|
||||
* Adds onclick events to the apply buttons.
|
||||
*/
|
||||
$('#doaction, #doaction2').click(function(e){
|
||||
var n;
|
||||
|
||||
t.whichBulkButtonId = $( this ).attr( 'id' );
|
||||
n = t.whichBulkButtonId.substr( 2 );
|
||||
|
||||
if ( 'edit' === $( 'select[name="' + n + '"]' ).val() ) {
|
||||
e.preventDefault();
|
||||
t.setBulk();
|
||||
} else if ( $('form#posts-filter tr.inline-editor').length > 0 ) {
|
||||
t.revert();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the quick edit window, hiding it when it's active and showing it when
|
||||
* inactive.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {Object} el Element within a post table row.
|
||||
*/
|
||||
toggle : function(el){
|
||||
var t = this;
|
||||
$( t.what + t.getId( el ) ).css( 'display' ) === 'none' ? t.revert() : t.edit( el );
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the bulk editor row to edit multiple posts at once.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*/
|
||||
setBulk : function(){
|
||||
var te = '', type = this.type, c = true;
|
||||
this.revert();
|
||||
|
||||
$( '#bulk-edit td' ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
|
||||
|
||||
// Insert the editor at the top of the table with an empty row above to maintain zebra striping.
|
||||
$('table.widefat tbody').prepend( $('#bulk-edit') ).prepend('<tr class="hidden"></tr>');
|
||||
$('#bulk-edit').addClass('inline-editor').show();
|
||||
|
||||
/**
|
||||
* Create a HTML div with the title and a link(delete-icon) for each selected
|
||||
* post.
|
||||
*
|
||||
* Get the selected posts based on the checked checkboxes in the post table.
|
||||
*/
|
||||
$( 'tbody th.check-column input[type="checkbox"]' ).each( function() {
|
||||
|
||||
// If the checkbox for a post is selected, add the post to the edit list.
|
||||
if ( $(this).prop('checked') ) {
|
||||
c = false;
|
||||
var id = $(this).val(), theTitle;
|
||||
theTitle = $('#inline_'+id+' .post_title').html() || inlineEditL10n.notitle;
|
||||
te += '<div id="ttle'+id+'"><a id="_'+id+'" class="ntdelbutton" title="'+inlineEditL10n.ntdeltitle+'">X</a>'+theTitle+'</div>';
|
||||
}
|
||||
});
|
||||
|
||||
// If no checkboxes where checked, just hide the quick/bulk edit rows.
|
||||
if ( c ) {
|
||||
return this.revert();
|
||||
}
|
||||
|
||||
// Add onclick events to the delete-icons in the bulk editors the post title list.
|
||||
$('#bulk-titles').html(te);
|
||||
/**
|
||||
* Binds on click events to the checkboxes before the posts in the table.
|
||||
*
|
||||
* @listens click
|
||||
*/
|
||||
$('#bulk-titles a').click(function(){
|
||||
var id = $(this).attr('id').substr(1);
|
||||
|
||||
$('table.widefat input[value="' + id + '"]').prop('checked', false);
|
||||
$('#ttle'+id).remove();
|
||||
});
|
||||
|
||||
// Enable auto-complete for tags when editing posts.
|
||||
if ( 'post' === type ) {
|
||||
$( 'tr.inline-editor textarea[data-wp-taxonomy]' ).each( function ( i, element ) {
|
||||
/*
|
||||
* While Quick Edit clones the form each time, Bulk Edit always re-uses
|
||||
* the same form. Let's check if an autocomplete instance already exists.
|
||||
*/
|
||||
if ( $( element ).autocomplete( 'instance' ) ) {
|
||||
// jQuery equivalent of `continue` within an `each()` loop.
|
||||
return;
|
||||
}
|
||||
|
||||
$( element ).wpTagsSuggest();
|
||||
} );
|
||||
}
|
||||
|
||||
// Scrolls to the top of the table where the editor is rendered.
|
||||
$('html, body').animate( { scrollTop: 0 }, 'fast' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a quick edit window for the post that has been clicked.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {number|Object} id The id of the clicked post or an element within a post
|
||||
* table row.
|
||||
* @returns {boolean} Always returns false at the end of execution.
|
||||
*/
|
||||
edit : function(id) {
|
||||
var t = this, fields, editRow, rowData, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, f, val, pw;
|
||||
t.revert();
|
||||
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = t.getId(id);
|
||||
}
|
||||
|
||||
fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order', 'page_template'];
|
||||
if ( t.type === 'page' ) {
|
||||
fields.push('post_parent');
|
||||
}
|
||||
|
||||
// Add the new edit row with an extra blank row underneath to maintain zebra striping.
|
||||
editRow = $('#inline-edit').clone(true);
|
||||
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
|
||||
|
||||
$(t.what+id).removeClass('is-expanded').hide().after(editRow).after('<tr class="hidden"></tr>');
|
||||
|
||||
// Populate fields in the quick edit window.
|
||||
rowData = $('#inline_'+id);
|
||||
if ( !$(':input[name="post_author"] option[value="' + $('.post_author', rowData).text() + '"]', editRow).val() ) {
|
||||
|
||||
// The post author no longer has edit capabilities, so we need to add them to the list of authors.
|
||||
$(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
|
||||
}
|
||||
if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
|
||||
$('label.inline-edit-author', editRow).hide();
|
||||
}
|
||||
|
||||
for ( f = 0; f < fields.length; f++ ) {
|
||||
val = $('.'+fields[f], rowData);
|
||||
|
||||
/**
|
||||
* Replaces the image for a Twemoji(Twitter emoji) with it's alternate text.
|
||||
*
|
||||
* @returns Alternate text from the image.
|
||||
*/
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="' + fields[f] + '"]', editRow).val( val );
|
||||
}
|
||||
|
||||
if ( $( '.comment_status', rowData ).text() === 'open' ) {
|
||||
$( 'input[name="comment_status"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
if ( $( '.ping_status', rowData ).text() === 'open' ) {
|
||||
$( 'input[name="ping_status"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
if ( $( '.sticky', rowData ).text() === 'sticky' ) {
|
||||
$( 'input[name="sticky"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the select boxes for the categories.
|
||||
*/
|
||||
$('.post_category', rowData).each(function(){
|
||||
var taxname,
|
||||
term_ids = $(this).text();
|
||||
|
||||
if ( term_ids ) {
|
||||
taxname = $(this).attr('id').replace('_'+id, '');
|
||||
$('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(','));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets all the taxonomies for live auto-fill suggestions when typing the name
|
||||
* of a tag.
|
||||
*/
|
||||
$('.tags_input', rowData).each(function(){
|
||||
var terms = $(this),
|
||||
taxname = $(this).attr('id').replace('_' + id, ''),
|
||||
textarea = $('textarea.tax_input_' + taxname, editRow),
|
||||
comma = inlineEditL10n.comma;
|
||||
|
||||
terms.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
terms = terms.text();
|
||||
|
||||
if ( terms ) {
|
||||
if ( ',' !== comma ) {
|
||||
terms = terms.replace(/,/g, comma);
|
||||
}
|
||||
textarea.val(terms);
|
||||
}
|
||||
|
||||
textarea.wpTagsSuggest();
|
||||
});
|
||||
|
||||
// Handle the post status.
|
||||
status = $('._status', rowData).text();
|
||||
if ( 'future' !== status ) {
|
||||
$('select[name="_status"] option[value="future"]', editRow).remove();
|
||||
}
|
||||
|
||||
pw = $( '.inline-edit-password-input' ).prop( 'disabled', false );
|
||||
if ( 'private' === status ) {
|
||||
$('input[name="keep_private"]', editRow).prop('checked', true);
|
||||
pw.val( '' ).prop( 'disabled', true );
|
||||
}
|
||||
|
||||
// Remove the current page and children from the parent dropdown.
|
||||
pageOpt = $('select[name="post_parent"] option[value="' + id + '"]', editRow);
|
||||
if ( pageOpt.length > 0 ) {
|
||||
pageLevel = pageOpt[0].className.split('-')[1];
|
||||
nextPage = pageOpt;
|
||||
while ( pageLoop ) {
|
||||
nextPage = nextPage.next('option');
|
||||
if ( nextPage.length === 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
nextLevel = nextPage[0].className.split('-')[1];
|
||||
|
||||
if ( nextLevel <= pageLevel ) {
|
||||
pageLoop = false;
|
||||
} else {
|
||||
nextPage.remove();
|
||||
nextPage = pageOpt;
|
||||
}
|
||||
}
|
||||
pageOpt.remove();
|
||||
}
|
||||
|
||||
$(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show();
|
||||
$('.ptitle', editRow).focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the changes made in the quick edit window to the post.
|
||||
* AJAX saving is only for Quick Edit and not for bulk edit.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {int} id The id for the post that has been changed.
|
||||
* @returns {boolean} false, so the form does not submit when pressing
|
||||
* Enter on a focused field.
|
||||
*/
|
||||
save : function(id) {
|
||||
var params, fields, page = $('.post_status_page').val() || '';
|
||||
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = this.getId(id);
|
||||
}
|
||||
|
||||
$( 'table.widefat .spinner' ).addClass( 'is-active' );
|
||||
|
||||
params = {
|
||||
action: 'inline-save',
|
||||
post_type: typenow,
|
||||
post_ID: id,
|
||||
edit_date: 'true',
|
||||
post_status: page
|
||||
};
|
||||
|
||||
fields = $('#edit-'+id).find(':input').serialize();
|
||||
params = fields + '&' + $.param(params);
|
||||
|
||||
// Make ajax request.
|
||||
$.post( ajaxurl, params,
|
||||
function(r) {
|
||||
var $errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
$( '.ac_results' ).hide();
|
||||
|
||||
if (r) {
|
||||
if ( -1 !== r.indexOf( '<tr' ) ) {
|
||||
$(inlineEditPost.what+id).siblings('tr.hidden').addBack().remove();
|
||||
$('#edit-'+id).before(r).remove();
|
||||
$( inlineEditPost.what + id ).hide().fadeIn( 400, function() {
|
||||
// Move focus back to the Quick Edit button. $( this ) is the row being animated.
|
||||
$( this ).find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
wp.a11y.speak( inlineEditL10n.saved );
|
||||
});
|
||||
} else {
|
||||
r = r.replace( /<.[^<>]*?>/g, '' );
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( r );
|
||||
wp.a11y.speak( $error.text() );
|
||||
}
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( inlineEditL10n.error );
|
||||
wp.a11y.speak( inlineEditL10n.error );
|
||||
}
|
||||
},
|
||||
'html');
|
||||
|
||||
// Prevent submitting the form when pressing Enter on a focused field.
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides and empties the Quick Edit and/or Bulk Edit windows.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
revert : function(){
|
||||
var $tableWideFat = $( '.widefat' ),
|
||||
id = $( '.inline-editor', $tableWideFat ).attr( 'id' );
|
||||
|
||||
if ( id ) {
|
||||
$( '.spinner', $tableWideFat ).removeClass( 'is-active' );
|
||||
$( '.ac_results' ).hide();
|
||||
|
||||
if ( 'bulk-edit' === id ) {
|
||||
|
||||
// Hide the bulk editor.
|
||||
$( '#bulk-edit', $tableWideFat ).removeClass( 'inline-editor' ).hide().siblings( '.hidden' ).remove();
|
||||
$('#bulk-titles').empty();
|
||||
|
||||
// Store the empty bulk editor in a hidden element.
|
||||
$('#inlineedit').append( $('#bulk-edit') );
|
||||
|
||||
// Move focus back to the Bulk Action button that was activated.
|
||||
$( '#' + inlineEditPost.whichBulkButtonId ).focus();
|
||||
} else {
|
||||
|
||||
// Remove both the inline-editor and its hidden tr siblings.
|
||||
$('#'+id).siblings('tr.hidden').addBack().remove();
|
||||
id = id.substr( id.lastIndexOf('-') + 1 );
|
||||
|
||||
// Show the post row and move focus back to the Quick Edit button.
|
||||
$( this.what + id ).show().find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the id for a the post that you want to quick edit from the row in the quick
|
||||
* edit table.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {Object} o DOM row object to get the id for.
|
||||
* @returns {string} The post id extracted from the table row in the object.
|
||||
*/
|
||||
getId : function(o) {
|
||||
var id = $(o).closest('tr').attr('id'),
|
||||
parts = id.split('-');
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
$( document ).ready( function(){ inlineEditPost.init(); } );
|
||||
|
||||
// Show/hide locks on posts.
|
||||
$( document ).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) {
|
||||
var locked = data['wp-check-locked-posts'] || {};
|
||||
|
||||
$('#the-list tr').each( function(i, el) {
|
||||
var key = el.id, row = $(el), lock_data, avatar;
|
||||
|
||||
if ( locked.hasOwnProperty( key ) ) {
|
||||
if ( ! row.hasClass('wp-locked') ) {
|
||||
lock_data = locked[key];
|
||||
row.find('.column-title .locked-text').text( lock_data.text );
|
||||
row.find('.check-column checkbox').prop('checked', false);
|
||||
|
||||
if ( lock_data.avatar_src ) {
|
||||
avatar = $( '<img class="avatar avatar-18 photo" width="18" height="18" alt="" />' ).attr( 'src', lock_data.avatar_src.replace( /&/g, '&' ) );
|
||||
row.find('.column-title .locked-avatar').empty().append( avatar );
|
||||
}
|
||||
row.addClass('wp-locked');
|
||||
}
|
||||
} else if ( row.hasClass('wp-locked') ) {
|
||||
row.removeClass( 'wp-locked' ).find( '.locked-info span' ).empty();
|
||||
}
|
||||
});
|
||||
}).on( 'heartbeat-send.wp-check-locked-posts', function( e, data ) {
|
||||
var check = [];
|
||||
|
||||
$('#the-list tr').each( function(i, el) {
|
||||
if ( el.id ) {
|
||||
check.push( el.id );
|
||||
}
|
||||
});
|
||||
|
||||
if ( check.length ) {
|
||||
data['wp-check-locked-posts'] = check;
|
||||
}
|
||||
}).ready( function() {
|
||||
|
||||
// Set the heartbeat interval to 15 sec.
|
||||
if ( typeof wp !== 'undefined' && wp.heartbeat ) {
|
||||
wp.heartbeat.interval( 15 );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery, window.wp );
|
||||
1
wp-admin/js/inline-edit-post.min.js
vendored
Normal file
1
wp-admin/js/inline-edit-post.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
294
wp-admin/js/inline-edit-tax.js
Normal file
294
wp-admin/js/inline-edit-tax.js
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* This file is used on the term overview page to power quick-editing terms.
|
||||
*
|
||||
* @output wp-admin/js/inline-edit-tax.js
|
||||
*/
|
||||
|
||||
/* global inlineEditL10n, ajaxurl, inlineEditTax */
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Consists of functions relevant to the inline taxonomy editor.
|
||||
*
|
||||
* @namespace inlineEditTax
|
||||
*
|
||||
* @property {string} type The type of inline edit we are currently on.
|
||||
* @property {string} what The type property with a hash prefixed and a dash
|
||||
* suffixed.
|
||||
*/
|
||||
( function( $, wp ) {
|
||||
|
||||
window.inlineEditTax = {
|
||||
|
||||
/**
|
||||
* Initializes the inline taxonomy editor by adding event handlers to be able to
|
||||
* quick edit.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function() {
|
||||
var t = this, row = $('#inline-edit');
|
||||
|
||||
t.type = $('#the-list').attr('data-wp-lists').substr(5);
|
||||
t.what = '#'+t.type+'-';
|
||||
|
||||
$( '#the-list' ).on( 'click', '.editinline', function() {
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
inlineEditTax.edit( this );
|
||||
});
|
||||
|
||||
/**
|
||||
* Cancels inline editing when pressing escape inside the inline editor.
|
||||
*
|
||||
* @param {Object} e The keyup event that has been triggered.
|
||||
*/
|
||||
row.keyup( function( e ) {
|
||||
// 27 = [escape]
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditTax.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cancels inline editing when clicking the cancel button.
|
||||
*/
|
||||
$( '.cancel', row ).click( function() {
|
||||
return inlineEditTax.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits when clicking the save button.
|
||||
*/
|
||||
$( '.save', row ).click( function() {
|
||||
return inlineEditTax.save(this);
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits when pressing enter inside the inline editor.
|
||||
*/
|
||||
$( 'input, select', row ).keydown( function( e ) {
|
||||
// 13 = [enter]
|
||||
if ( e.which === 13 ) {
|
||||
return inlineEditTax.save( this );
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits on submitting the inline edit form.
|
||||
*/
|
||||
$( '#posts-filter input[type="submit"]' ).mousedown( function() {
|
||||
t.revert();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the quick edit based on if it is currently shown or hidden.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {HTMLElement} el An element within the table row or the table row
|
||||
* itself that we want to quick edit.
|
||||
* @returns {void}
|
||||
*/
|
||||
toggle : function(el) {
|
||||
var t = this;
|
||||
|
||||
$(t.what+t.getId(el)).css('display') === 'none' ? t.revert() : t.edit(el);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the quick editor
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {string|HTMLElement} id The ID of the term we want to quick edit or an
|
||||
* element within the table row or the
|
||||
* table row itself.
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
edit : function(id) {
|
||||
var editRow, rowData, val,
|
||||
t = this;
|
||||
t.revert();
|
||||
|
||||
// Makes sure we can pass an HTMLElement as the ID.
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = t.getId(id);
|
||||
}
|
||||
|
||||
editRow = $('#inline-edit').clone(true), rowData = $('#inline_'+id);
|
||||
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.wp-list-table.widefat:first thead' ).length );
|
||||
|
||||
$(t.what+id).hide().after(editRow).after('<tr class="hidden"></tr>');
|
||||
|
||||
val = $('.name', rowData);
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="name"]', editRow).val( val );
|
||||
|
||||
val = $('.slug', rowData);
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="slug"]', editRow).val( val );
|
||||
|
||||
$(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show();
|
||||
$('.ptitle', editRow).eq(0).focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the quick edit data.
|
||||
*
|
||||
* Saves the quick edit data to the server and replaces the table row with the
|
||||
* HTML retrieved from the server.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {string|HTMLElement} id The ID of the term we want to quick edit or an
|
||||
* element within the table row or the
|
||||
* table row itself.
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
save : function(id) {
|
||||
var params, fields, tax = $('input[name="taxonomy"]').val() || '';
|
||||
|
||||
// Makes sure we can pass an HTMLElement as the ID.
|
||||
if( typeof(id) === 'object' ) {
|
||||
id = this.getId(id);
|
||||
}
|
||||
|
||||
$( 'table.widefat .spinner' ).addClass( 'is-active' );
|
||||
|
||||
params = {
|
||||
action: 'inline-save-tax',
|
||||
tax_type: this.type,
|
||||
tax_ID: id,
|
||||
taxonomy: tax
|
||||
};
|
||||
|
||||
fields = $('#edit-'+id).find(':input').serialize();
|
||||
params = fields + '&' + $.param(params);
|
||||
|
||||
// Do the ajax request to save the data to the server.
|
||||
$.post( ajaxurl, params,
|
||||
/**
|
||||
* Handles the response from the server
|
||||
*
|
||||
* Handles the response from the server, replaces the table row with the response
|
||||
* from the server.
|
||||
*
|
||||
* @param {string} r The string with which to replace the table row.
|
||||
*/
|
||||
function(r) {
|
||||
var row, new_id, option_value,
|
||||
$errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
if (r) {
|
||||
if ( -1 !== r.indexOf( '<tr' ) ) {
|
||||
$(inlineEditTax.what+id).siblings('tr.hidden').addBack().remove();
|
||||
new_id = $(r).attr('id');
|
||||
|
||||
$('#edit-'+id).before(r).remove();
|
||||
|
||||
if ( new_id ) {
|
||||
option_value = new_id.replace( inlineEditTax.type + '-', '' );
|
||||
row = $( '#' + new_id );
|
||||
} else {
|
||||
option_value = id;
|
||||
row = $( inlineEditTax.what + id );
|
||||
}
|
||||
|
||||
// Update the value in the Parent dropdown.
|
||||
$( '#parent' ).find( 'option[value=' + option_value + ']' ).text( row.find( '.row-title' ).text() );
|
||||
|
||||
row.hide().fadeIn( 400, function() {
|
||||
// Move focus back to the Quick Edit button.
|
||||
row.find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
wp.a11y.speak( inlineEditL10n.saved );
|
||||
});
|
||||
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( r );
|
||||
/*
|
||||
* Some error strings may contain HTML entities (e.g. `“`), let's use
|
||||
* the HTML element's text.
|
||||
*/
|
||||
wp.a11y.speak( $error.text() );
|
||||
}
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( inlineEditL10n.error );
|
||||
wp.a11y.speak( inlineEditL10n.error );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Prevent submitting the form when pressing Enter on a focused field.
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the quick edit form.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
* @returns {void}
|
||||
*/
|
||||
revert : function() {
|
||||
var id = $('table.widefat tr.inline-editor').attr('id');
|
||||
|
||||
if ( id ) {
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
$('#'+id).siblings('tr.hidden').addBack().remove();
|
||||
id = id.substr( id.lastIndexOf('-') + 1 );
|
||||
|
||||
// Show the taxonomy row and move focus back to the Quick Edit button.
|
||||
$( this.what + id ).show().find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the ID of the term of the element inside the table row.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {HTMLElement} o An element within the table row or the table row itself.
|
||||
* @returns {string} The ID of the term based on the element.
|
||||
*/
|
||||
getId : function(o) {
|
||||
var id = o.tagName === 'TR' ? o.id : $(o).parents('tr').attr('id'), parts = id.split('-');
|
||||
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function(){inlineEditTax.init();});
|
||||
|
||||
})( jQuery, window.wp );
|
||||
1
wp-admin/js/inline-edit-tax.min.js
vendored
Normal file
1
wp-admin/js/inline-edit-tax.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
window.wp=window.wp||{},function(s,l){window.inlineEditTax={init:function(){var t=this,i=s("#inline-edit");t.type=s("#the-list").attr("data-wp-lists").substr(5),t.what="#"+t.type+"-",s("#the-list").on("click",".editinline",function(){s(this).attr("aria-expanded","true"),inlineEditTax.edit(this)}),i.keyup(function(t){if(27===t.which)return inlineEditTax.revert()}),s(".cancel",i).click(function(){return inlineEditTax.revert()}),s(".save",i).click(function(){return inlineEditTax.save(this)}),s("input, select",i).keydown(function(t){if(13===t.which)return inlineEditTax.save(this)}),s('#posts-filter input[type="submit"]').mousedown(function(){t.revert()})},toggle:function(t){var i=this;"none"===s(i.what+i.getId(t)).css("display")?i.revert():i.edit(t)},edit:function(t){var i,e,n,a=this;return a.revert(),"object"==typeof t&&(t=a.getId(t)),i=s("#inline-edit").clone(!0),e=s("#inline_"+t),s("td",i).attr("colspan",s("th:visible, td:visible",".wp-list-table.widefat:first thead").length),s(a.what+t).hide().after(i).after('<tr class="hidden"></tr>'),(n=s(".name",e)).find("img").replaceWith(function(){return this.alt}),n=n.text(),s(':input[name="name"]',i).val(n),(n=s(".slug",e)).find("img").replaceWith(function(){return this.alt}),n=n.text(),s(':input[name="slug"]',i).val(n),s(i).attr("id","edit-"+t).addClass("inline-editor").show(),s(".ptitle",i).eq(0).focus(),!1},save:function(d){var t,i=s('input[name="taxonomy"]').val()||"";return"object"==typeof d&&(d=this.getId(d)),s("table.widefat .spinner").addClass("is-active"),t={action:"inline-save-tax",tax_type:this.type,tax_ID:d,taxonomy:i},t=s("#edit-"+d).find(":input").serialize()+"&"+s.param(t),s.post(ajaxurl,t,function(t){var i,e,n,a=s("#edit-"+d+" .inline-edit-save .notice-error"),r=a.find(".error");s("table.widefat .spinner").removeClass("is-active"),t?-1!==t.indexOf("<tr")?(s(inlineEditTax.what+d).siblings("tr.hidden").addBack().remove(),e=s(t).attr("id"),s("#edit-"+d).before(t).remove(),i=e?(n=e.replace(inlineEditTax.type+"-",""),s("#"+e)):(n=d,s(inlineEditTax.what+d)),s("#parent").find("option[value="+n+"]").text(i.find(".row-title").text()),i.hide().fadeIn(400,function(){i.find(".editinline").attr("aria-expanded","false").focus(),l.a11y.speak(inlineEditL10n.saved)})):(a.removeClass("hidden"),r.html(t),l.a11y.speak(r.text())):(a.removeClass("hidden"),r.html(inlineEditL10n.error),l.a11y.speak(inlineEditL10n.error))}),!1},revert:function(){var t=s("table.widefat tr.inline-editor").attr("id");t&&(s("table.widefat .spinner").removeClass("is-active"),s("#"+t).siblings("tr.hidden").addBack().remove(),t=t.substr(t.lastIndexOf("-")+1),s(this.what+t).show().find(".editinline").attr("aria-expanded","false").focus())},getId:function(t){var i=("TR"===t.tagName?t.id:s(t).parents("tr").attr("id")).split("-");return i[i.length-1]}},s(document).ready(function(){inlineEditTax.init()})}(jQuery,window.wp);
|
||||
4
wp-admin/js/iris.min.js
vendored
Normal file
4
wp-admin/js/iris.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
36
wp-admin/js/language-chooser.js
Normal file
36
wp-admin/js/language-chooser.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @output wp-admin/js/language-chooser.js
|
||||
*/
|
||||
|
||||
jQuery( function($) {
|
||||
/*
|
||||
* Set the correct translation to the continue button and show a spinner
|
||||
* when downloading a language.
|
||||
*/
|
||||
var select = $( '#language' ),
|
||||
submit = $( '#language-continue' );
|
||||
|
||||
if ( ! $( 'body' ).hasClass( 'language-chooser' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
select.focus().on( 'change', function() {
|
||||
/*
|
||||
* When a language is selected, set matching translation to continue button
|
||||
* and attach the language attribute.
|
||||
*/
|
||||
var option = select.children( 'option:selected' );
|
||||
submit.attr({
|
||||
value: option.data( 'continue' ),
|
||||
lang: option.attr( 'lang' )
|
||||
});
|
||||
});
|
||||
|
||||
$( 'form' ).submit( function() {
|
||||
// Show spinner for languages that need to be downloaded.
|
||||
if ( ! select.children( 'option:selected' ).data( 'installed' ) ) {
|
||||
$( this ).find( '.step .spinner' ).css( 'visibility', 'visible' );
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
1
wp-admin/js/language-chooser.min.js
vendored
Normal file
1
wp-admin/js/language-chooser.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(function(n){var a=n("#language"),e=n("#language-continue");n("body").hasClass("language-chooser")&&(a.focus().on("change",function(){var n=a.children("option:selected");e.attr({value:n.data("continue"),lang:n.attr("lang")})}),n("form").submit(function(){a.children("option:selected").data("installed")||n(this).find(".step .spinner").css("visibility","visible")}))});
|
||||
136
wp-admin/js/link.js
Normal file
136
wp-admin/js/link.js
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* @output wp-admin/js/link.js
|
||||
*/
|
||||
|
||||
/* global postboxes, deleteUserSetting, setUserSetting, getUserSetting */
|
||||
|
||||
jQuery(document).ready( function($) {
|
||||
|
||||
var newCat, noSyncChecks = false, syncChecks, catAddAfter;
|
||||
|
||||
$('#link_name').focus();
|
||||
// postboxes
|
||||
postboxes.add_postbox_toggles('link');
|
||||
|
||||
/**
|
||||
* Adds event that opens a particular category tab.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @return {boolean} Always returns false to prevent the default behavior.
|
||||
*/
|
||||
$('#category-tabs a').click(function(){
|
||||
var t = $(this).attr('href');
|
||||
$(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
|
||||
$('.tabs-panel').hide();
|
||||
$(t).show();
|
||||
if ( '#categories-all' == t )
|
||||
deleteUserSetting('cats');
|
||||
else
|
||||
setUserSetting('cats','pop');
|
||||
return false;
|
||||
});
|
||||
if ( getUserSetting('cats') )
|
||||
$('#category-tabs a[href="#categories-pop"]').click();
|
||||
|
||||
// Ajax Cat
|
||||
newCat = $('#newcat').one( 'focus', function() { $(this).val( '' ).removeClass( 'form-input-tip' ); } );
|
||||
|
||||
/**
|
||||
* After adding a new category, focus on the category add input field.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$('#link-category-add-submit').click( function() { newCat.focus(); } );
|
||||
|
||||
/**
|
||||
* Synchronize category checkboxes.
|
||||
*
|
||||
* This function makes sure that the checkboxes are synced between the all
|
||||
* categories tab and the most used categories tab.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
syncChecks = function() {
|
||||
if ( noSyncChecks )
|
||||
return;
|
||||
noSyncChecks = true;
|
||||
var th = $(this), c = th.is(':checked'), id = th.val().toString();
|
||||
$('#in-link-category-' + id + ', #in-popular-link_category-' + id).prop( 'checked', c );
|
||||
noSyncChecks = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds event listeners to an added category.
|
||||
*
|
||||
* This is run on the addAfter event to make sure the correct event listeners
|
||||
* are bound to the DOM elements.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param {string} r Raw XML response returned from the server after adding a
|
||||
* category.
|
||||
* @param {Object} s List manager configuration object; settings for the Ajax
|
||||
* request.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
catAddAfter = function( r, s ) {
|
||||
$(s.what + ' response_data', r).each( function() {
|
||||
var t = $($(this).text());
|
||||
t.find( 'label' ).each( function() {
|
||||
var th = $(this), val = th.find('input').val(), id = th.find('input')[0].id, name = $.trim( th.text() ), o;
|
||||
$('#' + id).change( syncChecks );
|
||||
o = $( '<option value="' + parseInt( val, 10 ) + '"></option>' ).text( name );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
/*
|
||||
* Instantiates the list manager.
|
||||
*
|
||||
* @see js/_enqueues/lib/lists.js
|
||||
*/
|
||||
$('#categorychecklist').wpList( {
|
||||
// CSS class name for alternate styling.
|
||||
alt: '',
|
||||
|
||||
// The type of list.
|
||||
what: 'link-category',
|
||||
|
||||
// ID of the element the parsed Ajax response will be stored in.
|
||||
response: 'category-ajax-response',
|
||||
|
||||
// Callback that's run after an item got added to the list.
|
||||
addAfter: catAddAfter
|
||||
} );
|
||||
|
||||
// All categories is the default tab, so we delete the user setting.
|
||||
$('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');});
|
||||
|
||||
// Set a preference for the popular categories to cookies.
|
||||
$('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');});
|
||||
|
||||
if ( 'pop' == getUserSetting('cats') )
|
||||
$('a[href="#categories-pop"]').click();
|
||||
|
||||
/**
|
||||
* Adds event handler that shows the interface controls to add a new category.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {boolean} Always returns false to prevent regular link
|
||||
* functionality.
|
||||
*/
|
||||
$('#category-add-toggle').click( function() {
|
||||
$(this).parents('div:first').toggleClass( 'wp-hidden-children' );
|
||||
$('#category-tabs a[href="#categories-all"]').click();
|
||||
$('#newcategory').focus();
|
||||
return false;
|
||||
} );
|
||||
|
||||
$('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change();
|
||||
});
|
||||
1
wp-admin/js/link.min.js
vendored
Normal file
1
wp-admin/js/link.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(i){var t,s,e,c=!1;i("#link_name").focus(),postboxes.add_postbox_toggles("link"),i("#category-tabs a").click(function(){var t=i(this).attr("href");return i(this).parent().addClass("tabs").siblings("li").removeClass("tabs"),i(".tabs-panel").hide(),i(t).show(),"#categories-all"==t?deleteUserSetting("cats"):setUserSetting("cats","pop"),!1}),getUserSetting("cats")&&i('#category-tabs a[href="#categories-pop"]').click(),t=i("#newcat").one("focus",function(){i(this).val("").removeClass("form-input-tip")}),i("#link-category-add-submit").click(function(){t.focus()}),s=function(){if(!c){c=!0;var t=i(this),e=t.is(":checked"),a=t.val().toString();i("#in-link-category-"+a+", #in-popular-link_category-"+a).prop("checked",e),c=!1}},e=function(t,e){i(e.what+" response_data",t).each(function(){i(i(this).text()).find("label").each(function(){var t=i(this),e=t.find("input").val(),a=t.find("input")[0].id,c=i.trim(t.text());i("#"+a).change(s),i('<option value="'+parseInt(e,10)+'"></option>').text(c)})})},i("#categorychecklist").wpList({alt:"",what:"link-category",response:"category-ajax-response",addAfter:e}),i('a[href="#categories-all"]').click(function(){deleteUserSetting("cats")}),i('a[href="#categories-pop"]').click(function(){setUserSetting("cats","pop")}),"pop"==getUserSetting("cats")&&i('a[href="#categories-pop"]').click(),i("#category-add-toggle").click(function(){return i(this).parents("div:first").toggleClass("wp-hidden-children"),i('#category-tabs a[href="#categories-all"]').click(),i("#newcategory").focus(),!1}),i(".categorychecklist :checkbox").change(s).filter(":checked").change()});
|
||||
41
wp-admin/js/media-gallery.js
Normal file
41
wp-admin/js/media-gallery.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* This file is used on media-upload.php which has been replaced by media-new.php and upload.php
|
||||
*
|
||||
* @deprecated 3.5.0
|
||||
* @output wp-admin/js/media-gallery.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl */
|
||||
jQuery(function($) {
|
||||
/**
|
||||
* Adds a click event handler to the element with a 'wp-gallery' class.
|
||||
*/
|
||||
$( 'body' ).bind( 'click.wp-gallery', function(e) {
|
||||
var target = $( e.target ), id, img_size;
|
||||
|
||||
if ( target.hasClass( 'wp-set-header' ) ) {
|
||||
// Opens the image to preview it full size.
|
||||
( window.dialogArguments || opener || parent || top ).location.href = target.data( 'location' );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass( 'wp-set-background' ) ) {
|
||||
// Sets the image as background of the theme.
|
||||
id = target.data( 'attachment-id' );
|
||||
img_size = $( 'input[name="attachments[' + id + '][image-size]"]:checked').val();
|
||||
|
||||
/**
|
||||
* This AJAX action has been deprecated since 3.5.0, see custom-background.php
|
||||
*/
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'set-background-image',
|
||||
attachment_id: id,
|
||||
size: img_size
|
||||
}, function() {
|
||||
var win = window.dialogArguments || opener || parent || top;
|
||||
win.tb_remove();
|
||||
win.location.reload();
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
1
wp-admin/js/media-gallery.min.js
vendored
Normal file
1
wp-admin/js/media-gallery.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(function(o){o("body").bind("click.wp-gallery",function(a){var e,t,n=o(a.target);n.hasClass("wp-set-header")?((window.dialogArguments||opener||parent||top).location.href=n.data("location"),a.preventDefault()):n.hasClass("wp-set-background")&&(e=n.data("attachment-id"),t=o('input[name="attachments['+e+'][image-size]"]:checked').val(),jQuery.post(ajaxurl,{action:"set-background-image",attachment_id:e,size:t},function(){var a=window.dialogArguments||opener||parent||top;a.tb_remove(),a.location.reload()}),a.preventDefault())})});
|
||||
113
wp-admin/js/media-upload.js
Normal file
113
wp-admin/js/media-upload.js
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Contains global functions for the media upload within the post edit screen.
|
||||
*
|
||||
* Updates the ThickBox anchor href and the ThickBox's own properties in order
|
||||
* to set the size and position on every resize event. Also adds a function to
|
||||
* send HTML or text to the currently active editor.
|
||||
*
|
||||
* @file
|
||||
* @since 2.5.0
|
||||
* @output wp-admin/js/media-upload.js
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
|
||||
/* global tinymce, QTags, wpActiveEditor, tb_position */
|
||||
|
||||
/**
|
||||
* Sends the HTML passed in the parameters to TinyMCE.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @param {string} html The HTML to be sent to the editor.
|
||||
* @returns {void|boolean} Returns false when both TinyMCE and QTags instances
|
||||
* are unavailable. This means that the HTML was not
|
||||
* sent to the editor.
|
||||
*/
|
||||
window.send_to_editor = function( html ) {
|
||||
var editor,
|
||||
hasTinymce = typeof tinymce !== 'undefined',
|
||||
hasQuicktags = typeof QTags !== 'undefined';
|
||||
|
||||
// If no active editor is set, try to set it.
|
||||
if ( ! wpActiveEditor ) {
|
||||
if ( hasTinymce && tinymce.activeEditor ) {
|
||||
editor = tinymce.activeEditor;
|
||||
window.wpActiveEditor = editor.id;
|
||||
} else if ( ! hasQuicktags ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( hasTinymce ) {
|
||||
editor = tinymce.get( wpActiveEditor );
|
||||
}
|
||||
|
||||
// If the editor is set and not hidden, insert the HTML into the content of the
|
||||
// editor.
|
||||
if ( editor && ! editor.isHidden() ) {
|
||||
editor.execCommand( 'mceInsertContent', false, html );
|
||||
} else if ( hasQuicktags ) {
|
||||
// If quick tags are available, insert the HTML into its content.
|
||||
QTags.insertContent( html );
|
||||
} else {
|
||||
// If neither the TinyMCE editor and the quick tags are available, add the HTML
|
||||
// to the current active editor.
|
||||
document.getElementById( wpActiveEditor ).value += html;
|
||||
}
|
||||
|
||||
// If the old thickbox remove function exists, call it.
|
||||
if ( window.tb_remove ) {
|
||||
try { window.tb_remove(); } catch( e ) {}
|
||||
}
|
||||
};
|
||||
|
||||
(function($) {
|
||||
/**
|
||||
* Recalculates and applies the new ThickBox position based on the current
|
||||
* window size.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @returns {Object[]} Array containing jQuery objects for all the found
|
||||
* ThickBox anchors.
|
||||
*/
|
||||
window.tb_position = function() {
|
||||
var tbWindow = $('#TB_window'),
|
||||
width = $(window).width(),
|
||||
H = $(window).height(),
|
||||
W = ( 833 < width ) ? 833 : width,
|
||||
adminbar_height = 0;
|
||||
|
||||
if ( $('#wpadminbar').length ) {
|
||||
adminbar_height = parseInt( $('#wpadminbar').css('height'), 10 );
|
||||
}
|
||||
|
||||
if ( tbWindow.length ) {
|
||||
tbWindow.width( W - 50 ).height( H - 45 - adminbar_height );
|
||||
$('#TB_iframeContent').width( W - 50 ).height( H - 75 - adminbar_height );
|
||||
tbWindow.css({'margin-left': '-' + parseInt( ( ( W - 50 ) / 2 ), 10 ) + 'px'});
|
||||
if ( typeof document.body.style.maxWidth !== 'undefined' )
|
||||
tbWindow.css({'top': 20 + adminbar_height + 'px', 'margin-top': '0'});
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the new height and width for all links with a ThickBox class.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
return $('a.thickbox').each( function() {
|
||||
var href = $(this).attr('href');
|
||||
if ( ! href ) return;
|
||||
href = href.replace(/&width=[0-9]+/g, '');
|
||||
href = href.replace(/&height=[0-9]+/g, '');
|
||||
$(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 - adminbar_height ) );
|
||||
});
|
||||
};
|
||||
|
||||
// Add handler to recalculates the ThickBox position when the window is resized.
|
||||
$(window).resize(function(){ tb_position(); });
|
||||
|
||||
})(jQuery);
|
||||
1
wp-admin/js/media-upload.min.js
vendored
Normal file
1
wp-admin/js/media-upload.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
window.send_to_editor=function(t){var e,i="undefined"!=typeof tinymce,n="undefined"!=typeof QTags;if(wpActiveEditor)i&&(e=tinymce.get(wpActiveEditor));else if(i&&tinymce.activeEditor)e=tinymce.activeEditor,window.wpActiveEditor=e.id;else if(!n)return!1;if(e&&!e.isHidden()?e.execCommand("mceInsertContent",!1,t):n?QTags.insertContent(t):document.getElementById(wpActiveEditor).value+=t,window.tb_remove)try{window.tb_remove()}catch(t){}},function(d){window.tb_position=function(){var t=d("#TB_window"),e=d(window).width(),i=d(window).height(),n=833<e?833:e,o=0;return d("#wpadminbar").length&&(o=parseInt(d("#wpadminbar").css("height"),10)),t.length&&(t.width(n-50).height(i-45-o),d("#TB_iframeContent").width(n-50).height(i-75-o),t.css({"margin-left":"-"+parseInt((n-50)/2,10)+"px"}),void 0!==document.body.style.maxWidth&&t.css({top:20+o+"px","margin-top":"0"})),d("a.thickbox").each(function(){var t=d(this).attr("href");t&&(t=(t=t.replace(/&width=[0-9]+/g,"")).replace(/&height=[0-9]+/g,""),d(this).attr("href",t+"&width="+(n-80)+"&height="+(i-85-o)))})},d(window).resize(function(){tb_position()})}(jQuery);
|
||||
207
wp-admin/js/media.js
Normal file
207
wp-admin/js/media.js
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* Creates a dialog containing posts that can have a particular media attached
|
||||
* to it.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @output wp-admin/js/media.js
|
||||
*
|
||||
* @namespace findPosts
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
|
||||
/* global ajaxurl, attachMediaBoxL10n, _wpMediaGridSettings, showNotice, findPosts */
|
||||
|
||||
( function( $ ){
|
||||
window.findPosts = {
|
||||
/**
|
||||
* Opens a dialog to attach media to a post.
|
||||
*
|
||||
* Adds an overlay prior to retrieving a list of posts to attach the media to.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @param {string} af_name The name of the affected element.
|
||||
* @param {string} af_val The value of the affected post element.
|
||||
*
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
open: function( af_name, af_val ) {
|
||||
var overlay = $( '.ui-find-overlay' );
|
||||
|
||||
if ( overlay.length === 0 ) {
|
||||
$( 'body' ).append( '<div class="ui-find-overlay"></div>' );
|
||||
findPosts.overlay();
|
||||
}
|
||||
|
||||
overlay.show();
|
||||
|
||||
if ( af_name && af_val ) {
|
||||
// #affected is a hidden input field in the dialog that keeps track of which media should be attached.
|
||||
$( '#affected' ).attr( 'name', af_name ).val( af_val );
|
||||
}
|
||||
|
||||
$( '#find-posts' ).show();
|
||||
|
||||
// Close the dialog when the escape key is pressed.
|
||||
$('#find-posts-input').focus().keyup( function( event ){
|
||||
if ( event.which == 27 ) {
|
||||
findPosts.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Retrieves a list of applicable posts for media attachment and shows them.
|
||||
findPosts.send();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the found posts lists before hiding the attach media dialog.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
close: function() {
|
||||
$('#find-posts-response').empty();
|
||||
$('#find-posts').hide();
|
||||
$( '.ui-find-overlay' ).hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds a click event listener to the overlay which closes the attach media
|
||||
* dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
overlay: function() {
|
||||
$( '.ui-find-overlay' ).on( 'click', function () {
|
||||
findPosts.close();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves and displays posts based on the search term.
|
||||
*
|
||||
* Sends a post request to the admin_ajax.php, requesting posts based on the
|
||||
* search term provided by the user. Defaults to all posts if no search term is
|
||||
* provided.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
send: function() {
|
||||
var post = {
|
||||
ps: $( '#find-posts-input' ).val(),
|
||||
action: 'find_posts',
|
||||
_ajax_nonce: $('#_ajax_nonce').val()
|
||||
},
|
||||
spinner = $( '.find-box-search .spinner' );
|
||||
|
||||
spinner.addClass( 'is-active' );
|
||||
|
||||
/**
|
||||
* Send a POST request to admin_ajax.php, hide the spinner and replace the list
|
||||
* of posts with the response data. If an error occurs, display it.
|
||||
*/
|
||||
$.ajax( ajaxurl, {
|
||||
type: 'POST',
|
||||
data: post,
|
||||
dataType: 'json'
|
||||
}).always( function() {
|
||||
spinner.removeClass( 'is-active' );
|
||||
}).done( function( x ) {
|
||||
if ( ! x.success ) {
|
||||
$( '#find-posts-response' ).text( attachMediaBoxL10n.error );
|
||||
}
|
||||
|
||||
$( '#find-posts-response' ).html( x.data );
|
||||
}).fail( function() {
|
||||
$( '#find-posts-response' ).text( attachMediaBoxL10n.error );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the file once the DOM is fully loaded and attaches events to the
|
||||
* various form elements.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( document ).ready( function() {
|
||||
var settings, $mediaGridWrap = $( '#wp-media-grid' );
|
||||
|
||||
// Opens a manage media frame into the grid.
|
||||
if ( $mediaGridWrap.length && window.wp && window.wp.media ) {
|
||||
settings = _wpMediaGridSettings;
|
||||
|
||||
window.wp.media({
|
||||
frame: 'manage',
|
||||
container: $mediaGridWrap,
|
||||
library: settings.queryVars
|
||||
}).open();
|
||||
}
|
||||
|
||||
// Prevents form submission if no post has been selected.
|
||||
$( '#find-posts-submit' ).click( function( event ) {
|
||||
if ( ! $( '#find-posts-response input[type="radio"]:checked' ).length )
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Submits the search query when hitting the enter key in the search input.
|
||||
$( '#find-posts .find-box-search :input' ).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
findPosts.send();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Binds the click event to the search button.
|
||||
$( '#find-posts-search' ).click( findPosts.send );
|
||||
|
||||
// Binds the close dialog click event.
|
||||
$( '#find-posts-close' ).click( findPosts.close );
|
||||
|
||||
// Binds the bulk action events to the submit buttons.
|
||||
$( '#doaction, #doaction2' ).click( function( event ) {
|
||||
|
||||
/*
|
||||
* Retrieves all select elements for bulk actions that have a name starting with `action`
|
||||
* and handle its action based on its value.
|
||||
*/
|
||||
$( 'select[name^="action"]' ).each( function() {
|
||||
var optionValue = $( this ).val();
|
||||
|
||||
if ( 'attach' === optionValue ) {
|
||||
event.preventDefault();
|
||||
findPosts.open();
|
||||
} else if ( 'delete' === optionValue ) {
|
||||
if ( ! showNotice.warn() ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Enables clicking on the entire table row.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '.find-box-inside' ).on( 'click', 'tr', function() {
|
||||
$( this ).find( '.found-radio input' ).prop( 'checked', true );
|
||||
});
|
||||
});
|
||||
})( jQuery );
|
||||
1
wp-admin/js/media.min.js
vendored
Normal file
1
wp-admin/js/media.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(s){window.findPosts={open:function(n,i){var e=s(".ui-find-overlay");return 0===e.length&&(s("body").append('<div class="ui-find-overlay"></div>'),findPosts.overlay()),e.show(),n&&i&&s("#affected").attr("name",n).val(i),s("#find-posts").show(),s("#find-posts-input").focus().keyup(function(n){27==n.which&&findPosts.close()}),findPosts.send(),!1},close:function(){s("#find-posts-response").empty(),s("#find-posts").hide(),s(".ui-find-overlay").hide()},overlay:function(){s(".ui-find-overlay").on("click",function(){findPosts.close()})},send:function(){var n={ps:s("#find-posts-input").val(),action:"find_posts",_ajax_nonce:s("#_ajax_nonce").val()},i=s(".find-box-search .spinner");i.addClass("is-active"),s.ajax(ajaxurl,{type:"POST",data:n,dataType:"json"}).always(function(){i.removeClass("is-active")}).done(function(n){n.success||s("#find-posts-response").text(attachMediaBoxL10n.error),s("#find-posts-response").html(n.data)}).fail(function(){s("#find-posts-response").text(attachMediaBoxL10n.error)})}},s(document).ready(function(){var n,i=s("#wp-media-grid");i.length&&window.wp&&window.wp.media&&(n=_wpMediaGridSettings,window.wp.media({frame:"manage",container:i,library:n.queryVars}).open()),s("#find-posts-submit").click(function(n){s('#find-posts-response input[type="radio"]:checked').length||n.preventDefault()}),s("#find-posts .find-box-search :input").keypress(function(n){if(13==n.which)return findPosts.send(),!1}),s("#find-posts-search").click(findPosts.send),s("#find-posts-close").click(findPosts.close),s("#doaction, #doaction2").click(function(i){s('select[name^="action"]').each(function(){var n=s(this).val();"attach"===n?(i.preventDefault(),findPosts.open()):"delete"===n&&(showNotice.warn()||i.preventDefault())})}),s(".find-box-inside").on("click","tr",function(){s(this).find(".found-radio input").prop("checked",!0)})})}(jQuery);
|
||||
1321
wp-admin/js/nav-menu.js
Normal file
1321
wp-admin/js/nav-menu.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/nav-menu.min.js
vendored
Normal file
1
wp-admin/js/nav-menu.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
121
wp-admin/js/password-strength-meter.js
Normal file
121
wp-admin/js/password-strength-meter.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @output wp-admin/js/password-strength-meter.js
|
||||
*/
|
||||
|
||||
/* global zxcvbn */
|
||||
window.wp = window.wp || {};
|
||||
|
||||
(function($){
|
||||
|
||||
/**
|
||||
* Contains functions to determine the password strength.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
wp.passwordStrength = {
|
||||
/**
|
||||
* Determines the strength of a given password.
|
||||
*
|
||||
* Compares first password to the password confirmation.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param {string} password1 The subject password.
|
||||
* @param {Array} blacklist An array of words that will lower the entropy of
|
||||
* the password.
|
||||
* @param {string} password2 The password confirmation.
|
||||
*
|
||||
* @returns {number} The password strength score.
|
||||
*/
|
||||
meter : function( password1, blacklist, password2 ) {
|
||||
if ( ! $.isArray( blacklist ) )
|
||||
blacklist = [ blacklist.toString() ];
|
||||
|
||||
if (password1 != password2 && password2 && password2.length > 0)
|
||||
return 5;
|
||||
|
||||
if ( 'undefined' === typeof window.zxcvbn ) {
|
||||
// Password strength unknown.
|
||||
return -1;
|
||||
}
|
||||
|
||||
var result = zxcvbn( password1, blacklist );
|
||||
return result.score;
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds an array of words that should be penalized.
|
||||
*
|
||||
* Certain words need to be penalized because it would lower the entropy of a
|
||||
* password if they were used. The blacklist is based on user input fields such
|
||||
* as username, first name, email etc.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @returns {string[]} The array of words to be blacklisted.
|
||||
*/
|
||||
userInputBlacklist : function() {
|
||||
var i, userInputFieldsLength, rawValuesLength, currentField,
|
||||
rawValues = [],
|
||||
blacklist = [],
|
||||
userInputFields = [ 'user_login', 'first_name', 'last_name', 'nickname', 'display_name', 'email', 'url', 'description', 'weblog_title', 'admin_email' ];
|
||||
|
||||
// Collect all the strings we want to blacklist.
|
||||
rawValues.push( document.title );
|
||||
rawValues.push( document.URL );
|
||||
|
||||
userInputFieldsLength = userInputFields.length;
|
||||
for ( i = 0; i < userInputFieldsLength; i++ ) {
|
||||
currentField = $( '#' + userInputFields[ i ] );
|
||||
|
||||
if ( 0 === currentField.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rawValues.push( currentField[0].defaultValue );
|
||||
rawValues.push( currentField.val() );
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip out non-alphanumeric characters and convert each word to an
|
||||
* individual entry.
|
||||
*/
|
||||
rawValuesLength = rawValues.length;
|
||||
for ( i = 0; i < rawValuesLength; i++ ) {
|
||||
if ( rawValues[ i ] ) {
|
||||
blacklist = blacklist.concat( rawValues[ i ].replace( /\W/g, ' ' ).split( ' ' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove empty values, short words and duplicates. Short words are likely to
|
||||
* cause many false positives.
|
||||
*/
|
||||
blacklist = $.grep( blacklist, function( value, key ) {
|
||||
if ( '' === value || 4 > value.length ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $.inArray( value, blacklist ) === key;
|
||||
});
|
||||
|
||||
return blacklist;
|
||||
}
|
||||
};
|
||||
|
||||
// Backward compatibility.
|
||||
|
||||
/**
|
||||
* Password strength meter function.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @deprecated 3.7.0 Use wp.passwordStrength.meter instead.
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @type {wp.passwordStrength.meter}
|
||||
*/
|
||||
window.passwordStrength = wp.passwordStrength.meter;
|
||||
})(jQuery);
|
||||
1
wp-admin/js/password-strength-meter.min.js
vendored
Normal file
1
wp-admin/js/password-strength-meter.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
window.wp=window.wp||{},function(l){wp.passwordStrength={meter:function(n,e,t){return l.isArray(e)||(e=[e.toString()]),n!=t&&t&&0<t.length?5:void 0===window.zxcvbn?-1:zxcvbn(n,e).score},userInputBlacklist:function(){var n,e,t,r,i=[],o=[],a=["user_login","first_name","last_name","nickname","display_name","email","url","description","weblog_title","admin_email"];for(i.push(document.title),i.push(document.URL),e=a.length,n=0;n<e;n++)0!==(r=l("#"+a[n])).length&&(i.push(r[0].defaultValue),i.push(r.val()));for(t=i.length,n=0;n<t;n++)i[n]&&(o=o.concat(i[n].replace(/\W/g," ").split(" ")));return o=l.grep(o,function(n,e){return!(""===n||n.length<4)&&l.inArray(n,o)===e})}},window.passwordStrength=wp.passwordStrength.meter}(jQuery);
|
||||
222
wp-admin/js/plugin-install.js
Normal file
222
wp-admin/js/plugin-install.js
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* @file Functionality for the plugin install screens.
|
||||
*
|
||||
* @output wp-admin/js/plugin-install.js
|
||||
*/
|
||||
|
||||
/* global plugininstallL10n, tb_click, tb_remove, tb_position */
|
||||
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
|
||||
var tbWindow,
|
||||
$iframeBody,
|
||||
$tabbables,
|
||||
$firstTabbable,
|
||||
$lastTabbable,
|
||||
$focusedBefore = $(),
|
||||
$uploadViewToggle = $( '.upload-view-toggle' ),
|
||||
$wrap = $ ( '.wrap' ),
|
||||
$body = $( document.body );
|
||||
|
||||
window.tb_position = function() {
|
||||
var width = $( window ).width(),
|
||||
H = $( window ).height() - ( ( 792 < width ) ? 60 : 20 ),
|
||||
W = ( 792 < width ) ? 772 : width - 20;
|
||||
|
||||
tbWindow = $( '#TB_window' );
|
||||
|
||||
if ( tbWindow.length ) {
|
||||
tbWindow.width( W ).height( H );
|
||||
$( '#TB_iframeContent' ).width( W ).height( H );
|
||||
tbWindow.css({
|
||||
'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px'
|
||||
});
|
||||
if ( typeof document.body.style.maxWidth !== 'undefined' ) {
|
||||
tbWindow.css({
|
||||
'top': '30px',
|
||||
'margin-top': '0'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $( 'a.thickbox' ).each( function() {
|
||||
var href = $( this ).attr( 'href' );
|
||||
if ( ! href ) {
|
||||
return;
|
||||
}
|
||||
href = href.replace( /&width=[0-9]+/g, '' );
|
||||
href = href.replace( /&height=[0-9]+/g, '' );
|
||||
$(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) );
|
||||
});
|
||||
};
|
||||
|
||||
$( window ).resize( function() {
|
||||
tb_position();
|
||||
});
|
||||
|
||||
/*
|
||||
* Custom events: when a Thickbox iframe has loaded and when the Thickbox
|
||||
* modal gets removed from the DOM.
|
||||
*/
|
||||
$body
|
||||
.on( 'thickbox:iframe:loaded', tbWindow, function() {
|
||||
/*
|
||||
* Return if it's not the modal with the plugin details iframe. Other
|
||||
* thickbox instances might want to load an iframe with content from
|
||||
* an external domain. Avoid to access the iframe contents when we're
|
||||
* not sure the iframe loads from the same domain.
|
||||
*/
|
||||
if ( ! tbWindow.hasClass( 'plugin-details-modal' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
iframeLoaded();
|
||||
})
|
||||
.on( 'thickbox:removed', function() {
|
||||
// Set focus back to the element that opened the modal dialog.
|
||||
// Note: IE 8 would need this wrapped in a fake setTimeout `0`.
|
||||
$focusedBefore.focus();
|
||||
});
|
||||
|
||||
function iframeLoaded() {
|
||||
var $iframe = tbWindow.find( '#TB_iframeContent' );
|
||||
|
||||
// Get the iframe body.
|
||||
$iframeBody = $iframe.contents().find( 'body' );
|
||||
|
||||
// Get the tabbable elements and handle the keydown event on first load.
|
||||
handleTabbables();
|
||||
|
||||
// Set initial focus on the "Close" button.
|
||||
$firstTabbable.focus();
|
||||
|
||||
/*
|
||||
* When the "Install" button is disabled (e.g. the Plugin is already installed)
|
||||
* then we can't predict where the last focusable element is. We need to get
|
||||
* the tabbable elements and handle the keydown event again and again,
|
||||
* each time the active tab panel changes.
|
||||
*/
|
||||
$( '#plugin-information-tabs a', $iframeBody ).on( 'click', function() {
|
||||
handleTabbables();
|
||||
});
|
||||
|
||||
// Close the modal when pressing Escape.
|
||||
$iframeBody.on( 'keydown', function( event ) {
|
||||
if ( 27 !== event.which ) {
|
||||
return;
|
||||
}
|
||||
tb_remove();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the tabbable elements and detach/attach the keydown event.
|
||||
* Called after the iframe has fully loaded so we have all the elements we need.
|
||||
* Called again each time a Tab gets clicked.
|
||||
* @todo Consider to implement a WordPress general utility for this and don't use jQuery UI.
|
||||
*/
|
||||
function handleTabbables() {
|
||||
var $firstAndLast;
|
||||
// Get all the tabbable elements.
|
||||
$tabbables = $( ':tabbable', $iframeBody );
|
||||
// Our first tabbable element is always the "Close" button.
|
||||
$firstTabbable = tbWindow.find( '#TB_closeWindowButton' );
|
||||
// Get the last tabbable element.
|
||||
$lastTabbable = $tabbables.last();
|
||||
// Make a jQuery collection.
|
||||
$firstAndLast = $firstTabbable.add( $lastTabbable );
|
||||
// Detach any previously attached keydown event.
|
||||
$firstAndLast.off( 'keydown.wp-plugin-details' );
|
||||
// Attach again the keydown event on the first and last focusable elements.
|
||||
$firstAndLast.on( 'keydown.wp-plugin-details', function( event ) {
|
||||
constrainTabbing( event );
|
||||
});
|
||||
}
|
||||
|
||||
// Constrain tabbing within the plugin modal dialog.
|
||||
function constrainTabbing( event ) {
|
||||
if ( 9 !== event.which ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $lastTabbable[0] === event.target && ! event.shiftKey ) {
|
||||
event.preventDefault();
|
||||
$firstTabbable.focus();
|
||||
} else if ( $firstTabbable[0] === event.target && event.shiftKey ) {
|
||||
event.preventDefault();
|
||||
$lastTabbable.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the Plugin details modal. The event is delegated to get also the links
|
||||
* in the plugins search tab, after the AJAX search rebuilds the HTML. It's
|
||||
* delegated on the closest ancestor and not on the body to avoid conflicts
|
||||
* with other handlers, see Trac ticket #43082.
|
||||
*/
|
||||
$( '.wrap' ).on( 'click', '.thickbox.open-plugin-details-modal', function( e ) {
|
||||
// The `data-title` attribute is used only in the Plugin screens.
|
||||
var title = $( this ).data( 'title' ) ? plugininstallL10n.plugin_information + ' ' + $( this ).data( 'title' ) : plugininstallL10n.plugin_modal_label;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Store the element that has focus before opening the modal dialog, i.e. the control which opens it.
|
||||
$focusedBefore = $( this );
|
||||
|
||||
tb_click.call(this);
|
||||
|
||||
// Set ARIA role, ARIA label, and add a CSS class.
|
||||
tbWindow
|
||||
.attr({
|
||||
'role': 'dialog',
|
||||
'aria-label': plugininstallL10n.plugin_modal_label
|
||||
})
|
||||
.addClass( 'plugin-details-modal' );
|
||||
|
||||
// Set title attribute on the iframe.
|
||||
tbWindow.find( '#TB_iframeContent' ).attr( 'title', title );
|
||||
});
|
||||
|
||||
/* Plugin install related JS */
|
||||
$( '#plugin-information-tabs a' ).click( function( event ) {
|
||||
var tab = $( this ).attr( 'name' );
|
||||
event.preventDefault();
|
||||
|
||||
// Flip the tab
|
||||
$( '#plugin-information-tabs a.current' ).removeClass( 'current' );
|
||||
$( this ).addClass( 'current' );
|
||||
|
||||
// Only show the fyi box in the description section, on smaller screen, where it's otherwise always displayed at the top.
|
||||
if ( 'description' !== tab && $( window ).width() < 772 ) {
|
||||
$( '#plugin-information-content' ).find( '.fyi' ).hide();
|
||||
} else {
|
||||
$( '#plugin-information-content' ).find( '.fyi' ).show();
|
||||
}
|
||||
|
||||
// Flip the content.
|
||||
$( '#section-holder div.section' ).hide(); // Hide 'em all.
|
||||
$( '#section-' + tab ).show();
|
||||
});
|
||||
|
||||
/*
|
||||
* When a user presses the "Upload Plugin" button, show the upload form in place
|
||||
* rather than sending them to the devoted upload plugin page.
|
||||
* The `?tab=upload` page still exists for no-js support and for plugins that
|
||||
* might access it directly. When we're in this page, let the link behave
|
||||
* like a link. Otherwise we're in the normal plugin installer pages and the
|
||||
* link should behave like a toggle button.
|
||||
*/
|
||||
if ( ! $wrap.hasClass( 'plugin-install-tab-upload' ) ) {
|
||||
$uploadViewToggle
|
||||
.attr({
|
||||
role: 'button',
|
||||
'aria-expanded': 'false'
|
||||
})
|
||||
.on( 'click', function( event ) {
|
||||
event.preventDefault();
|
||||
$body.toggleClass( 'show-upload-view' );
|
||||
$uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
|
||||
});
|
||||
}
|
||||
});
|
||||
1
wp-admin/js/plugin-install.min.js
vendored
Normal file
1
wp-admin/js/plugin-install.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(o){var a,i,n,e,l,d=o(),s=o(".upload-view-toggle"),t=o(".wrap"),r=o(document.body);function u(){var t;n=o(":tabbable",i),e=a.find("#TB_closeWindowButton"),l=n.last(),(t=e.add(l)).off("keydown.wp-plugin-details"),t.on("keydown.wp-plugin-details",function(t){!function(t){if(9!==t.which)return;l[0]!==t.target||t.shiftKey?e[0]===t.target&&t.shiftKey&&(t.preventDefault(),l.focus()):(t.preventDefault(),e.focus())}(t)})}window.tb_position=function(){var t=o(window).width(),i=o(window).height()-(792<t?60:20),n=792<t?772:t-20;return(a=o("#TB_window")).length&&(a.width(n).height(i),o("#TB_iframeContent").width(n).height(i),a.css({"margin-left":"-"+parseInt(n/2,10)+"px"}),void 0!==document.body.style.maxWidth&&a.css({top:"30px","margin-top":"0"})),o("a.thickbox").each(function(){var t=o(this).attr("href");t&&(t=(t=t.replace(/&width=[0-9]+/g,"")).replace(/&height=[0-9]+/g,""),o(this).attr("href",t+"&width="+n+"&height="+i))})},o(window).resize(function(){tb_position()}),r.on("thickbox:iframe:loaded",a,function(){a.hasClass("plugin-details-modal")&&function(){var t=a.find("#TB_iframeContent");i=t.contents().find("body"),u(),e.focus(),o("#plugin-information-tabs a",i).on("click",function(){u()}),i.on("keydown",function(t){27===t.which&&tb_remove()})}()}).on("thickbox:removed",function(){d.focus()}),o(".wrap").on("click",".thickbox.open-plugin-details-modal",function(t){var i=o(this).data("title")?plugininstallL10n.plugin_information+" "+o(this).data("title"):plugininstallL10n.plugin_modal_label;t.preventDefault(),t.stopPropagation(),d=o(this),tb_click.call(this),a.attr({role:"dialog","aria-label":plugininstallL10n.plugin_modal_label}).addClass("plugin-details-modal"),a.find("#TB_iframeContent").attr("title",i)}),o("#plugin-information-tabs a").click(function(t){var i=o(this).attr("name");t.preventDefault(),o("#plugin-information-tabs a.current").removeClass("current"),o(this).addClass("current"),"description"!==i&&o(window).width()<772?o("#plugin-information-content").find(".fyi").hide():o("#plugin-information-content").find(".fyi").show(),o("#section-holder div.section").hide(),o("#section-"+i).show()}),t.hasClass("plugin-install-tab-upload")||s.attr({role:"button","aria-expanded":"false"}).on("click",function(t){t.preventDefault(),r.toggleClass("show-upload-view"),s.attr("aria-expanded",r.hasClass("show-upload-view"))})});
|
||||
1273
wp-admin/js/post.js
Normal file
1273
wp-admin/js/post.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/post.min.js
vendored
Normal file
1
wp-admin/js/post.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
445
wp-admin/js/postbox.js
Normal file
445
wp-admin/js/postbox.js
Normal file
@@ -0,0 +1,445 @@
|
||||
/**
|
||||
* Contains the postboxes logic, opening and closing postboxes, reordering and saving
|
||||
* the state and ordering to the database.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @requires jQuery
|
||||
* @output wp-admin/js/postbox.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, postBoxL10n, postboxes */
|
||||
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
/**
|
||||
* This object contains all function to handle the behaviour of the post boxes. The post boxes are the boxes you see
|
||||
* around the content on the edit page.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @namespace postboxes
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
window.postboxes = {
|
||||
|
||||
/**
|
||||
* Handles a click on either the postbox heading or the postbox open/close icon.
|
||||
*
|
||||
* Opens or closes the postbox. Expects `this` to equal the clicked element.
|
||||
* Calls postboxes.pbshow if the postbox has been opened, calls postboxes.pbhide
|
||||
* if the postbox has been closed.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @memberof postboxes
|
||||
* @fires postboxes#postbox-toggled
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
handle_click : function () {
|
||||
var $el = $( this ),
|
||||
p = $el.parent( '.postbox' ),
|
||||
id = p.attr( 'id' ),
|
||||
ariaExpandedValue;
|
||||
|
||||
if ( 'dashboard_browser_nag' === id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
p.toggleClass( 'closed' );
|
||||
|
||||
ariaExpandedValue = ! p.hasClass( 'closed' );
|
||||
|
||||
if ( $el.hasClass( 'handlediv' ) ) {
|
||||
// The handle button was clicked.
|
||||
$el.attr( 'aria-expanded', ariaExpandedValue );
|
||||
} else {
|
||||
// The handle heading was clicked.
|
||||
$el.closest( '.postbox' ).find( 'button.handlediv' )
|
||||
.attr( 'aria-expanded', ariaExpandedValue );
|
||||
}
|
||||
|
||||
if ( postboxes.page !== 'press-this' ) {
|
||||
postboxes.save_state( postboxes.page );
|
||||
}
|
||||
|
||||
if ( id ) {
|
||||
if ( !p.hasClass('closed') && $.isFunction( postboxes.pbshow ) ) {
|
||||
postboxes.pbshow( id );
|
||||
} else if ( p.hasClass('closed') && $.isFunction( postboxes.pbhide ) ) {
|
||||
postboxes.pbhide( id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when a postbox has been opened or closed.
|
||||
*
|
||||
* Contains a jQuery object with the relevant postbox element.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @ignore
|
||||
*
|
||||
* @event postboxes#postbox-toggled
|
||||
* @type {Object}
|
||||
*/
|
||||
$document.trigger( 'postbox-toggled', p );
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds event handlers to all postboxes and screen option on the current page.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @param {Object} [args]
|
||||
* @param {Function} args.pbshow A callback that is called when a postbox opens.
|
||||
* @param {Function} args.pbhide A callback that is called when a postbox closes.
|
||||
* @returns {void}
|
||||
*/
|
||||
add_postbox_toggles : function (page, args) {
|
||||
var $handles = $( '.postbox .hndle, .postbox .handlediv' );
|
||||
|
||||
this.page = page;
|
||||
this.init( page, args );
|
||||
|
||||
$handles.on( 'click.postboxes', this.handle_click );
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
*/
|
||||
$('.postbox .hndle a').click( function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Hides a postbox.
|
||||
*
|
||||
* Event handler for the postbox dismiss button. After clicking the button
|
||||
* the postbox will be hidden.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '.postbox a.dismiss' ).on( 'click.postboxes', function( e ) {
|
||||
var hide_id = $(this).parents('.postbox').attr('id') + '-hide';
|
||||
e.preventDefault();
|
||||
$( '#' + hide_id ).prop('checked', false).triggerHandler('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Hides the postbox element
|
||||
*
|
||||
* Event handler for the screen options checkboxes. When a checkbox is
|
||||
* clicked this function will hide or show the relevant postboxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @ignore
|
||||
*
|
||||
* @fires postboxes#postbox-toggled
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('.hide-postbox-tog').bind('click.postboxes', function() {
|
||||
var $el = $(this),
|
||||
boxId = $el.val(),
|
||||
$postbox = $( '#' + boxId );
|
||||
|
||||
if ( $el.prop( 'checked' ) ) {
|
||||
$postbox.show();
|
||||
if ( $.isFunction( postboxes.pbshow ) ) {
|
||||
postboxes.pbshow( boxId );
|
||||
}
|
||||
} else {
|
||||
$postbox.hide();
|
||||
if ( $.isFunction( postboxes.pbhide ) ) {
|
||||
postboxes.pbhide( boxId );
|
||||
}
|
||||
}
|
||||
|
||||
postboxes.save_state( page );
|
||||
postboxes._mark_area();
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
* @see postboxes.handle_click
|
||||
*/
|
||||
$document.trigger( 'postbox-toggled', $postbox );
|
||||
});
|
||||
|
||||
/**
|
||||
* Changes the amount of columns based on the layout preferences.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('.columns-prefs input[type="radio"]').bind('click.postboxes', function(){
|
||||
var n = parseInt($(this).val(), 10);
|
||||
|
||||
if ( n ) {
|
||||
postboxes._pb_edit(n);
|
||||
postboxes.save_order( page );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes all the postboxes, mainly their sortable behaviour.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @param {Object} [args={}] The arguments for the postbox initializer.
|
||||
* @param {Function} args.pbshow A callback that is called when a postbox opens.
|
||||
* @param {Function} args.pbhide A callback that is called when a postbox
|
||||
* closes.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function(page, args) {
|
||||
var isMobile = $( document.body ).hasClass( 'mobile' ),
|
||||
$handleButtons = $( '.postbox .handlediv' );
|
||||
|
||||
$.extend( this, args || {} );
|
||||
$('#wpbody-content').css('overflow','hidden');
|
||||
$('.meta-box-sortables').sortable({
|
||||
placeholder: 'sortable-placeholder',
|
||||
connectWith: '.meta-box-sortables',
|
||||
items: '.postbox',
|
||||
handle: '.hndle',
|
||||
cursor: 'move',
|
||||
delay: ( isMobile ? 200 : 0 ),
|
||||
distance: 2,
|
||||
tolerance: 'pointer',
|
||||
forcePlaceholderSize: true,
|
||||
helper: function( event, element ) {
|
||||
/* `helper: 'clone'` is equivalent to `return element.clone();`
|
||||
* Cloning a checked radio and then inserting that clone next to the original
|
||||
* radio unchecks the original radio (since only one of the two can be checked).
|
||||
* We get around this by renaming the helper's inputs' name attributes so that,
|
||||
* when the helper is inserted into the DOM for the sortable, no radios are
|
||||
* duplicated, and no original radio gets unchecked.
|
||||
*/
|
||||
return element.clone()
|
||||
.find( ':input' )
|
||||
.attr( 'name', function( i, currentName ) {
|
||||
return 'sort_' + parseInt( Math.random() * 100000, 10 ).toString() + '_' + currentName;
|
||||
} )
|
||||
.end();
|
||||
},
|
||||
opacity: 0.65,
|
||||
stop: function() {
|
||||
var $el = $( this );
|
||||
|
||||
if ( $el.find( '#dashboard_browser_nag' ).is( ':visible' ) && 'dashboard_browser_nag' != this.firstChild.id ) {
|
||||
$el.sortable('cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
postboxes.save_order(page);
|
||||
},
|
||||
receive: function(e,ui) {
|
||||
if ( 'dashboard_browser_nag' == ui.item[0].id )
|
||||
$(ui.sender).sortable('cancel');
|
||||
|
||||
postboxes._mark_area();
|
||||
$document.trigger( 'postbox-moved', ui.item );
|
||||
}
|
||||
});
|
||||
|
||||
if ( isMobile ) {
|
||||
$(document.body).bind('orientationchange.postboxes', function(){ postboxes._pb_change(); });
|
||||
this._pb_change();
|
||||
}
|
||||
|
||||
this._mark_area();
|
||||
|
||||
// Set the handle buttons `aria-expanded` attribute initial value on page load.
|
||||
$handleButtons.each( function () {
|
||||
var $el = $( this );
|
||||
$el.attr( 'aria-expanded', ! $el.parent( '.postbox' ).hasClass( 'closed' ) );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the state of the postboxes to the server.
|
||||
*
|
||||
* It sends two lists, one with all the closed postboxes, one with all the
|
||||
* hidden postboxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @returns {void}
|
||||
*/
|
||||
save_state : function(page) {
|
||||
var closed, hidden;
|
||||
|
||||
// Return on the nav-menus.php screen, see #35112.
|
||||
if ( 'nav-menus' === page ) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = $( '.postbox' ).filter( '.closed' ).map( function() { return this.id; } ).get().join( ',' );
|
||||
hidden = $( '.postbox' ).filter( ':hidden' ).map( function() { return this.id; } ).get().join( ',' );
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'closed-postboxes',
|
||||
closed: closed,
|
||||
hidden: hidden,
|
||||
closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(),
|
||||
page: page
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the order of the postboxes to the server.
|
||||
*
|
||||
* Sends a list of all postboxes inside a sortable area to the server.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @returns {void}
|
||||
*/
|
||||
save_order : function(page) {
|
||||
var postVars, page_columns = $('.columns-prefs input:checked').val() || 0;
|
||||
|
||||
postVars = {
|
||||
action: 'meta-box-order',
|
||||
_ajax_nonce: $('#meta-box-order-nonce').val(),
|
||||
page_columns: page_columns,
|
||||
page: page
|
||||
};
|
||||
|
||||
$('.meta-box-sortables').each( function() {
|
||||
postVars[ 'order[' + this.id.split( '-' )[0] + ']' ] = $( this ).sortable( 'toArray' ).join( ',' );
|
||||
} );
|
||||
|
||||
$.post( ajaxurl, postVars );
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks empty postbox areas.
|
||||
*
|
||||
* Adds a message to empty sortable areas on the dashboard page. Also adds a
|
||||
* border around the side area on the post edit screen if there are no postboxes
|
||||
* present.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_mark_area : function() {
|
||||
var visible = $('div.postbox:visible').length, side = $('#post-body #side-sortables');
|
||||
|
||||
$( '#dashboard-widgets .meta-box-sortables:visible' ).each( function() {
|
||||
var t = $(this);
|
||||
|
||||
if ( visible == 1 || t.children('.postbox:visible').length ) {
|
||||
t.removeClass('empty-container');
|
||||
}
|
||||
else {
|
||||
t.addClass('empty-container');
|
||||
t.attr('data-emptyString', postBoxL10n.postBoxEmptyString);
|
||||
}
|
||||
});
|
||||
|
||||
if ( side.length ) {
|
||||
if ( side.children('.postbox:visible').length )
|
||||
side.removeClass('empty-container');
|
||||
else if ( $('#postbox-container-1').css('width') == '280px' )
|
||||
side.addClass('empty-container');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the amount of columns on the post edit page.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @fires postboxes#postboxes-columnchange
|
||||
* @access private
|
||||
*
|
||||
* @param {number} n The amount of columns to divide the post edit page in.
|
||||
* @returns {void}
|
||||
*/
|
||||
_pb_edit : function(n) {
|
||||
var el = $('.metabox-holder').get(0);
|
||||
|
||||
if ( el ) {
|
||||
el.className = el.className.replace(/columns-\d+/, 'columns-' + n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the amount of columns on the post edit page has been changed.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @ignore
|
||||
*
|
||||
* @event postboxes#postboxes-columnchange
|
||||
*/
|
||||
$( document ).trigger( 'postboxes-columnchange' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the amount of columns the postboxes are in based on the current
|
||||
* orientation of the browser.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_pb_change : function() {
|
||||
var check = $( 'label.columns-prefs-1 input[type="radio"]' );
|
||||
|
||||
switch ( window.orientation ) {
|
||||
case 90:
|
||||
case -90:
|
||||
if ( !check.length || !check.is(':checked') )
|
||||
this._pb_edit(2);
|
||||
break;
|
||||
case 0:
|
||||
case 180:
|
||||
if ( $('#poststuff').length ) {
|
||||
this._pb_edit(1);
|
||||
} else {
|
||||
if ( !check.length || !check.is(':checked') )
|
||||
this._pb_edit(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
* @access public
|
||||
* @property {Function|boolean} pbshow A callback that is called when a postbox
|
||||
* is opened.
|
||||
*/
|
||||
pbshow : false,
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
* @access public
|
||||
* @property {Function|boolean} pbhide A callback that is called when a postbox
|
||||
* is closed.
|
||||
*/
|
||||
pbhide : false
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
1
wp-admin/js/postbox.min.js
vendored
Normal file
1
wp-admin/js/postbox.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(a){var n=a(document);window.postboxes={handle_click:function(){var e,o=a(this),s=o.parent(".postbox"),t=s.attr("id");"dashboard_browser_nag"!==t&&(s.toggleClass("closed"),e=!s.hasClass("closed"),o.hasClass("handlediv")?o.attr("aria-expanded",e):o.closest(".postbox").find("button.handlediv").attr("aria-expanded",e),"press-this"!==postboxes.page&&postboxes.save_state(postboxes.page),t&&(!s.hasClass("closed")&&a.isFunction(postboxes.pbshow)?postboxes.pbshow(t):s.hasClass("closed")&&a.isFunction(postboxes.pbhide)&&postboxes.pbhide(t)),n.trigger("postbox-toggled",s))},add_postbox_toggles:function(t,e){var o=a(".postbox .hndle, .postbox .handlediv");this.page=t,this.init(t,e),o.on("click.postboxes",this.handle_click),a(".postbox .hndle a").click(function(e){e.stopPropagation()}),a(".postbox a.dismiss").on("click.postboxes",function(e){var o=a(this).parents(".postbox").attr("id")+"-hide";e.preventDefault(),a("#"+o).prop("checked",!1).triggerHandler("click")}),a(".hide-postbox-tog").bind("click.postboxes",function(){var e=a(this),o=e.val(),s=a("#"+o);e.prop("checked")?(s.show(),a.isFunction(postboxes.pbshow)&&postboxes.pbshow(o)):(s.hide(),a.isFunction(postboxes.pbhide)&&postboxes.pbhide(o)),postboxes.save_state(t),postboxes._mark_area(),n.trigger("postbox-toggled",s)}),a('.columns-prefs input[type="radio"]').bind("click.postboxes",function(){var e=parseInt(a(this).val(),10);e&&(postboxes._pb_edit(e),postboxes.save_order(t))})},init:function(o,e){var s=a(document.body).hasClass("mobile"),t=a(".postbox .handlediv");a.extend(this,e||{}),a("#wpbody-content").css("overflow","hidden"),a(".meta-box-sortables").sortable({placeholder:"sortable-placeholder",connectWith:".meta-box-sortables",items:".postbox",handle:".hndle",cursor:"move",delay:s?200:0,distance:2,tolerance:"pointer",forcePlaceholderSize:!0,helper:function(e,o){return o.clone().find(":input").attr("name",function(e,o){return"sort_"+parseInt(1e5*Math.random(),10).toString()+"_"+o}).end()},opacity:.65,stop:function(){var e=a(this);e.find("#dashboard_browser_nag").is(":visible")&&"dashboard_browser_nag"!=this.firstChild.id?e.sortable("cancel"):postboxes.save_order(o)},receive:function(e,o){"dashboard_browser_nag"==o.item[0].id&&a(o.sender).sortable("cancel"),postboxes._mark_area(),n.trigger("postbox-moved",o.item)}}),s&&(a(document.body).bind("orientationchange.postboxes",function(){postboxes._pb_change()}),this._pb_change()),this._mark_area(),t.each(function(){var e=a(this);e.attr("aria-expanded",!e.parent(".postbox").hasClass("closed"))})},save_state:function(e){var o,s;"nav-menus"!==e&&(o=a(".postbox").filter(".closed").map(function(){return this.id}).get().join(","),s=a(".postbox").filter(":hidden").map(function(){return this.id}).get().join(","),a.post(ajaxurl,{action:"closed-postboxes",closed:o,hidden:s,closedpostboxesnonce:jQuery("#closedpostboxesnonce").val(),page:e}))},save_order:function(e){var o,s=a(".columns-prefs input:checked").val()||0;o={action:"meta-box-order",_ajax_nonce:a("#meta-box-order-nonce").val(),page_columns:s,page:e},a(".meta-box-sortables").each(function(){o["order["+this.id.split("-")[0]+"]"]=a(this).sortable("toArray").join(",")}),a.post(ajaxurl,o)},_mark_area:function(){var o=a("div.postbox:visible").length,e=a("#post-body #side-sortables");a("#dashboard-widgets .meta-box-sortables:visible").each(function(){var e=a(this);1==o||e.children(".postbox:visible").length?e.removeClass("empty-container"):(e.addClass("empty-container"),e.attr("data-emptyString",postBoxL10n.postBoxEmptyString))}),e.length&&(e.children(".postbox:visible").length?e.removeClass("empty-container"):"280px"==a("#postbox-container-1").css("width")&&e.addClass("empty-container"))},_pb_edit:function(e){var o=a(".metabox-holder").get(0);o&&(o.className=o.className.replace(/columns-\d+/,"columns-"+e)),a(document).trigger("postboxes-columnchange")},_pb_change:function(){var e=a('label.columns-prefs-1 input[type="radio"]');switch(window.orientation){case 90:case-90:e.length&&e.is(":checked")||this._pb_edit(2);break;case 0:case 180:a("#poststuff").length?this._pb_edit(1):e.length&&e.is(":checked")||this._pb_edit(2)}},pbshow:!1,pbhide:!1}}(jQuery);
|
||||
263
wp-admin/js/privacy-tools.js
Normal file
263
wp-admin/js/privacy-tools.js
Normal file
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* Interactions used by the User Privacy tools in WordPress.
|
||||
*
|
||||
* @output wp-admin/js/privacy-tools.js
|
||||
*/
|
||||
|
||||
// Privacy request action handling
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
var strings = window.privacyToolsL10n || {};
|
||||
|
||||
function setActionState( $action, state ) {
|
||||
$action.children().addClass( 'hidden' );
|
||||
$action.children( '.' + state ).removeClass( 'hidden' );
|
||||
}
|
||||
|
||||
function clearResultsAfterRow( $requestRow ) {
|
||||
$requestRow.removeClass( 'has-request-results' );
|
||||
|
||||
if ( $requestRow.next().hasClass( 'request-results' ) ) {
|
||||
$requestRow.next().remove();
|
||||
}
|
||||
}
|
||||
|
||||
function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) {
|
||||
var itemList = '',
|
||||
resultRowClasses = 'request-results';
|
||||
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
if ( additionalMessages.length ) {
|
||||
$.each( additionalMessages, function( index, value ) {
|
||||
itemList = itemList + '<li>' + value + '</li>';
|
||||
});
|
||||
itemList = '<ul>' + itemList + '</ul>';
|
||||
}
|
||||
|
||||
$requestRow.addClass( 'has-request-results' );
|
||||
|
||||
if ( $requestRow.hasClass( 'status-request-confirmed' ) ) {
|
||||
resultRowClasses = resultRowClasses + ' status-request-confirmed';
|
||||
}
|
||||
|
||||
if ( $requestRow.hasClass( 'status-request-failed' ) ) {
|
||||
resultRowClasses = resultRowClasses + ' status-request-failed';
|
||||
}
|
||||
|
||||
$requestRow.after( function() {
|
||||
return '<tr class="' + resultRowClasses + '"><th colspan="5">' +
|
||||
'<div class="notice inline notice-alt ' + classes + '">' +
|
||||
'<p>' + summaryMessage + '</p>' +
|
||||
itemList +
|
||||
'</div>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
});
|
||||
}
|
||||
|
||||
$( '.export-personal-data-handle' ).click( function( event ) {
|
||||
var $this = $( this ),
|
||||
$action = $this.parents( '.export-personal-data' ),
|
||||
$requestRow = $this.parents( 'tr' ),
|
||||
requestID = $action.data( 'request-id' ),
|
||||
nonce = $action.data( 'nonce' ),
|
||||
exportersCount = $action.data( 'exporters-count' ),
|
||||
sendAsEmail = $action.data( 'send-as-email' ) ? true : false;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$action.blur();
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
function onExportDoneSuccess( zipUrl ) {
|
||||
var summaryMessage = strings.emailSent;
|
||||
|
||||
setActionState( $action, 'export-personal-data-success' );
|
||||
|
||||
appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] );
|
||||
$this.hide();
|
||||
|
||||
if ( 'undefined' !== typeof zipUrl ) {
|
||||
window.location = zipUrl;
|
||||
} else if ( ! sendAsEmail ) {
|
||||
onExportFailure( strings.noExportFile );
|
||||
}
|
||||
}
|
||||
|
||||
function onExportFailure( errorMessage ) {
|
||||
setActionState( $action, 'export-personal-data-failed' );
|
||||
if ( errorMessage ) {
|
||||
appendResultsAfterRow( $requestRow, 'notice-error', strings.exportError, [ errorMessage ] );
|
||||
}
|
||||
}
|
||||
|
||||
function doNextExport( exporterIndex, pageIndex ) {
|
||||
$.ajax(
|
||||
{
|
||||
url: window.ajaxurl,
|
||||
data: {
|
||||
action: 'wp-privacy-export-personal-data',
|
||||
exporter: exporterIndex,
|
||||
id: requestID,
|
||||
page: pageIndex,
|
||||
security: nonce,
|
||||
sendAsEmail: sendAsEmail
|
||||
},
|
||||
method: 'post'
|
||||
}
|
||||
).done( function( response ) {
|
||||
var responseData = response.data;
|
||||
|
||||
if ( ! response.success ) {
|
||||
|
||||
// e.g. invalid request ID
|
||||
onExportFailure( response.data );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! responseData.done ) {
|
||||
setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) );
|
||||
} else {
|
||||
if ( exporterIndex < exportersCount ) {
|
||||
setTimeout( doNextExport( exporterIndex + 1, 1 ) );
|
||||
} else {
|
||||
onExportDoneSuccess( responseData.url );
|
||||
}
|
||||
}
|
||||
}).fail( function( jqxhr, textStatus, error ) {
|
||||
|
||||
// e.g. Nonce failure
|
||||
onExportFailure( error );
|
||||
});
|
||||
}
|
||||
|
||||
// And now, let's begin
|
||||
setActionState( $action, 'export-personal-data-processing' );
|
||||
doNextExport( 1, 1 );
|
||||
});
|
||||
|
||||
$( '.remove-personal-data-handle' ).click( function( event ) {
|
||||
var $this = $( this ),
|
||||
$action = $this.parents( '.remove-personal-data' ),
|
||||
$requestRow = $this.parents( 'tr' ),
|
||||
requestID = $action.data( 'request-id' ),
|
||||
nonce = $action.data( 'nonce' ),
|
||||
erasersCount = $action.data( 'erasers-count' ),
|
||||
hasRemoved = false,
|
||||
hasRetained = false,
|
||||
messages = [];
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
$action.blur();
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
function onErasureDoneSuccess() {
|
||||
var summaryMessage = strings.noDataFound;
|
||||
var classes = 'notice-success';
|
||||
|
||||
setActionState( $action, 'remove-personal-data-success' );
|
||||
|
||||
if ( false === hasRemoved ) {
|
||||
if ( false === hasRetained ) {
|
||||
summaryMessage = strings.noDataFound;
|
||||
} else {
|
||||
summaryMessage = strings.noneRemoved;
|
||||
classes = 'notice-warning';
|
||||
}
|
||||
} else {
|
||||
if ( false === hasRetained ) {
|
||||
summaryMessage = strings.foundAndRemoved;
|
||||
} else {
|
||||
summaryMessage = strings.someNotRemoved;
|
||||
classes = 'notice-warning';
|
||||
}
|
||||
}
|
||||
appendResultsAfterRow( $requestRow, classes, summaryMessage, messages );
|
||||
$this.hide();
|
||||
}
|
||||
|
||||
function onErasureFailure() {
|
||||
setActionState( $action, 'remove-personal-data-failed' );
|
||||
appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] );
|
||||
}
|
||||
|
||||
function doNextErasure( eraserIndex, pageIndex ) {
|
||||
$.ajax({
|
||||
url: window.ajaxurl,
|
||||
data: {
|
||||
action: 'wp-privacy-erase-personal-data',
|
||||
eraser: eraserIndex,
|
||||
id: requestID,
|
||||
page: pageIndex,
|
||||
security: nonce
|
||||
},
|
||||
method: 'post'
|
||||
}).done( function( response ) {
|
||||
var responseData = response.data;
|
||||
|
||||
if ( ! response.success ) {
|
||||
onErasureFailure();
|
||||
return;
|
||||
}
|
||||
if ( responseData.items_removed ) {
|
||||
hasRemoved = hasRemoved || responseData.items_removed;
|
||||
}
|
||||
if ( responseData.items_retained ) {
|
||||
hasRetained = hasRetained || responseData.items_retained;
|
||||
}
|
||||
if ( responseData.messages ) {
|
||||
messages = messages.concat( responseData.messages );
|
||||
}
|
||||
if ( ! responseData.done ) {
|
||||
setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) );
|
||||
} else {
|
||||
if ( eraserIndex < erasersCount ) {
|
||||
setTimeout( doNextErasure( eraserIndex + 1, 1 ) );
|
||||
} else {
|
||||
onErasureDoneSuccess();
|
||||
}
|
||||
}
|
||||
}).fail( function() {
|
||||
onErasureFailure();
|
||||
});
|
||||
}
|
||||
|
||||
// And now, let's begin
|
||||
setActionState( $action, 'remove-personal-data-processing' );
|
||||
|
||||
doNextErasure( 1, 1 );
|
||||
});
|
||||
|
||||
// Privacy policy page, copy button.
|
||||
$( document ).on( 'click', function( event ) {
|
||||
var $target = $( event.target );
|
||||
var $parent, $container, range;
|
||||
|
||||
if ( $target.is( 'button.privacy-text-copy' ) ) {
|
||||
$parent = $target.parent().parent();
|
||||
$container = $parent.find( 'div.wp-suggested-text' );
|
||||
|
||||
if ( ! $container.length ) {
|
||||
$container = $parent.find( 'div.policy-text' );
|
||||
}
|
||||
|
||||
if ( $container.length ) {
|
||||
try {
|
||||
window.getSelection().removeAllRanges();
|
||||
range = document.createRange();
|
||||
$container.addClass( 'hide-privacy-policy-tutorial' );
|
||||
|
||||
range.selectNodeContents( $container[0] );
|
||||
window.getSelection().addRange( range );
|
||||
document.execCommand( 'copy' );
|
||||
|
||||
$container.removeClass( 'hide-privacy-policy-tutorial' );
|
||||
window.getSelection().removeAllRanges();
|
||||
} catch ( er ) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
1
wp-admin/js/privacy-tools.min.js
vendored
Normal file
1
wp-admin/js/privacy-tools.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(v){var f=window.privacyToolsL10n||{};function h(e,t){e.children().addClass("hidden"),e.children("."+t).removeClass("hidden")}function g(e){e.removeClass("has-request-results"),e.next().hasClass("request-results")&&e.next().remove()}function x(e,t,a,n){var o="",s="request-results";g(e),n.length&&(v.each(n,function(e,t){o=o+"<li>"+t+"</li>"}),o="<ul>"+o+"</ul>"),e.addClass("has-request-results"),e.hasClass("status-request-confirmed")&&(s+=" status-request-confirmed"),e.hasClass("status-request-failed")&&(s+=" status-request-failed"),e.after(function(){return'<tr class="'+s+'"><th colspan="5"><div class="notice inline notice-alt '+t+'"><p>'+a+"</p>"+o+"</div></td></tr>"})}v(".export-personal-data-handle").click(function(e){var s=v(this),r=s.parents(".export-personal-data"),i=s.parents("tr"),t=r.data("request-id"),d=r.data("nonce"),c=r.data("exporters-count"),l=!!r.data("send-as-email");function u(e){h(r,"export-personal-data-failed"),e&&x(i,"notice-error",f.exportError,[e])}e.preventDefault(),e.stopPropagation(),r.blur(),g(i),h(r,"export-personal-data-processing"),function a(n,o){v.ajax({url:window.ajaxurl,data:{action:"wp-privacy-export-personal-data",exporter:n,id:t,page:o,security:d,sendAsEmail:l},method:"post"}).done(function(e){var t=e.data;e.success?t.done?n<c?setTimeout(a(n+1,1)):function(e){var t=f.emailSent;h(r,"export-personal-data-success"),x(i,"notice-success",t,[]),s.hide(),void 0!==e?window.location=e:l||u(f.noExportFile)}(t.url):setTimeout(a(n,o+1)):u(e.data)}).fail(function(e,t,a){u(a)})}(1,1)}),v(".remove-personal-data-handle").click(function(e){var s=v(this),r=s.parents(".remove-personal-data"),i=s.parents("tr"),t=r.data("request-id"),d=r.data("nonce"),c=r.data("erasers-count"),l=!1,u=!1,p=[];function m(){h(r,"remove-personal-data-failed"),x(i,"notice-error",f.removalError,[])}e.stopPropagation(),r.blur(),g(i),h(r,"remove-personal-data-processing"),function a(n,o){v.ajax({url:window.ajaxurl,data:{action:"wp-privacy-erase-personal-data",eraser:n,id:t,page:o,security:d},method:"post"}).done(function(e){var t=e.data;e.success?(t.items_removed&&(l=l||t.items_removed),t.items_retained&&(u=u||t.items_retained),t.messages&&(p=p.concat(t.messages)),t.done?n<c?setTimeout(a(n+1,1)):function(){var e=f.noDataFound,t="notice-success";h(r,"remove-personal-data-success"),!1===l?!1===u?e=f.noDataFound:(e=f.noneRemoved,t="notice-warning"):!1===u?e=f.foundAndRemoved:(e=f.someNotRemoved,t="notice-warning"),x(i,t,e,p),s.hide()}():setTimeout(a(n,o+1))):m()}).fail(function(){m()})}(1,1)}),v(document).on("click",function(e){var t,a,n,o=v(e.target);if(o.is("button.privacy-text-copy")&&((a=(t=o.parent().parent()).find("div.wp-suggested-text")).length||(a=t.find("div.policy-text")),a.length))try{window.getSelection().removeAllRanges(),n=document.createRange(),a.addClass("hide-privacy-policy-tutorial"),n.selectNodeContents(a[0]),window.getSelection().addRange(n),document.execCommand("copy"),a.removeClass("hide-privacy-policy-tutorial"),window.getSelection().removeAllRanges()}catch(e){}})});
|
||||
1171
wp-admin/js/revisions.js
Normal file
1171
wp-admin/js/revisions.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/revisions.min.js
vendored
Normal file
1
wp-admin/js/revisions.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
28
wp-admin/js/set-post-thumbnail.js
Normal file
28
wp-admin/js/set-post-thumbnail.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @output wp-admin/js/set-post-thumbnail.js
|
||||
*/
|
||||
|
||||
/* global setPostThumbnailL10n, ajaxurl, post_id, alert */
|
||||
/* exported WPSetAsThumbnail */
|
||||
|
||||
window.WPSetAsThumbnail = function( id, nonce ) {
|
||||
var $link = jQuery('a#wp-post-thumbnail-' + id);
|
||||
|
||||
$link.text( setPostThumbnailL10n.saving );
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'set-post-thumbnail', post_id: post_id, thumbnail_id: id, _ajax_nonce: nonce, cookie: encodeURIComponent( document.cookie )
|
||||
}, function(str){
|
||||
var win = window.dialogArguments || opener || parent || top;
|
||||
$link.text( setPostThumbnailL10n.setThumbnail );
|
||||
if ( str == '0' ) {
|
||||
alert( setPostThumbnailL10n.error );
|
||||
} else {
|
||||
jQuery('a.wp-post-thumbnail').show();
|
||||
$link.text( setPostThumbnailL10n.done );
|
||||
$link.fadeOut( 2000 );
|
||||
win.WPSetThumbnailID(id);
|
||||
win.WPSetThumbnailHTML(str);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
1
wp-admin/js/set-post-thumbnail.min.js
vendored
Normal file
1
wp-admin/js/set-post-thumbnail.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
window.WPSetAsThumbnail=function(e,t){var o=jQuery("a#wp-post-thumbnail-"+e);o.text(setPostThumbnailL10n.saving),jQuery.post(ajaxurl,{action:"set-post-thumbnail",post_id:post_id,thumbnail_id:e,_ajax_nonce:t,cookie:encodeURIComponent(document.cookie)},function(t){var n=window.dialogArguments||opener||parent||top;o.text(setPostThumbnailL10n.setThumbnail),"0"==t?alert(setPostThumbnailL10n.error):(jQuery("a.wp-post-thumbnail").show(),o.text(setPostThumbnailL10n.done),o.fadeOut(2e3),n.WPSetThumbnailID(e),n.WPSetThumbnailHTML(t))})};
|
||||
314
wp-admin/js/site-health.js
Normal file
314
wp-admin/js/site-health.js
Normal file
@@ -0,0 +1,314 @@
|
||||
/**
|
||||
* Interactions used by the Site Health modules in WordPress.
|
||||
*
|
||||
* @output wp-admin/js/site-health.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, ClipboardJS, SiteHealth, wp */
|
||||
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
|
||||
var __ = wp.i18n.__,
|
||||
_n = wp.i18n._n,
|
||||
sprintf = wp.i18n.sprintf;
|
||||
|
||||
var data;
|
||||
var clipboard = new ClipboardJS( '.site-health-copy-buttons .copy-button' );
|
||||
var isDebugTab = $( '.health-check-body.health-check-debug-tab' ).length;
|
||||
var pathsSizesSection = $( '#health-check-accordion-block-wp-paths-sizes' );
|
||||
|
||||
// Debug information copy section.
|
||||
clipboard.on( 'success', function( e ) {
|
||||
var $wrapper = $( e.trigger ).closest( 'div' );
|
||||
$( '.success', $wrapper ).addClass( 'visible' );
|
||||
|
||||
wp.a11y.speak( __( 'Site information has been added to your clipboard.' ) );
|
||||
} );
|
||||
|
||||
// Accordion handling in various areas.
|
||||
$( '.health-check-accordion' ).on( 'click', '.health-check-accordion-trigger', function() {
|
||||
var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) );
|
||||
|
||||
if ( isExpanded ) {
|
||||
$( this ).attr( 'aria-expanded', 'false' );
|
||||
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true );
|
||||
} else {
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false );
|
||||
}
|
||||
} );
|
||||
|
||||
// Site Health test handling.
|
||||
|
||||
$( '.site-health-view-passed' ).on( 'click', function() {
|
||||
var goodIssuesWrapper = $( '#health-check-issues-good' );
|
||||
|
||||
goodIssuesWrapper.toggleClass( 'hidden' );
|
||||
$( this ).attr( 'aria-expanded', ! goodIssuesWrapper.hasClass( 'hidden' ) );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Append a new issue to the issue list.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @param {Object} issue The issue data.
|
||||
*/
|
||||
function AppendIssue( issue ) {
|
||||
var template = wp.template( 'health-check-issue' ),
|
||||
issueWrapper = $( '#health-check-issues-' + issue.status ),
|
||||
heading,
|
||||
count;
|
||||
|
||||
SiteHealth.site_status.issues[ issue.status ]++;
|
||||
|
||||
count = SiteHealth.site_status.issues[ issue.status ];
|
||||
|
||||
if ( 'critical' === issue.status ) {
|
||||
heading = sprintf( _n( '%s critical issue', '%s critical issues', count ), '<span class="issue-count">' + count + '</span>' );
|
||||
} else if ( 'recommended' === issue.status ) {
|
||||
heading = sprintf( _n( '%s recommended improvement', '%s recommended improvements', count ), '<span class="issue-count">' + count + '</span>' );
|
||||
} else if ( 'good' === issue.status ) {
|
||||
heading = sprintf( _n( '%s item with no issues detected', '%s items with no issues detected', count ), '<span class="issue-count">' + count + '</span>' );
|
||||
}
|
||||
|
||||
if ( heading ) {
|
||||
$( '.site-health-issue-count-title', issueWrapper ).html( heading );
|
||||
}
|
||||
|
||||
$( '.issues', '#health-check-issues-' + issue.status ).append( template( issue ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update site health status indicator as asynchronous tests are run and returned.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
function RecalculateProgression() {
|
||||
var r, c, pct;
|
||||
var $progress = $( '.site-health-progress' );
|
||||
var $wrapper = $progress.closest( '.site-health-progress-wrapper' );
|
||||
var $progressLabel = $( '.site-health-progress-label', $wrapper );
|
||||
var $circle = $( '.site-health-progress svg #bar' );
|
||||
var totalTests = parseInt( SiteHealth.site_status.issues.good, 0 ) + parseInt( SiteHealth.site_status.issues.recommended, 0 ) + ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 );
|
||||
var failedTests = ( parseInt( SiteHealth.site_status.issues.recommended, 0 ) * 0.5 ) + ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 );
|
||||
var val = 100 - Math.ceil( ( failedTests / totalTests ) * 100 );
|
||||
|
||||
if ( 0 === totalTests ) {
|
||||
$progress.addClass( 'hidden' );
|
||||
return;
|
||||
}
|
||||
|
||||
$wrapper.removeClass( 'loading' );
|
||||
|
||||
r = $circle.attr( 'r' );
|
||||
c = Math.PI * ( r * 2 );
|
||||
|
||||
if ( 0 > val ) {
|
||||
val = 0;
|
||||
}
|
||||
if ( 100 < val ) {
|
||||
val = 100;
|
||||
}
|
||||
|
||||
pct = ( ( 100 - val ) / 100 ) * c;
|
||||
|
||||
$circle.css( { strokeDashoffset: pct } );
|
||||
|
||||
if ( 1 > parseInt( SiteHealth.site_status.issues.critical, 0 ) ) {
|
||||
$( '#health-check-issues-critical' ).addClass( 'hidden' );
|
||||
}
|
||||
|
||||
if ( 1 > parseInt( SiteHealth.site_status.issues.recommended, 0 ) ) {
|
||||
$( '#health-check-issues-recommended' ).addClass( 'hidden' );
|
||||
}
|
||||
|
||||
if ( 80 <= val && 0 === parseInt( SiteHealth.site_status.issues.critical, 0 ) ) {
|
||||
$wrapper.addClass( 'green' ).removeClass( 'orange' );
|
||||
|
||||
$progressLabel.text( __( 'Good' ) );
|
||||
wp.a11y.speak( __( 'All site health tests have finished running. Your site is looking good, and the results are now available on the page.' ) );
|
||||
} else {
|
||||
$wrapper.addClass( 'orange' ).removeClass( 'green' );
|
||||
|
||||
$progressLabel.text( __( 'Should be improved' ) );
|
||||
wp.a11y.speak( __( 'All site health tests have finished running. There are items that should be addressed, and the results are now available on the page.' ) );
|
||||
}
|
||||
|
||||
if ( ! isDebugTab ) {
|
||||
$.post(
|
||||
ajaxurl,
|
||||
{
|
||||
'action': 'health-check-site-status-result',
|
||||
'_wpnonce': SiteHealth.nonce.site_status_result,
|
||||
'counts': SiteHealth.site_status.issues
|
||||
}
|
||||
);
|
||||
|
||||
if ( 100 === val ) {
|
||||
$( '.site-status-all-clear' ).removeClass( 'hide' );
|
||||
$( '.site-status-has-issues' ).addClass( 'hide' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the next asynchronous test when we're ready to run it.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
function maybeRunNextAsyncTest() {
|
||||
var doCalculation = true;
|
||||
|
||||
if ( 1 <= SiteHealth.site_status.async.length ) {
|
||||
$.each( SiteHealth.site_status.async, function() {
|
||||
var data = {
|
||||
'action': 'health-check-' + this.test.replace( '_', '-' ),
|
||||
'_wpnonce': SiteHealth.nonce.site_status
|
||||
};
|
||||
|
||||
if ( this.completed ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
doCalculation = false;
|
||||
|
||||
this.completed = true;
|
||||
|
||||
$.post(
|
||||
ajaxurl,
|
||||
data,
|
||||
function( response ) {
|
||||
/** This filter is documented in wp-admin/includes/class-wp-site-health.php */
|
||||
AppendIssue( wp.hooks.applyFilters( 'site_status_test_result', response.data ) );
|
||||
maybeRunNextAsyncTest();
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
|
||||
if ( doCalculation ) {
|
||||
RecalculateProgression();
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'undefined' !== typeof SiteHealth && ! isDebugTab ) {
|
||||
if ( 0 === SiteHealth.site_status.direct.length && 0 === SiteHealth.site_status.async.length ) {
|
||||
RecalculateProgression();
|
||||
} else {
|
||||
SiteHealth.site_status.issues = {
|
||||
'good': 0,
|
||||
'recommended': 0,
|
||||
'critical': 0
|
||||
};
|
||||
}
|
||||
|
||||
if ( 0 < SiteHealth.site_status.direct.length ) {
|
||||
$.each( SiteHealth.site_status.direct, function() {
|
||||
AppendIssue( this );
|
||||
} );
|
||||
}
|
||||
|
||||
if ( 0 < SiteHealth.site_status.async.length ) {
|
||||
data = {
|
||||
'action': 'health-check-' + SiteHealth.site_status.async[0].test.replace( '_', '-' ),
|
||||
'_wpnonce': SiteHealth.nonce.site_status
|
||||
};
|
||||
|
||||
SiteHealth.site_status.async[0].completed = true;
|
||||
|
||||
$.post(
|
||||
ajaxurl,
|
||||
data,
|
||||
function( response ) {
|
||||
AppendIssue( response.data );
|
||||
maybeRunNextAsyncTest();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
RecalculateProgression();
|
||||
}
|
||||
}
|
||||
|
||||
function getDirectorySizes() {
|
||||
var data = {
|
||||
action: 'health-check-get-sizes',
|
||||
_wpnonce: SiteHealth.nonce.site_status_result
|
||||
};
|
||||
|
||||
var timestamp = ( new Date().getTime() );
|
||||
|
||||
// After 3 seconds announce that we're still waiting for directory sizes.
|
||||
var timeout = window.setTimeout( function() {
|
||||
wp.a11y.speak( __( 'Please wait...' ) );
|
||||
}, 3000 );
|
||||
|
||||
$.post( {
|
||||
type: 'POST',
|
||||
url: ajaxurl,
|
||||
data: data,
|
||||
dataType: 'json'
|
||||
} ).done( function( response ) {
|
||||
updateDirSizes( response.data || {} );
|
||||
} ).always( function() {
|
||||
var delay = ( new Date().getTime() ) - timestamp;
|
||||
|
||||
$( '.health-check-wp-paths-sizes.spinner' ).css( 'visibility', 'hidden' );
|
||||
RecalculateProgression();
|
||||
|
||||
if ( delay > 3000 ) {
|
||||
// We have announced that we're waiting.
|
||||
// Announce that we're ready after giving at least 3 seconds for the first announcement
|
||||
// to be read out, or the two may collide.
|
||||
if ( delay > 6000 ) {
|
||||
delay = 0;
|
||||
} else {
|
||||
delay = 6500 - delay;
|
||||
}
|
||||
|
||||
window.setTimeout( function() {
|
||||
wp.a11y.speak( __( 'All site health tests have finished running.' ) );
|
||||
}, delay );
|
||||
} else {
|
||||
// Cancel the announcement.
|
||||
window.clearTimeout( timeout );
|
||||
}
|
||||
|
||||
$( document ).trigger( 'site-health-info-dirsizes-done' );
|
||||
} );
|
||||
}
|
||||
|
||||
function updateDirSizes( data ) {
|
||||
var copyButton = $( 'button.button.copy-button' );
|
||||
var clipdoardText = copyButton.attr( 'data-clipboard-text' );
|
||||
|
||||
$.each( data, function( name, value ) {
|
||||
var text = value.debug || value.size;
|
||||
|
||||
if ( typeof text !== 'undefined' ) {
|
||||
clipdoardText = clipdoardText.replace( name + ': loading...', name + ': ' + text );
|
||||
}
|
||||
} );
|
||||
|
||||
copyButton.attr( 'data-clipboard-text', clipdoardText );
|
||||
|
||||
pathsSizesSection.find( 'td[class]' ).each( function( i, element ) {
|
||||
var td = $( element );
|
||||
var name = td.attr( 'class' );
|
||||
|
||||
if ( data.hasOwnProperty( name ) && data[ name ].size ) {
|
||||
td.text( data[ name ].size );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if ( isDebugTab ) {
|
||||
if ( pathsSizesSection.length ) {
|
||||
getDirectorySizes();
|
||||
} else {
|
||||
RecalculateProgression();
|
||||
}
|
||||
}
|
||||
} );
|
||||
1
wp-admin/js/site-health.min.js
vendored
Normal file
1
wp-admin/js/site-health.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
241
wp-admin/js/svg-painter.js
Normal file
241
wp-admin/js/svg-painter.js
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* Attempt to re-color SVG icons used in the admin menu or the toolbar
|
||||
*
|
||||
* @output wp-admin/js/svg-painter.js
|
||||
*/
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
wp.svgPainter = ( function( $, window, document, undefined ) {
|
||||
'use strict';
|
||||
var selector, base64, painter,
|
||||
colorscheme = {},
|
||||
elements = [];
|
||||
|
||||
$(document).ready( function() {
|
||||
// detection for browser SVG capability
|
||||
if ( document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ) ) {
|
||||
$( document.body ).removeClass( 'no-svg' ).addClass( 'svg' );
|
||||
wp.svgPainter.init();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Needed only for IE9
|
||||
*
|
||||
* Based on jquery.base64.js 0.0.3 - https://github.com/yckart/jquery.base64.js
|
||||
*
|
||||
* Based on: https://gist.github.com/Yaffle/1284012
|
||||
*
|
||||
* Copyright (c) 2012 Yannick Albert (http://yckart.com)
|
||||
* Licensed under the MIT license
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
base64 = ( function() {
|
||||
var c,
|
||||
b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||
a256 = '',
|
||||
r64 = [256],
|
||||
r256 = [256],
|
||||
i = 0;
|
||||
|
||||
function init() {
|
||||
while( i < 256 ) {
|
||||
c = String.fromCharCode(i);
|
||||
a256 += c;
|
||||
r256[i] = i;
|
||||
r64[i] = b64.indexOf(c);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
function code( s, discard, alpha, beta, w1, w2 ) {
|
||||
var tmp, length,
|
||||
buffer = 0,
|
||||
i = 0,
|
||||
result = '',
|
||||
bitsInBuffer = 0;
|
||||
|
||||
s = String(s);
|
||||
length = s.length;
|
||||
|
||||
while( i < length ) {
|
||||
c = s.charCodeAt(i);
|
||||
c = c < 256 ? alpha[c] : -1;
|
||||
|
||||
buffer = ( buffer << w1 ) + c;
|
||||
bitsInBuffer += w1;
|
||||
|
||||
while( bitsInBuffer >= w2 ) {
|
||||
bitsInBuffer -= w2;
|
||||
tmp = buffer >> bitsInBuffer;
|
||||
result += beta.charAt(tmp);
|
||||
buffer ^= tmp << bitsInBuffer;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if ( ! discard && bitsInBuffer > 0 ) {
|
||||
result += beta.charAt( buffer << ( w2 - bitsInBuffer ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function btoa( plain ) {
|
||||
if ( ! c ) {
|
||||
init();
|
||||
}
|
||||
|
||||
plain = code( plain, false, r256, b64, 8, 6 );
|
||||
return plain + '===='.slice( ( plain.length % 4 ) || 4 );
|
||||
}
|
||||
|
||||
function atob( coded ) {
|
||||
var i;
|
||||
|
||||
if ( ! c ) {
|
||||
init();
|
||||
}
|
||||
|
||||
coded = coded.replace( /[^A-Za-z0-9\+\/\=]/g, '' );
|
||||
coded = String(coded).split('=');
|
||||
i = coded.length;
|
||||
|
||||
do {
|
||||
--i;
|
||||
coded[i] = code( coded[i], true, r64, a256, 6, 8 );
|
||||
} while ( i > 0 );
|
||||
|
||||
coded = coded.join('');
|
||||
return coded;
|
||||
}
|
||||
|
||||
return {
|
||||
atob: atob,
|
||||
btoa: btoa
|
||||
};
|
||||
})();
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
painter = this;
|
||||
selector = $( '#adminmenu .wp-menu-image, #wpadminbar .ab-item' );
|
||||
|
||||
this.setColors();
|
||||
this.findElements();
|
||||
this.paint();
|
||||
},
|
||||
|
||||
setColors: function( colors ) {
|
||||
if ( typeof colors === 'undefined' && typeof window._wpColorScheme !== 'undefined' ) {
|
||||
colors = window._wpColorScheme;
|
||||
}
|
||||
|
||||
if ( colors && colors.icons && colors.icons.base && colors.icons.current && colors.icons.focus ) {
|
||||
colorscheme = colors.icons;
|
||||
}
|
||||
},
|
||||
|
||||
findElements: function() {
|
||||
selector.each( function() {
|
||||
var $this = $(this), bgImage = $this.css( 'background-image' );
|
||||
|
||||
if ( bgImage && bgImage.indexOf( 'data:image/svg+xml;base64' ) != -1 ) {
|
||||
elements.push( $this );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
paint: function() {
|
||||
// loop through all elements
|
||||
$.each( elements, function( index, $element ) {
|
||||
var $menuitem = $element.parent().parent();
|
||||
|
||||
if ( $menuitem.hasClass( 'current' ) || $menuitem.hasClass( 'wp-has-current-submenu' ) ) {
|
||||
// paint icon in 'current' color
|
||||
painter.paintElement( $element, 'current' );
|
||||
} else {
|
||||
// paint icon in base color
|
||||
painter.paintElement( $element, 'base' );
|
||||
|
||||
// set hover callbacks
|
||||
$menuitem.hover(
|
||||
function() {
|
||||
painter.paintElement( $element, 'focus' );
|
||||
},
|
||||
function() {
|
||||
// Match the delay from hoverIntent
|
||||
window.setTimeout( function() {
|
||||
painter.paintElement( $element, 'base' );
|
||||
}, 100 );
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
paintElement: function( $element, colorType ) {
|
||||
var xml, encoded, color;
|
||||
|
||||
if ( ! colorType || ! colorscheme.hasOwnProperty( colorType ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = colorscheme[ colorType ];
|
||||
|
||||
// only accept hex colors: #101 or #101010
|
||||
if ( ! color.match( /^(#[0-9a-f]{3}|#[0-9a-f]{6})$/i ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml = $element.data( 'wp-ui-svg-' + color );
|
||||
|
||||
if ( xml === 'none' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! xml ) {
|
||||
encoded = $element.css( 'background-image' ).match( /.+data:image\/svg\+xml;base64,([A-Za-z0-9\+\/\=]+)/ );
|
||||
|
||||
if ( ! encoded || ! encoded[1] ) {
|
||||
$element.data( 'wp-ui-svg-' + color, 'none' );
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if ( 'atob' in window ) {
|
||||
xml = window.atob( encoded[1] );
|
||||
} else {
|
||||
xml = base64.atob( encoded[1] );
|
||||
}
|
||||
} catch ( error ) {}
|
||||
|
||||
if ( xml ) {
|
||||
// replace `fill` attributes
|
||||
xml = xml.replace( /fill="(.+?)"/g, 'fill="' + color + '"');
|
||||
|
||||
// replace `style` attributes
|
||||
xml = xml.replace( /style="(.+?)"/g, 'style="fill:' + color + '"');
|
||||
|
||||
// replace `fill` properties in `<style>` tags
|
||||
xml = xml.replace( /fill:.*?;/g, 'fill: ' + color + ';');
|
||||
|
||||
if ( 'btoa' in window ) {
|
||||
xml = window.btoa( xml );
|
||||
} else {
|
||||
xml = base64.btoa( xml );
|
||||
}
|
||||
|
||||
$element.data( 'wp-ui-svg-' + color, xml );
|
||||
} else {
|
||||
$element.data( 'wp-ui-svg-' + color, 'none' );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$element.attr( 'style', 'background-image: url("data:image/svg+xml;base64,' + xml + '") !important;' );
|
||||
}
|
||||
};
|
||||
|
||||
})( jQuery, window, document );
|
||||
1
wp-admin/js/svg-painter.min.js
vendored
Normal file
1
wp-admin/js/svg-painter.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
window.wp=window.wp||{},wp.svgPainter=function(a,o,n){"use strict";var t,r,e,m,i,s,c,u,l,f={},g=[];function p(){for(;l<256;)m=String.fromCharCode(l),s+=m,u[l]=l,c[l]=i.indexOf(m),++l}function d(n,t,a,e,i,o){var r,s,c=0,u=0,l="",f=0;for(s=(n=String(n)).length;u<s;){for(c=(c<<i)+(m=(m=n.charCodeAt(u))<256?a[m]:-1),f+=i;o<=f;)r=c>>(f-=o),l+=e.charAt(r),c^=r<<f;++u}return!t&&0<f&&(l+=e.charAt(c<<o-f)),l}return a(n).ready(function(){n.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")&&(a(n.body).removeClass("no-svg").addClass("svg"),wp.svgPainter.init())}),i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s="",c=[256],u=[256],l=0,r={atob:function(n){var t;for(m||p(),n=n.replace(/[^A-Za-z0-9\+\/\=]/g,""),t=(n=String(n).split("=")).length;n[--t]=d(n[t],!0,c,s,6,8),0<t;);return n=n.join("")},btoa:function(n){return m||p(),(n=d(n,!1,u,i,8,6))+"====".slice(n.length%4||4)}},{init:function(){e=this,t=a("#adminmenu .wp-menu-image, #wpadminbar .ab-item"),this.setColors(),this.findElements(),this.paint()},setColors:function(n){void 0===n&&void 0!==o._wpColorScheme&&(n=o._wpColorScheme),n&&n.icons&&n.icons.base&&n.icons.current&&n.icons.focus&&(f=n.icons)},findElements:function(){t.each(function(){var n=a(this),t=n.css("background-image");t&&-1!=t.indexOf("data:image/svg+xml;base64")&&g.push(n)})},paint:function(){a.each(g,function(n,t){var a=t.parent().parent();a.hasClass("current")||a.hasClass("wp-has-current-submenu")?e.paintElement(t,"current"):(e.paintElement(t,"base"),a.hover(function(){e.paintElement(t,"focus")},function(){o.setTimeout(function(){e.paintElement(t,"base")},100)}))})},paintElement:function(n,t){var a,e,i;if(t&&f.hasOwnProperty(t)&&(i=f[t]).match(/^(#[0-9a-f]{3}|#[0-9a-f]{6})$/i)&&"none"!==(a=n.data("wp-ui-svg-"+i))){if(!a){if(!(e=n.css("background-image").match(/.+data:image\/svg\+xml;base64,([A-Za-z0-9\+\/\=]+)/))||!e[1])return void n.data("wp-ui-svg-"+i,"none");try{a="atob"in o?o.atob(e[1]):r.atob(e[1])}catch(n){}if(!a)return void n.data("wp-ui-svg-"+i,"none");a=(a=(a=a.replace(/fill="(.+?)"/g,'fill="'+i+'"')).replace(/style="(.+?)"/g,'style="fill:'+i+'"')).replace(/fill:.*?;/g,"fill: "+i+";"),a="btoa"in o?o.btoa(a):r.btoa(a),n.data("wp-ui-svg-"+i,a)}n.attr("style",'background-image: url("data:image/svg+xml;base64,'+a+'") !important;')}}}}(jQuery,window,document);
|
||||
430
wp-admin/js/tags-box.js
Normal file
430
wp-admin/js/tags-box.js
Normal file
@@ -0,0 +1,430 @@
|
||||
/**
|
||||
* @output wp-admin/js/tags-box.js
|
||||
*/
|
||||
|
||||
/* jshint curly: false, eqeqeq: false */
|
||||
/* global ajaxurl, tagBox, array_unique_noempty */
|
||||
|
||||
( function( $ ) {
|
||||
var tagDelimiter = ( window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter ) || ',';
|
||||
|
||||
/**
|
||||
* Filters unique items and returns a new array.
|
||||
*
|
||||
* Filters all items from an array into a new array containing only the unique
|
||||
* items. This also excludes whitespace or empty values.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @param {Array} array The array to filter through.
|
||||
*
|
||||
* @return {Array} A new array containing only the unique items.
|
||||
*/
|
||||
window.array_unique_noempty = function( array ) {
|
||||
var out = [];
|
||||
|
||||
// Trim the values and ensure they are unique.
|
||||
$.each( array, function( key, val ) {
|
||||
val = $.trim( val );
|
||||
|
||||
if ( val && $.inArray( val, out ) === -1 ) {
|
||||
out.push( val );
|
||||
}
|
||||
} );
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* The TagBox object.
|
||||
*
|
||||
* Contains functions to create and manage tags that can be associated with a
|
||||
* post.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @global
|
||||
*/
|
||||
window.tagBox = {
|
||||
/**
|
||||
* Cleans up tags by removing redundant characters.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} tags Comma separated tags that need to be cleaned up.
|
||||
*
|
||||
* @return {string} The cleaned up tags.
|
||||
*/
|
||||
clean : function( tags ) {
|
||||
if ( ',' !== tagDelimiter ) {
|
||||
tags = tags.replace( new RegExp( tagDelimiter, 'g' ), ',' );
|
||||
}
|
||||
|
||||
tags = tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');
|
||||
|
||||
if ( ',' !== tagDelimiter ) {
|
||||
tags = tags.replace( /,/g, tagDelimiter );
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses tags and makes them editable.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The tag element to retrieve the ID from.
|
||||
*
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
parseTags : function(el) {
|
||||
var id = el.id,
|
||||
num = id.split('-check-num-')[1],
|
||||
taxbox = $(el).closest('.tagsdiv'),
|
||||
thetags = taxbox.find('.the-tags'),
|
||||
current_tags = thetags.val().split( tagDelimiter ),
|
||||
new_tags = [];
|
||||
|
||||
delete current_tags[num];
|
||||
|
||||
// Sanitize the current tags and push them as if they're new tags.
|
||||
$.each( current_tags, function( key, val ) {
|
||||
val = $.trim( val );
|
||||
if ( val ) {
|
||||
new_tags.push( val );
|
||||
}
|
||||
});
|
||||
|
||||
thetags.val( this.clean( new_tags.join( tagDelimiter ) ) );
|
||||
|
||||
this.quickClicks( taxbox );
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates clickable links, buttons and fields for adding or editing tags.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The container HTML element.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
quickClicks : function( el ) {
|
||||
var thetags = $('.the-tags', el),
|
||||
tagchecklist = $('.tagchecklist', el),
|
||||
id = $(el).attr('id'),
|
||||
current_tags, disabled;
|
||||
|
||||
if ( ! thetags.length )
|
||||
return;
|
||||
|
||||
disabled = thetags.prop('disabled');
|
||||
|
||||
current_tags = thetags.val().split( tagDelimiter );
|
||||
tagchecklist.empty();
|
||||
|
||||
/**
|
||||
* Creates a delete button if tag editing is enabled, before adding it to the tag list.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} key The index of the current tag.
|
||||
* @param {string} val The value of the current tag.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$.each( current_tags, function( key, val ) {
|
||||
var listItem, xbutton;
|
||||
|
||||
val = $.trim( val );
|
||||
|
||||
if ( ! val )
|
||||
return;
|
||||
|
||||
// Create a new list item, and ensure the text is properly escaped.
|
||||
listItem = $( '<li />' ).text( val );
|
||||
|
||||
// If tags editing isn't disabled, create the X button.
|
||||
if ( ! disabled ) {
|
||||
/*
|
||||
* Build the X buttons, hide the X icon with aria-hidden and
|
||||
* use visually hidden text for screen readers.
|
||||
*/
|
||||
xbutton = $( '<button type="button" id="' + id + '-check-num-' + key + '" class="ntdelbutton">' +
|
||||
'<span class="remove-tag-icon" aria-hidden="true"></span>' +
|
||||
'<span class="screen-reader-text">' + window.tagsSuggestL10n.removeTerm + ' ' + listItem.html() + '</span>' +
|
||||
'</button>' );
|
||||
|
||||
/**
|
||||
* Handles the click and keypress event of the tag remove button.
|
||||
*
|
||||
* Makes sure the focus ends up in the tag input field when using
|
||||
* the keyboard to delete the tag.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @param {Event} e The click or keypress event to handle.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
xbutton.on( 'click keypress', function( e ) {
|
||||
// On click or when using the Enter/Spacebar keys.
|
||||
if ( 'click' === e.type || 13 === e.keyCode || 32 === e.keyCode ) {
|
||||
/*
|
||||
* When using the keyboard, move focus back to the
|
||||
* add new tag field. Note: when releasing the pressed
|
||||
* key this will fire the `keyup` event on the input.
|
||||
*/
|
||||
if ( 13 === e.keyCode || 32 === e.keyCode ) {
|
||||
$( this ).closest( '.tagsdiv' ).find( 'input.newtag' ).focus();
|
||||
}
|
||||
|
||||
tagBox.userAction = 'remove';
|
||||
tagBox.parseTags( this );
|
||||
}
|
||||
});
|
||||
|
||||
listItem.prepend( ' ' ).prepend( xbutton );
|
||||
}
|
||||
|
||||
// Append the list item to the tag list.
|
||||
tagchecklist.append( listItem );
|
||||
});
|
||||
|
||||
// The buttons list is built now, give feedback to screen reader users.
|
||||
tagBox.screenReadersMessage();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new tag.
|
||||
*
|
||||
* Also ensures that the quick links are properly generated.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The container HTML element.
|
||||
* @param {Object|boolean} a When this is an HTML element the text of that
|
||||
* element will be used for the new tag.
|
||||
* @param {number|boolean} f If this value is not passed then the tag input
|
||||
* field is focused.
|
||||
*
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
flushTags : function( el, a, f ) {
|
||||
var tagsval, newtags, text,
|
||||
tags = $( '.the-tags', el ),
|
||||
newtag = $( 'input.newtag', el );
|
||||
|
||||
a = a || false;
|
||||
|
||||
text = a ? $(a).text() : newtag.val();
|
||||
|
||||
/*
|
||||
* Return if there's no new tag or if the input field is empty.
|
||||
* Note: when using the keyboard to add tags, focus is moved back to
|
||||
* the input field and the `keyup` event attached on this field will
|
||||
* fire when releasing the pressed key. Checking also for the field
|
||||
* emptiness avoids to set the tags and call quickClicks() again.
|
||||
*/
|
||||
if ( 'undefined' == typeof( text ) || '' === text ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tagsval = tags.val();
|
||||
newtags = tagsval ? tagsval + tagDelimiter + text : text;
|
||||
|
||||
newtags = this.clean( newtags );
|
||||
newtags = array_unique_noempty( newtags.split( tagDelimiter ) ).join( tagDelimiter );
|
||||
tags.val( newtags );
|
||||
this.quickClicks( el );
|
||||
|
||||
if ( ! a )
|
||||
newtag.val('');
|
||||
if ( 'undefined' == typeof( f ) )
|
||||
newtag.focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the available tags and creates a tagcloud.
|
||||
*
|
||||
* Retrieves the available tags from the database and creates an interactive
|
||||
* tagcloud. Clicking a tag will add it.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} id The ID to extract the taxonomy from.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
get : function( id ) {
|
||||
var tax = id.substr( id.indexOf('-') + 1 );
|
||||
|
||||
/**
|
||||
* Puts a received tag cloud into a DOM element.
|
||||
*
|
||||
* The tag cloud HTML is generated on the server.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param {number|string} r The response message from the AJAX call.
|
||||
* @param {string} stat The status of the AJAX request.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$.post( ajaxurl, { 'action': 'get-tagcloud', 'tax': tax }, function( r, stat ) {
|
||||
if ( 0 === r || 'success' != stat ) {
|
||||
return;
|
||||
}
|
||||
|
||||
r = $( '<div id="tagcloud-' + tax + '" class="the-tagcloud">' + r + '</div>' );
|
||||
|
||||
/**
|
||||
* Adds a new tag when a tag in the tagcloud is clicked.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {boolean} Returns false to prevent the default action.
|
||||
*/
|
||||
$( 'a', r ).click( function() {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( '#' + tax ), this );
|
||||
return false;
|
||||
});
|
||||
|
||||
$( '#' + id ).after( r );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Track the user's last action.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*/
|
||||
userAction: '',
|
||||
|
||||
/**
|
||||
* Dispatches an audible message to screen readers.
|
||||
*
|
||||
* This will inform the user when a tag has been added or removed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
screenReadersMessage: function() {
|
||||
var message;
|
||||
|
||||
switch ( this.userAction ) {
|
||||
case 'remove':
|
||||
message = window.tagsSuggestL10n.termRemoved;
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
message = window.tagsSuggestL10n.termAdded;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
window.wp.a11y.speak( message, 'assertive' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the tags box by setting up the links, buttons. Sets up event
|
||||
* handling.
|
||||
*
|
||||
* This includes handling of pressing the enter key in the input field and the
|
||||
* retrieval of tag suggestions.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
init : function() {
|
||||
var ajaxtag = $('div.ajaxtag');
|
||||
|
||||
$('.tagsdiv').each( function() {
|
||||
tagBox.quickClicks( this );
|
||||
});
|
||||
|
||||
$( '.tagadd', ajaxtag ).click( function() {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles pressing enter on the new tag input field.
|
||||
*
|
||||
* Prevents submitting the post edit form. Uses `keypress` to take
|
||||
* into account Input Method Editor (IME) converters.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param {Event} event The keypress event that occurred.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$( 'input.newtag', ajaxtag ).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}).each( function( i, element ) {
|
||||
$( element ).wpTagsSuggest();
|
||||
});
|
||||
|
||||
/**
|
||||
* Before a post is saved the value currently in the new tag input field will be
|
||||
* added as a tag.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$('#post').submit(function(){
|
||||
$('div.tagsdiv').each( function() {
|
||||
tagBox.flushTags(this, false, 1);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles clicking on the tag cloud link.
|
||||
*
|
||||
* Makes sure the ARIA attributes are set correctly.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$('.tagcloud-link').click(function(){
|
||||
// On the first click, fetch the tag cloud and insert it in the DOM.
|
||||
tagBox.get( $( this ).attr( 'id' ) );
|
||||
// Update button state, remove previous click event and attach a new one to toggle the cloud.
|
||||
$( this )
|
||||
.attr( 'aria-expanded', 'true' )
|
||||
.unbind()
|
||||
.click( function() {
|
||||
$( this )
|
||||
.attr( 'aria-expanded', 'false' === $( this ).attr( 'aria-expanded' ) ? 'true' : 'false' )
|
||||
.siblings( '.the-tagcloud' ).toggle();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}( jQuery ));
|
||||
1
wp-admin/js/tags-box.min.js
vendored
Normal file
1
wp-admin/js/tags-box.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(r){var u=window.tagsSuggestL10n&&window.tagsSuggestL10n.tagDelimiter||",";window.array_unique_noempty=function(t){var a=[];return r.each(t,function(t,e){(e=r.trim(e))&&-1===r.inArray(e,a)&&a.push(e)}),a},window.tagBox={clean:function(t){return","!==u&&(t=t.replace(new RegExp(u,"g"),",")),t=t.replace(/\s*,\s*/g,",").replace(/,+/g,",").replace(/[,\s]+$/,"").replace(/^[,\s]+/,""),","!==u&&(t=t.replace(/,/g,u)),t},parseTags:function(t){var e=t.id.split("-check-num-")[1],a=r(t).closest(".tagsdiv"),s=a.find(".the-tags"),i=s.val().split(u),n=[];return delete i[e],r.each(i,function(t,e){(e=r.trim(e))&&n.push(e)}),s.val(this.clean(n.join(u))),this.quickClicks(a),!1},quickClicks:function(t){var e,i,a=r(".the-tags",t),n=r(".tagchecklist",t),c=r(t).attr("id");a.length&&(i=a.prop("disabled"),e=a.val().split(u),n.empty(),r.each(e,function(t,e){var a,s;(e=r.trim(e))&&(a=r("<li />").text(e),i||((s=r('<button type="button" id="'+c+"-check-num-"+t+'" class="ntdelbutton"><span class="remove-tag-icon" aria-hidden="true"></span><span class="screen-reader-text">'+window.tagsSuggestL10n.removeTerm+" "+a.html()+"</span></button>")).on("click keypress",function(t){"click"!==t.type&&13!==t.keyCode&&32!==t.keyCode||(13!==t.keyCode&&32!==t.keyCode||r(this).closest(".tagsdiv").find("input.newtag").focus(),tagBox.userAction="remove",tagBox.parseTags(this))}),a.prepend(" ").prepend(s)),n.append(a))}),tagBox.screenReadersMessage())},flushTags:function(t,e,a){var s,i,n,c=r(".the-tags",t),o=r("input.newtag",t);return void 0===(n=(e=e||!1)?r(e).text():o.val())||""===n||(i=(s=c.val())?s+u+n:n,i=this.clean(i),i=array_unique_noempty(i.split(u)).join(u),c.val(i),this.quickClicks(t),e||o.val(""),void 0===a&&o.focus()),!1},get:function(a){var s=a.substr(a.indexOf("-")+1);r.post(ajaxurl,{action:"get-tagcloud",tax:s},function(t,e){0!==t&&"success"==e&&(t=r('<div id="tagcloud-'+s+'" class="the-tagcloud">'+t+"</div>"),r("a",t).click(function(){return tagBox.userAction="add",tagBox.flushTags(r("#"+s),this),!1}),r("#"+a).after(t))})},userAction:"",screenReadersMessage:function(){var t;switch(this.userAction){case"remove":t=window.tagsSuggestL10n.termRemoved;break;case"add":t=window.tagsSuggestL10n.termAdded;break;default:return}window.wp.a11y.speak(t,"assertive")},init:function(){var t=r("div.ajaxtag");r(".tagsdiv").each(function(){tagBox.quickClicks(this)}),r(".tagadd",t).click(function(){tagBox.userAction="add",tagBox.flushTags(r(this).closest(".tagsdiv"))}),r("input.newtag",t).keypress(function(t){13==t.which&&(tagBox.userAction="add",tagBox.flushTags(r(this).closest(".tagsdiv")),t.preventDefault(),t.stopPropagation())}).each(function(t,e){r(e).wpTagsSuggest()}),r("#post").submit(function(){r("div.tagsdiv").each(function(){tagBox.flushTags(this,!1,1)})}),r(".tagcloud-link").click(function(){tagBox.get(r(this).attr("id")),r(this).attr("aria-expanded","true").unbind().click(function(){r(this).attr("aria-expanded","false"===r(this).attr("aria-expanded")?"true":"false").siblings(".the-tagcloud").toggle()})})}}}(jQuery);
|
||||
193
wp-admin/js/tags-suggest.js
Normal file
193
wp-admin/js/tags-suggest.js
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
|
||||
*
|
||||
* @output wp-admin/js/tags-suggest.js
|
||||
*/
|
||||
( function( $ ) {
|
||||
if ( typeof window.tagsSuggestL10n === 'undefined' || typeof window.uiAutocompleteL10n === 'undefined' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tempID = 0;
|
||||
var separator = window.tagsSuggestL10n.tagDelimiter || ',';
|
||||
|
||||
function split( val ) {
|
||||
return val.split( new RegExp( separator + '\\s*' ) );
|
||||
}
|
||||
|
||||
function getLast( term ) {
|
||||
return split( term ).pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add UI Autocomplete to an input or textarea element with presets for use
|
||||
* with non-hierarchical taxonomies.
|
||||
*
|
||||
* Example: `$( element ).wpTagsSuggest( options )`.
|
||||
*
|
||||
* The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or
|
||||
* can be in `options.taxonomy`.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param {object} options Options that are passed to UI Autocomplete. Can be used to override the default settings.
|
||||
* @returns {object} jQuery instance.
|
||||
*/
|
||||
$.fn.wpTagsSuggest = function( options ) {
|
||||
var cache;
|
||||
var last;
|
||||
var $element = $( this );
|
||||
|
||||
options = options || {};
|
||||
|
||||
var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag';
|
||||
|
||||
delete( options.taxonomy );
|
||||
|
||||
options = $.extend( {
|
||||
source: function( request, response ) {
|
||||
var term;
|
||||
|
||||
if ( last === request.term ) {
|
||||
response( cache );
|
||||
return;
|
||||
}
|
||||
|
||||
term = getLast( request.term );
|
||||
|
||||
$.get( window.ajaxurl, {
|
||||
action: 'ajax-tag-search',
|
||||
tax: taxonomy,
|
||||
q: term
|
||||
} ).always( function() {
|
||||
$element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes?
|
||||
} ).done( function( data ) {
|
||||
var tagName;
|
||||
var tags = [];
|
||||
|
||||
if ( data ) {
|
||||
data = data.split( '\n' );
|
||||
|
||||
for ( tagName in data ) {
|
||||
var id = ++tempID;
|
||||
|
||||
tags.push({
|
||||
id: id,
|
||||
name: data[tagName]
|
||||
});
|
||||
}
|
||||
|
||||
cache = tags;
|
||||
response( tags );
|
||||
} else {
|
||||
response( tags );
|
||||
}
|
||||
} );
|
||||
|
||||
last = request.term;
|
||||
},
|
||||
focus: function( event, ui ) {
|
||||
$element.attr( 'aria-activedescendant', 'wp-tags-autocomplete-' + ui.item.id );
|
||||
|
||||
// Don't empty the input field when using the arrow keys to
|
||||
// highlight items. See api.jqueryui.com/autocomplete/#event-focus
|
||||
event.preventDefault();
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
var tags = split( $element.val() );
|
||||
// Remove the last user input.
|
||||
tags.pop();
|
||||
// Append the new tag and an empty element to get one more separator at the end.
|
||||
tags.push( ui.item.name, '' );
|
||||
|
||||
$element.val( tags.join( separator + ' ' ) );
|
||||
|
||||
if ( $.ui.keyCode.TAB === event.keyCode ) {
|
||||
// Audible confirmation message when a tag has been selected.
|
||||
window.wp.a11y.speak( window.tagsSuggestL10n.termSelected, 'assertive' );
|
||||
event.preventDefault();
|
||||
} else if ( $.ui.keyCode.ENTER === event.keyCode ) {
|
||||
// If we're in the edit post Tags meta box, add the tag.
|
||||
if ( window.tagBox ) {
|
||||
window.tagBox.userAction = 'add';
|
||||
window.tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
}
|
||||
|
||||
// Do not close Quick Edit / Bulk Edit
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
open: function() {
|
||||
$element.attr( 'aria-expanded', 'true' );
|
||||
},
|
||||
close: function() {
|
||||
$element.attr( 'aria-expanded', 'false' );
|
||||
},
|
||||
minLength: 2,
|
||||
position: {
|
||||
my: 'left top+2',
|
||||
at: 'left bottom',
|
||||
collision: 'none'
|
||||
},
|
||||
messages: {
|
||||
noResults: window.uiAutocompleteL10n.noResults,
|
||||
results: function( number ) {
|
||||
if ( number > 1 ) {
|
||||
return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
|
||||
}
|
||||
|
||||
return window.uiAutocompleteL10n.oneResult;
|
||||
}
|
||||
}
|
||||
}, options );
|
||||
|
||||
$element.on( 'keydown', function() {
|
||||
$element.removeAttr( 'aria-activedescendant' );
|
||||
} )
|
||||
.autocomplete( options )
|
||||
.autocomplete( 'instance' )._renderItem = function( ul, item ) {
|
||||
return $( '<li role="option" id="wp-tags-autocomplete-' + item.id + '">' )
|
||||
.text( item.name )
|
||||
.appendTo( ul );
|
||||
};
|
||||
|
||||
$element.attr( {
|
||||
'role': 'combobox',
|
||||
'aria-autocomplete': 'list',
|
||||
'aria-expanded': 'false',
|
||||
'aria-owns': $element.autocomplete( 'widget' ).attr( 'id' )
|
||||
} )
|
||||
.on( 'focus', function() {
|
||||
var inputValue = split( $element.val() ).pop();
|
||||
|
||||
// Don't trigger a search if the field is empty.
|
||||
// Also, avoids screen readers announce `No search results`.
|
||||
if ( inputValue ) {
|
||||
$element.autocomplete( 'search' );
|
||||
}
|
||||
} )
|
||||
// Returns a jQuery object containing the menu element.
|
||||
.autocomplete( 'widget' )
|
||||
.addClass( 'wp-tags-autocomplete' )
|
||||
.attr( 'role', 'listbox' )
|
||||
.removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI.
|
||||
|
||||
// Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301.
|
||||
// The `menufocus` and `menublur` events are the same events used to add and remove
|
||||
// the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget.
|
||||
.on( 'menufocus', function( event, ui ) {
|
||||
ui.item.attr( 'aria-selected', 'true' );
|
||||
})
|
||||
.on( 'menublur', function() {
|
||||
// The `menublur` event returns an object where the item is `null`
|
||||
// so we need to find the active item with other means.
|
||||
$( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
}( jQuery ) );
|
||||
1
wp-admin/js/tags-suggest.min.js
vendored
Normal file
1
wp-admin/js/tags-suggest.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(r){if(void 0!==window.tagsSuggestL10n&&void 0!==window.uiAutocompleteL10n){var s=0,a=window.tagsSuggestL10n.tagDelimiter||",";r.fn.wpTagsSuggest=function(t){var i,o,n=r(this),u=(t=t||{}).taxonomy||n.attr("data-wp-taxonomy")||"post_tag";return delete t.taxonomy,t=r.extend({source:function(t,a){var e;o!==t.term?(e=function(t){return l(t).pop()}(t.term),r.get(window.ajaxurl,{action:"ajax-tag-search",tax:u,q:e}).always(function(){n.removeClass("ui-autocomplete-loading")}).done(function(t){var e,o=[];if(t){for(e in t=t.split("\n")){var n=++s;o.push({id:n,name:t[e]})}a(i=o)}else a(o)}),o=t.term):a(i)},focus:function(t,e){n.attr("aria-activedescendant","wp-tags-autocomplete-"+e.item.id),t.preventDefault()},select:function(t,e){var o=l(n.val());return o.pop(),o.push(e.item.name,""),n.val(o.join(a+" ")),r.ui.keyCode.TAB===t.keyCode?(window.wp.a11y.speak(window.tagsSuggestL10n.termSelected,"assertive"),t.preventDefault()):r.ui.keyCode.ENTER===t.keyCode&&(window.tagBox&&(window.tagBox.userAction="add",window.tagBox.flushTags(r(this).closest(".tagsdiv"))),t.preventDefault(),t.stopPropagation()),!1},open:function(){n.attr("aria-expanded","true")},close:function(){n.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2",at:"left bottom",collision:"none"},messages:{noResults:window.uiAutocompleteL10n.noResults,results:function(t){return 1<t?window.uiAutocompleteL10n.manyResults.replace("%d",t):window.uiAutocompleteL10n.oneResult}}},t),n.on("keydown",function(){n.removeAttr("aria-activedescendant")}).autocomplete(t).autocomplete("instance")._renderItem=function(t,e){return r('<li role="option" id="wp-tags-autocomplete-'+e.id+'">').text(e.name).appendTo(t)},n.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":n.autocomplete("widget").attr("id")}).on("focus",function(){l(n.val()).pop()&&n.autocomplete("search")}).autocomplete("widget").addClass("wp-tags-autocomplete").attr("role","listbox").removeAttr("tabindex").on("menufocus",function(t,e){e.item.attr("aria-selected","true")}).on("menublur",function(){r(this).find('[aria-selected="true"]').removeAttr("aria-selected")}),this}}function l(t){return t.split(new RegExp(a+"\\s*"))}}(jQuery);
|
||||
160
wp-admin/js/tags.js
Normal file
160
wp-admin/js/tags.js
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* Contains logic for deleting and adding tags.
|
||||
*
|
||||
* For deleting tags it makes a request to the server to delete the tag.
|
||||
* For adding tags it makes a request to the server to add the tag.
|
||||
*
|
||||
* @output wp-admin/js/tags.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, wpAjax, tagsl10n, showNotice, validateForm */
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
var addingTerm = false;
|
||||
|
||||
/**
|
||||
* Adds an event handler to the delete term link on the term overview page.
|
||||
*
|
||||
* Cancels default event handling and event bubbling.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns boolean Always returns false to cancel the default event handling.
|
||||
*/
|
||||
$( '#the-list' ).on( 'click', '.delete-tag', function() {
|
||||
var t = $(this), tr = t.parents('tr'), r = true, data;
|
||||
|
||||
if ( 'undefined' != showNotice )
|
||||
r = showNotice.warn();
|
||||
|
||||
if ( r ) {
|
||||
data = t.attr('href').replace(/[^?]*\?/, '').replace(/action=delete/, 'action=delete-tag');
|
||||
|
||||
/**
|
||||
* Makes a request to the server to delete the term that corresponds to the
|
||||
* delete term button.
|
||||
*
|
||||
* @param {string} r The response from the server.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$.post(ajaxurl, data, function(r){
|
||||
if ( '1' == r ) {
|
||||
$('#ajax-response').empty();
|
||||
tr.fadeOut('normal', function(){ tr.remove(); });
|
||||
|
||||
/**
|
||||
* Removes the term from the parent box and the tag cloud.
|
||||
*
|
||||
* `data.match(/tag_ID=(\d+)/)[1]` matches the term id from the data variable.
|
||||
* This term id is then used to select the relevant HTML elements:
|
||||
* The parent box and the tag cloud.
|
||||
*/
|
||||
$('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
|
||||
$('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();
|
||||
|
||||
} else if ( '-1' == r ) {
|
||||
$('#ajax-response').empty().append('<div class="error"><p>' + tagsl10n.noPerm + '</p></div>');
|
||||
tr.children().css('backgroundColor', '');
|
||||
|
||||
} else {
|
||||
$('#ajax-response').empty().append('<div class="error"><p>' + tagsl10n.broken + '</p></div>');
|
||||
tr.children().css('backgroundColor', '');
|
||||
}
|
||||
});
|
||||
|
||||
tr.children().css('backgroundColor', '#f33');
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds a deletion confirmation when removing a tag.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '#edittag' ).on( 'click', '.delete', function( e ) {
|
||||
if ( 'undefined' === typeof showNotice ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Confirms the deletion, a negative response means the deletion must not be executed.
|
||||
var response = showNotice.warn();
|
||||
if ( ! response ) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds an event handler to the form submit on the term overview page.
|
||||
*
|
||||
* Cancels default event handling and event bubbling.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns boolean Always returns false to cancel the default event handling.
|
||||
*/
|
||||
$('#submit').click(function(){
|
||||
var form = $(this).parents('form');
|
||||
|
||||
if ( ! validateForm( form ) )
|
||||
return false;
|
||||
|
||||
if ( addingTerm ) {
|
||||
// If we're adding a term, noop the button to avoid duplicate requests.
|
||||
return false;
|
||||
}
|
||||
|
||||
addingTerm = true;
|
||||
form.find( '.submit .spinner' ).addClass( 'is-active' );
|
||||
|
||||
/**
|
||||
* Does a request to the server to add a new term to the database
|
||||
*
|
||||
* @param {string} r The response from the server.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$.post(ajaxurl, $('#addtag').serialize(), function(r){
|
||||
var res, parent, term, indent, i;
|
||||
|
||||
addingTerm = false;
|
||||
form.find( '.submit .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
$('#ajax-response').empty();
|
||||
res = wpAjax.parseAjaxResponse( r, 'ajax-response' );
|
||||
if ( ! res || res.errors )
|
||||
return;
|
||||
|
||||
parent = form.find( 'select#parent' ).val();
|
||||
|
||||
if ( parent > 0 && $('#tag-' + parent ).length > 0 ) // If the parent exists on this page, insert it below. Else insert it at the top of the list.
|
||||
$( '.tags #tag-' + parent ).after( res.responses[0].supplemental.noparents ); // As the parent exists, Insert the version with - - - prefixed
|
||||
else
|
||||
$( '.tags' ).prepend( res.responses[0].supplemental.parents ); // As the parent is not visible, Insert the version with Parent - Child - ThisTerm
|
||||
|
||||
$('.tags .no-items').remove();
|
||||
|
||||
if ( form.find('select#parent') ) {
|
||||
// Parents field exists, Add new term to the list.
|
||||
term = res.responses[1].supplemental;
|
||||
|
||||
// Create an indent for the Parent field
|
||||
indent = '';
|
||||
for ( i = 0; i < res.responses[1].position; i++ )
|
||||
indent += ' ';
|
||||
|
||||
form.find( 'select#parent option:selected' ).after( '<option value="' + term.term_id + '">' + indent + term.name + '</option>' );
|
||||
}
|
||||
|
||||
$('input[type="text"]:visible, textarea:visible', form).val('');
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
1
wp-admin/js/tags.min.js
vendored
Normal file
1
wp-admin/js/tags.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(i){var p=!1;i("#the-list").on("click",".delete-tag",function(){var t,e=i(this),n=e.parents("tr"),a=!0;return"undefined"!=showNotice&&(a=showNotice.warn()),a&&(t=e.attr("href").replace(/[^?]*\?/,"").replace(/action=delete/,"action=delete-tag"),i.post(ajaxurl,t,function(e){"1"==e?(i("#ajax-response").empty(),n.fadeOut("normal",function(){n.remove()}),i('select#parent option[value="'+t.match(/tag_ID=(\d+)/)[1]+'"]').remove(),i("a.tag-link-"+t.match(/tag_ID=(\d+)/)[1]).remove()):("-1"==e?i("#ajax-response").empty().append('<div class="error"><p>'+tagsl10n.noPerm+"</p></div>"):i("#ajax-response").empty().append('<div class="error"><p>'+tagsl10n.broken+"</p></div>"),n.children().css("backgroundColor",""))}),n.children().css("backgroundColor","#f33")),!1}),i("#edittag").on("click",".delete",function(e){if("undefined"==typeof showNotice)return!0;showNotice.warn()||e.preventDefault()}),i("#submit").click(function(){var o=i(this).parents("form");return validateForm(o)&&(p||(p=!0,o.find(".submit .spinner").addClass("is-active"),i.post(ajaxurl,i("#addtag").serialize(),function(e){var t,n,a,s,r;if(p=!1,o.find(".submit .spinner").removeClass("is-active"),i("#ajax-response").empty(),(t=wpAjax.parseAjaxResponse(e,"ajax-response"))&&!t.errors){if(0<(n=o.find("select#parent").val())&&0<i("#tag-"+n).length?i(".tags #tag-"+n).after(t.responses[0].supplemental.noparents):i(".tags").prepend(t.responses[0].supplemental.parents),i(".tags .no-items").remove(),o.find("select#parent")){for(a=t.responses[1].supplemental,s="",r=0;r<t.responses[1].position;r++)s+=" ";o.find("select#parent option:selected").after('<option value="'+a.term_id+'">'+s+a.name+"</option>")}i('input[type="text"]:visible, textarea:visible',o).val("")}}))),!1})});
|
||||
1006
wp-admin/js/theme-plugin-editor.js
Normal file
1006
wp-admin/js/theme-plugin-editor.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/theme-plugin-editor.min.js
vendored
Normal file
1
wp-admin/js/theme-plugin-editor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2070
wp-admin/js/theme.js
Normal file
2070
wp-admin/js/theme.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/theme.min.js
vendored
Normal file
1
wp-admin/js/theme.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2465
wp-admin/js/updates.js
Normal file
2465
wp-admin/js/updates.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/updates.min.js
vendored
Normal file
1
wp-admin/js/updates.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
409
wp-admin/js/user-profile.js
Normal file
409
wp-admin/js/user-profile.js
Normal file
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
* @output wp-admin/js/user-profile.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, pwsL10n, userProfileL10n */
|
||||
(function($) {
|
||||
var updateLock = false,
|
||||
|
||||
$pass1Row,
|
||||
$pass1,
|
||||
$pass2,
|
||||
$weakRow,
|
||||
$weakCheckbox,
|
||||
$toggleButton,
|
||||
$submitButtons,
|
||||
$submitButton,
|
||||
currentPass;
|
||||
|
||||
function generatePassword() {
|
||||
if ( typeof zxcvbn !== 'function' ) {
|
||||
setTimeout( generatePassword, 50 );
|
||||
return;
|
||||
} else if ( ! $pass1.val() ) {
|
||||
// zxcvbn loaded before user entered password.
|
||||
$pass1.val( $pass1.data( 'pw' ) );
|
||||
$pass1.trigger( 'pwupdate' );
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
}
|
||||
else {
|
||||
// zxcvbn loaded after the user entered password, check strength.
|
||||
check_pass_strength();
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
}
|
||||
|
||||
if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
|
||||
$pass1.attr( 'type', 'text' );
|
||||
} else {
|
||||
$toggleButton.trigger( 'click' );
|
||||
}
|
||||
|
||||
// Once zxcvbn loads, passwords strength is known.
|
||||
$( '#pw-weak-text-label' ).html( userProfileL10n.warnWeak );
|
||||
}
|
||||
|
||||
function bindPass1() {
|
||||
currentPass = $pass1.val();
|
||||
|
||||
if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
|
||||
generatePassword();
|
||||
}
|
||||
|
||||
$pass1.on( 'input' + ' pwupdate', function () {
|
||||
if ( $pass1.val() === currentPass ) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentPass = $pass1.val();
|
||||
|
||||
$pass1.removeClass( 'short bad good strong' );
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
} );
|
||||
}
|
||||
|
||||
function resetToggle( show ) {
|
||||
$toggleButton
|
||||
.attr({
|
||||
'aria-label': show ? userProfileL10n.ariaShow : userProfileL10n.ariaHide
|
||||
})
|
||||
.find( '.text' )
|
||||
.text( show ? userProfileL10n.show : userProfileL10n.hide )
|
||||
.end()
|
||||
.find( '.dashicons' )
|
||||
.removeClass( show ? 'dashicons-hidden' : 'dashicons-visibility' )
|
||||
.addClass( show ? 'dashicons-visibility' : 'dashicons-hidden' );
|
||||
}
|
||||
|
||||
function bindToggleButton() {
|
||||
$toggleButton = $pass1Row.find('.wp-hide-pw');
|
||||
$toggleButton.show().on( 'click', function () {
|
||||
if ( 'password' === $pass1.attr( 'type' ) ) {
|
||||
$pass1.attr( 'type', 'text' );
|
||||
resetToggle( false );
|
||||
} else {
|
||||
$pass1.attr( 'type', 'password' );
|
||||
resetToggle( true );
|
||||
}
|
||||
|
||||
$pass1.focus();
|
||||
|
||||
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
|
||||
$pass1[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindPasswordForm() {
|
||||
var $passwordWrapper,
|
||||
$generateButton,
|
||||
$cancelButton;
|
||||
|
||||
$pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' );
|
||||
|
||||
// Hide the confirm password field when JavaScript support is enabled.
|
||||
$('.user-pass2-wrap').hide();
|
||||
|
||||
$submitButton = $( '#submit, #wp-submit' ).on( 'click', function () {
|
||||
updateLock = false;
|
||||
});
|
||||
|
||||
$submitButtons = $submitButton.add( ' #createusersub' );
|
||||
|
||||
$weakRow = $( '.pw-weak' );
|
||||
$weakCheckbox = $weakRow.find( '.pw-checkbox' );
|
||||
$weakCheckbox.change( function() {
|
||||
$submitButtons.prop( 'disabled', ! $weakCheckbox.prop( 'checked' ) );
|
||||
} );
|
||||
|
||||
$pass1 = $('#pass1');
|
||||
if ( $pass1.length ) {
|
||||
bindPass1();
|
||||
} else {
|
||||
// Password field for the login form.
|
||||
$pass1 = $( '#user_pass' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a LastPass mismatch issue, LastPass only changes pass2.
|
||||
*
|
||||
* This fixes the issue by copying any changes from the hidden
|
||||
* pass2 field to the pass1 field, then running check_pass_strength.
|
||||
*/
|
||||
$pass2 = $( '#pass2' ).on( 'input', function () {
|
||||
if ( $pass2.val().length > 0 ) {
|
||||
$pass1.val( $pass2.val() );
|
||||
$pass2.val('');
|
||||
currentPass = '';
|
||||
$pass1.trigger( 'pwupdate' );
|
||||
}
|
||||
} );
|
||||
|
||||
// Disable hidden inputs to prevent autofill and submission.
|
||||
if ( $pass1.is( ':hidden' ) ) {
|
||||
$pass1.prop( 'disabled', true );
|
||||
$pass2.prop( 'disabled', true );
|
||||
}
|
||||
|
||||
$passwordWrapper = $pass1Row.find( '.wp-pwd' );
|
||||
$generateButton = $pass1Row.find( 'button.wp-generate-pw' );
|
||||
|
||||
bindToggleButton();
|
||||
|
||||
if ( $generateButton.length ) {
|
||||
$passwordWrapper.hide();
|
||||
}
|
||||
|
||||
$generateButton.show();
|
||||
$generateButton.on( 'click', function () {
|
||||
updateLock = true;
|
||||
|
||||
$generateButton.hide();
|
||||
$passwordWrapper.show();
|
||||
|
||||
// Enable the inputs when showing.
|
||||
$pass1.attr( 'disabled', false );
|
||||
$pass2.attr( 'disabled', false );
|
||||
|
||||
if ( $pass1.val().length === 0 ) {
|
||||
generatePassword();
|
||||
}
|
||||
} );
|
||||
|
||||
$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
|
||||
$cancelButton.on( 'click', function () {
|
||||
updateLock = false;
|
||||
|
||||
// Clear any entered password.
|
||||
$pass1.val( '' );
|
||||
|
||||
// Generate a new password.
|
||||
wp.ajax.post( 'generate-password' )
|
||||
.done( function( data ) {
|
||||
$pass1.data( 'pw', data );
|
||||
} );
|
||||
|
||||
$generateButton.show().focus();
|
||||
$passwordWrapper.hide();
|
||||
|
||||
$weakRow.hide( 0, function () {
|
||||
$weakCheckbox.removeProp( 'checked' );
|
||||
} );
|
||||
|
||||
// Disable the inputs when hiding to prevent autofill and submission.
|
||||
$pass1.prop( 'disabled', true );
|
||||
$pass2.prop( 'disabled', true );
|
||||
|
||||
resetToggle( false );
|
||||
|
||||
if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) {
|
||||
// Clear password field to prevent update
|
||||
$pass1.val( '' ).trigger( 'pwupdate' );
|
||||
$submitButtons.prop( 'disabled', false );
|
||||
}
|
||||
} );
|
||||
|
||||
$pass1Row.closest( 'form' ).on( 'submit', function () {
|
||||
updateLock = false;
|
||||
|
||||
$pass1.prop( 'disabled', false );
|
||||
$pass2.prop( 'disabled', false );
|
||||
$pass2.val( $pass1.val() );
|
||||
});
|
||||
}
|
||||
|
||||
function check_pass_strength() {
|
||||
var pass1 = $('#pass1').val(), strength;
|
||||
|
||||
$('#pass-strength-result').removeClass('short bad good strong empty');
|
||||
if ( ! pass1 ) {
|
||||
$( '#pass-strength-result' ).addClass( 'empty' ).html( ' ' );
|
||||
return;
|
||||
}
|
||||
|
||||
strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputBlacklist(), pass1 );
|
||||
|
||||
switch ( strength ) {
|
||||
case -1:
|
||||
$( '#pass-strength-result' ).addClass( 'bad' ).html( pwsL10n.unknown );
|
||||
break;
|
||||
case 2:
|
||||
$('#pass-strength-result').addClass('bad').html( pwsL10n.bad );
|
||||
break;
|
||||
case 3:
|
||||
$('#pass-strength-result').addClass('good').html( pwsL10n.good );
|
||||
break;
|
||||
case 4:
|
||||
$('#pass-strength-result').addClass('strong').html( pwsL10n.strong );
|
||||
break;
|
||||
case 5:
|
||||
$('#pass-strength-result').addClass('short').html( pwsL10n.mismatch );
|
||||
break;
|
||||
default:
|
||||
$('#pass-strength-result').addClass('short').html( pwsL10n['short'] );
|
||||
}
|
||||
}
|
||||
|
||||
function showOrHideWeakPasswordCheckbox() {
|
||||
var passStrength = $('#pass-strength-result')[0];
|
||||
|
||||
if ( passStrength.className ) {
|
||||
$pass1.addClass( passStrength.className );
|
||||
if ( $( passStrength ).is( '.short, .bad' ) ) {
|
||||
if ( ! $weakCheckbox.prop( 'checked' ) ) {
|
||||
$submitButtons.prop( 'disabled', true );
|
||||
}
|
||||
$weakRow.show();
|
||||
} else {
|
||||
if ( $( passStrength ).is( '.empty' ) ) {
|
||||
$submitButtons.prop( 'disabled', true );
|
||||
$weakCheckbox.prop( 'checked', false );
|
||||
} else {
|
||||
$submitButtons.prop( 'disabled', false );
|
||||
}
|
||||
$weakRow.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready( function() {
|
||||
var $colorpicker, $stylesheet, user_id, current_user_id,
|
||||
select = $( '#display_name' ),
|
||||
current_name = select.val(),
|
||||
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
|
||||
|
||||
$( '#pass1' ).val( '' ).on( 'input' + ' pwupdate', check_pass_strength );
|
||||
$('#pass-strength-result').show();
|
||||
$('.color-palette').click( function() {
|
||||
$(this).siblings('input[name="admin_color"]').prop('checked', true);
|
||||
});
|
||||
|
||||
if ( select.length ) {
|
||||
$('#first_name, #last_name, #nickname').bind( 'blur.user_profile', function() {
|
||||
var dub = [],
|
||||
inputs = {
|
||||
display_nickname : $('#nickname').val() || '',
|
||||
display_username : $('#user_login').val() || '',
|
||||
display_firstname : $('#first_name').val() || '',
|
||||
display_lastname : $('#last_name').val() || ''
|
||||
};
|
||||
|
||||
if ( inputs.display_firstname && inputs.display_lastname ) {
|
||||
inputs.display_firstlast = inputs.display_firstname + ' ' + inputs.display_lastname;
|
||||
inputs.display_lastfirst = inputs.display_lastname + ' ' + inputs.display_firstname;
|
||||
}
|
||||
|
||||
$.each( $('option', select), function( i, el ){
|
||||
dub.push( el.value );
|
||||
});
|
||||
|
||||
$.each(inputs, function( id, value ) {
|
||||
if ( ! value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var val = value.replace(/<\/?[a-z][^>]*>/gi, '');
|
||||
|
||||
if ( inputs[id].length && $.inArray( val, dub ) === -1 ) {
|
||||
dub.push(val);
|
||||
$('<option />', {
|
||||
'text': val
|
||||
}).appendTo( select );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Replaces "Howdy, *" in the admin toolbar whenever the display name dropdown is updated for one's own profile.
|
||||
*/
|
||||
select.on( 'change', function() {
|
||||
if ( user_id !== current_user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var display_name = $.trim( this.value ) || current_name;
|
||||
|
||||
greeting.text( display_name );
|
||||
} );
|
||||
}
|
||||
|
||||
$colorpicker = $( '#color-picker' );
|
||||
$stylesheet = $( '#colors-css' );
|
||||
user_id = $( 'input#user_id' ).val();
|
||||
current_user_id = $( 'input[name="checkuser_id"]' ).val();
|
||||
|
||||
$colorpicker.on( 'click.colorpicker', '.color-option', function() {
|
||||
var colors,
|
||||
$this = $(this);
|
||||
|
||||
if ( $this.hasClass( 'selected' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this.siblings( '.selected' ).removeClass( 'selected' );
|
||||
$this.addClass( 'selected' ).find( 'input[type="radio"]' ).prop( 'checked', true );
|
||||
|
||||
// Set color scheme
|
||||
if ( user_id === current_user_id ) {
|
||||
// Load the colors stylesheet.
|
||||
// The default color scheme won't have one, so we'll need to create an element.
|
||||
if ( 0 === $stylesheet.length ) {
|
||||
$stylesheet = $( '<link rel="stylesheet" />' ).appendTo( 'head' );
|
||||
}
|
||||
$stylesheet.attr( 'href', $this.children( '.css_url' ).val() );
|
||||
|
||||
// repaint icons
|
||||
if ( typeof wp !== 'undefined' && wp.svgPainter ) {
|
||||
try {
|
||||
colors = $.parseJSON( $this.children( '.icon_colors' ).val() );
|
||||
} catch ( error ) {}
|
||||
|
||||
if ( colors ) {
|
||||
wp.svgPainter.setColors( colors );
|
||||
wp.svgPainter.paint();
|
||||
}
|
||||
}
|
||||
|
||||
// update user option
|
||||
$.post( ajaxurl, {
|
||||
action: 'save-user-color-scheme',
|
||||
color_scheme: $this.children( 'input[name="admin_color"]' ).val(),
|
||||
nonce: $('#color-nonce').val()
|
||||
}).done( function( response ) {
|
||||
if ( response.success ) {
|
||||
$( 'body' ).removeClass( response.data.previousScheme ).addClass( response.data.currentScheme );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
bindPasswordForm();
|
||||
});
|
||||
|
||||
$( '#destroy-sessions' ).on( 'click', function( e ) {
|
||||
var $this = $(this);
|
||||
|
||||
wp.ajax.post( 'destroy-sessions', {
|
||||
nonce: $( '#_wpnonce' ).val(),
|
||||
user_id: $( '#user_id' ).val()
|
||||
}).done( function( response ) {
|
||||
$this.prop( 'disabled', true );
|
||||
$this.siblings( '.notice' ).remove();
|
||||
$this.before( '<div class="notice notice-success inline"><p>' + response.message + '</p></div>' );
|
||||
}).fail( function( response ) {
|
||||
$this.siblings( '.notice' ).remove();
|
||||
$this.before( '<div class="notice notice-error inline"><p>' + response.message + '</p></div>' );
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.generatePassword = generatePassword;
|
||||
|
||||
/* Warn the user if password was generated but not saved */
|
||||
$( window ).on( 'beforeunload', function () {
|
||||
if ( true === updateLock ) {
|
||||
return userProfileL10n.warn;
|
||||
}
|
||||
} );
|
||||
|
||||
})(jQuery);
|
||||
1
wp-admin/js/user-profile.min.js
vendored
Normal file
1
wp-admin/js/user-profile.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
64
wp-admin/js/user-suggest.js
Normal file
64
wp-admin/js/user-suggest.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Suggests users in a multisite environment.
|
||||
*
|
||||
* For input fields where the admin can select a user based on email or
|
||||
* username, this script shows an autocompletion menu for these inputs. Should
|
||||
* only be used in a multisite environment. Only users in the currently active
|
||||
* site are shown.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @output wp-admin/js/user-suggest.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, current_site_id, isRtl */
|
||||
|
||||
(function( $ ) {
|
||||
var id = ( typeof current_site_id !== 'undefined' ) ? '&site_id=' + current_site_id : '';
|
||||
$(document).ready( function() {
|
||||
var position = { offset: '0, -1' };
|
||||
if ( typeof isRtl !== 'undefined' && isRtl ) {
|
||||
position.my = 'right top';
|
||||
position.at = 'right bottom';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an autocomplete function to input fields marked with the class
|
||||
* 'wp-suggest-user'.
|
||||
*
|
||||
* A minimum of two characters is required to trigger the suggestions. The
|
||||
* autocompletion menu is shown at the left bottom of the input field. On
|
||||
* RTL installations, it is shown at the right top. Adds the class 'open' to
|
||||
* the input field when the autocompletion menu is shown.
|
||||
*
|
||||
* Does a backend call to retrieve the users.
|
||||
*
|
||||
* Optional data-attributes:
|
||||
* - data-autocomplete-type (add, search)
|
||||
* The action that is going to be performed: search for existing users
|
||||
* or add a new one. Default: add
|
||||
* - data-autocomplete-field (user_login, user_email)
|
||||
* The field that is returned as the value for the suggestion.
|
||||
* Default: user_login
|
||||
*
|
||||
* @see wp-admin/includes/admin-actions.php:wp_ajax_autocomplete_user()
|
||||
*/
|
||||
$( '.wp-suggest-user' ).each( function(){
|
||||
var $this = $( this ),
|
||||
autocompleteType = ( typeof $this.data( 'autocompleteType' ) !== 'undefined' ) ? $this.data( 'autocompleteType' ) : 'add',
|
||||
autocompleteField = ( typeof $this.data( 'autocompleteField' ) !== 'undefined' ) ? $this.data( 'autocompleteField' ) : 'user_login';
|
||||
|
||||
$this.autocomplete({
|
||||
source: ajaxurl + '?action=autocomplete-user&autocomplete_type=' + autocompleteType + '&autocomplete_field=' + autocompleteField + id,
|
||||
delay: 500,
|
||||
minLength: 2,
|
||||
position: position,
|
||||
open: function() {
|
||||
$( this ).addClass( 'open' );
|
||||
},
|
||||
close: function() {
|
||||
$( this ).removeClass( 'open' );
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})( jQuery );
|
||||
1
wp-admin/js/user-suggest.min.js
vendored
Normal file
1
wp-admin/js/user-suggest.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(i){var n="undefined"!=typeof current_site_id?"&site_id="+current_site_id:"";i(document).ready(function(){var a={offset:"0, -1"};"undefined"!=typeof isRtl&&isRtl&&(a.my="right top",a.at="right bottom"),i(".wp-suggest-user").each(function(){var e=i(this),t=void 0!==e.data("autocompleteType")?e.data("autocompleteType"):"add",o=void 0!==e.data("autocompleteField")?e.data("autocompleteField"):"user_login";e.autocomplete({source:ajaxurl+"?action=autocomplete-user&autocomplete_type="+t+"&autocomplete_field="+o+n,delay:500,minLength:2,position:a,open:function(){i(this).addClass("open")},close:function(){i(this).removeClass("open")}})})})}(jQuery);
|
||||
761
wp-admin/js/widgets.js
Normal file
761
wp-admin/js/widgets.js
Normal file
@@ -0,0 +1,761 @@
|
||||
/**
|
||||
* @output wp-admin/js/widgets.js
|
||||
*/
|
||||
|
||||
/* global ajaxurl, isRtl, wpWidgets */
|
||||
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
window.wpWidgets = {
|
||||
/**
|
||||
* A closed Sidebar that gets a Widget dragged over it.
|
||||
*
|
||||
* @var {element|null}
|
||||
*/
|
||||
hoveredSidebar: null,
|
||||
|
||||
/**
|
||||
* Translations.
|
||||
*
|
||||
* Exported from PHP in wp_default_scripts().
|
||||
*
|
||||
* @var {object}
|
||||
*/
|
||||
l10n: {
|
||||
save: '{save}',
|
||||
saved: '{saved}',
|
||||
saveAlert: '{saveAlert}',
|
||||
widgetAdded: '{widgetAdded}'
|
||||
},
|
||||
|
||||
/**
|
||||
* Lookup of which widgets have had change events triggered.
|
||||
*
|
||||
* @var {object}
|
||||
*/
|
||||
dirtyWidgets: {},
|
||||
|
||||
init : function() {
|
||||
var rem, the_id,
|
||||
self = this,
|
||||
chooser = $('.widgets-chooser'),
|
||||
selectSidebar = chooser.find('.widgets-chooser-sidebars'),
|
||||
sidebars = $('div.widgets-sortables'),
|
||||
isRTL = !! ( 'undefined' !== typeof isRtl && isRtl );
|
||||
|
||||
// Handle the widgets containers in the right column.
|
||||
$( '#widgets-right .sidebar-name' )
|
||||
/*
|
||||
* Toggle the widgets containers when clicked and update the toggle
|
||||
* button `aria-expanded` attribute value.
|
||||
*/
|
||||
.click( function() {
|
||||
var $this = $( this ),
|
||||
$wrap = $this.closest( '.widgets-holder-wrap '),
|
||||
$toggle = $this.find( '.handlediv' );
|
||||
|
||||
if ( $wrap.hasClass( 'closed' ) ) {
|
||||
$wrap.removeClass( 'closed' );
|
||||
$toggle.attr( 'aria-expanded', 'true' );
|
||||
// Refresh the jQuery UI sortable items.
|
||||
$this.parent().sortable( 'refresh' );
|
||||
} else {
|
||||
$wrap.addClass( 'closed' );
|
||||
$toggle.attr( 'aria-expanded', 'false' );
|
||||
}
|
||||
|
||||
// Update the admin menu "sticky" state.
|
||||
$document.triggerHandler( 'wp-pin-menu' );
|
||||
})
|
||||
/*
|
||||
* Set the initial `aria-expanded` attribute value on the widgets
|
||||
* containers toggle button. The first one is expanded by default.
|
||||
*/
|
||||
.find( '.handlediv' ).each( function( index ) {
|
||||
if ( 0 === index ) {
|
||||
// jQuery equivalent of `continue` within an `each()` loop.
|
||||
return;
|
||||
}
|
||||
|
||||
$( this ).attr( 'aria-expanded', 'false' );
|
||||
});
|
||||
|
||||
// Show AYS dialog when there are unsaved widget changes.
|
||||
$( window ).on( 'beforeunload.widgets', function( event ) {
|
||||
var dirtyWidgetIds = [], unsavedWidgetsElements;
|
||||
$.each( self.dirtyWidgets, function( widgetId, dirty ) {
|
||||
if ( dirty ) {
|
||||
dirtyWidgetIds.push( widgetId );
|
||||
}
|
||||
});
|
||||
if ( 0 !== dirtyWidgetIds.length ) {
|
||||
unsavedWidgetsElements = $( '#widgets-right' ).find( '.widget' ).filter( function() {
|
||||
return -1 !== dirtyWidgetIds.indexOf( $( this ).prop( 'id' ).replace( /^widget-\d+_/, '' ) );
|
||||
});
|
||||
unsavedWidgetsElements.each( function() {
|
||||
if ( ! $( this ).hasClass( 'open' ) ) {
|
||||
$( this ).find( '.widget-title-action:first' ).click();
|
||||
}
|
||||
});
|
||||
|
||||
// Bring the first unsaved widget into view and focus on the first tabbable field.
|
||||
unsavedWidgetsElements.first().each( function() {
|
||||
if ( this.scrollIntoViewIfNeeded ) {
|
||||
this.scrollIntoViewIfNeeded();
|
||||
} else {
|
||||
this.scrollIntoView();
|
||||
}
|
||||
$( this ).find( '.widget-inside :tabbable:first' ).focus();
|
||||
} );
|
||||
|
||||
event.returnValue = wpWidgets.l10n.saveAlert;
|
||||
return event.returnValue;
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the widgets containers in the left column.
|
||||
$( '#widgets-left .sidebar-name' ).click( function() {
|
||||
var $wrap = $( this ).closest( '.widgets-holder-wrap' );
|
||||
|
||||
$wrap
|
||||
.toggleClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', ! $wrap.hasClass( 'closed' ) );
|
||||
|
||||
// Update the admin menu "sticky" state.
|
||||
$document.triggerHandler( 'wp-pin-menu' );
|
||||
});
|
||||
|
||||
$(document.body).bind('click.widgets-toggle', function(e) {
|
||||
var target = $(e.target),
|
||||
css = { 'z-index': 100 },
|
||||
widget, inside, targetWidth, widgetWidth, margin, saveButton, widgetId,
|
||||
toggleBtn = target.closest( '.widget' ).find( '.widget-top button.widget-action' );
|
||||
|
||||
if ( target.parents('.widget-top').length && ! target.parents('#available-widgets').length ) {
|
||||
widget = target.closest('div.widget');
|
||||
inside = widget.children('.widget-inside');
|
||||
targetWidth = parseInt( widget.find('input.widget-width').val(), 10 );
|
||||
widgetWidth = widget.parent().width();
|
||||
widgetId = inside.find( '.widget-id' ).val();
|
||||
|
||||
// Save button is initially disabled, but is enabled when a field is changed.
|
||||
if ( ! widget.data( 'dirty-state-initialized' ) ) {
|
||||
saveButton = inside.find( '.widget-control-save' );
|
||||
saveButton.prop( 'disabled', true ).val( wpWidgets.l10n.saved );
|
||||
inside.on( 'input change', function() {
|
||||
self.dirtyWidgets[ widgetId ] = true;
|
||||
widget.addClass( 'widget-dirty' );
|
||||
saveButton.prop( 'disabled', false ).val( wpWidgets.l10n.save );
|
||||
});
|
||||
widget.data( 'dirty-state-initialized', true );
|
||||
}
|
||||
|
||||
if ( inside.is(':hidden') ) {
|
||||
if ( targetWidth > 250 && ( targetWidth + 30 > widgetWidth ) && widget.closest('div.widgets-sortables').length ) {
|
||||
if ( widget.closest('div.widget-liquid-right').length ) {
|
||||
margin = isRTL ? 'margin-right' : 'margin-left';
|
||||
} else {
|
||||
margin = isRTL ? 'margin-left' : 'margin-right';
|
||||
}
|
||||
|
||||
css[ margin ] = widgetWidth - ( targetWidth + 30 ) + 'px';
|
||||
widget.css( css );
|
||||
}
|
||||
/*
|
||||
* Don't change the order of attributes changes and animation:
|
||||
* it's important for screen readers, see ticket #31476.
|
||||
*/
|
||||
toggleBtn.attr( 'aria-expanded', 'true' );
|
||||
inside.slideDown( 'fast', function() {
|
||||
widget.addClass( 'open' );
|
||||
});
|
||||
} else {
|
||||
/*
|
||||
* Don't change the order of attributes changes and animation:
|
||||
* it's important for screen readers, see ticket #31476.
|
||||
*/
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
inside.slideUp( 'fast', function() {
|
||||
widget.attr( 'style', '' );
|
||||
widget.removeClass( 'open' );
|
||||
});
|
||||
}
|
||||
} else if ( target.hasClass('widget-control-save') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 0, 1, 0 );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-remove') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 1, 1, 0 );
|
||||
} else if ( target.hasClass('widget-control-close') ) {
|
||||
widget = target.closest('div.widget');
|
||||
widget.removeClass( 'open' );
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
wpWidgets.close( widget );
|
||||
} else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) {
|
||||
wpWidgets.removeInactiveWidgets();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
sidebars.children('.widget').each( function() {
|
||||
var $this = $(this);
|
||||
|
||||
wpWidgets.appendTitle( this );
|
||||
|
||||
if ( $this.find( 'p.widget-error' ).length ) {
|
||||
$this.find( '.widget-action' ).trigger( 'click' ).attr( 'aria-expanded', 'true' );
|
||||
}
|
||||
});
|
||||
|
||||
$('#widget-list').children('.widget').draggable({
|
||||
connectToSortable: 'div.widgets-sortables',
|
||||
handle: '> .widget-top > .widget-title',
|
||||
distance: 2,
|
||||
helper: 'clone',
|
||||
zIndex: 100,
|
||||
containment: '#wpwrap',
|
||||
refreshPositions: true,
|
||||
start: function( event, ui ) {
|
||||
var chooser = $(this).find('.widgets-chooser');
|
||||
|
||||
ui.helper.find('div.widget-description').hide();
|
||||
the_id = this.id;
|
||||
|
||||
if ( chooser.length ) {
|
||||
// Hide the chooser and move it out of the widget
|
||||
$( '#wpbody-content' ).append( chooser.hide() );
|
||||
// Delete the cloned chooser from the drag helper
|
||||
ui.helper.find('.widgets-chooser').remove();
|
||||
self.clearWidgetSelection();
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
if ( rem ) {
|
||||
$(rem).hide();
|
||||
}
|
||||
|
||||
rem = '';
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Opens and closes previously closed Sidebars when Widgets are dragged over/out of them.
|
||||
*/
|
||||
sidebars.droppable( {
|
||||
tolerance: 'intersect',
|
||||
|
||||
/**
|
||||
* Open Sidebar when a Widget gets dragged over it.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
over: function( event ) {
|
||||
var $wrap = $( event.target ).parent();
|
||||
|
||||
if ( wpWidgets.hoveredSidebar && ! $wrap.is( wpWidgets.hoveredSidebar ) ) {
|
||||
// Close the previous Sidebar as the Widget has been dragged onto another Sidebar.
|
||||
wpWidgets.closeSidebar( event );
|
||||
}
|
||||
|
||||
if ( $wrap.hasClass( 'closed' ) ) {
|
||||
wpWidgets.hoveredSidebar = $wrap;
|
||||
$wrap
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
}
|
||||
|
||||
$( this ).sortable( 'refresh' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Close Sidebar when the Widget gets dragged out of it.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
out: function( event ) {
|
||||
if ( wpWidgets.hoveredSidebar ) {
|
||||
wpWidgets.closeSidebar( event );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
sidebars.sortable({
|
||||
placeholder: 'widget-placeholder',
|
||||
items: '> .widget',
|
||||
handle: '> .widget-top > .widget-title',
|
||||
cursor: 'move',
|
||||
distance: 2,
|
||||
containment: '#wpwrap',
|
||||
tolerance: 'pointer',
|
||||
refreshPositions: true,
|
||||
start: function( event, ui ) {
|
||||
var height, $this = $(this),
|
||||
$wrap = $this.parent(),
|
||||
inside = ui.item.children('.widget-inside');
|
||||
|
||||
if ( inside.css('display') === 'block' ) {
|
||||
ui.item.removeClass('open');
|
||||
ui.item.find( '.widget-top button.widget-action' ).attr( 'aria-expanded', 'false' );
|
||||
inside.hide();
|
||||
$(this).sortable('refreshPositions');
|
||||
}
|
||||
|
||||
if ( ! $wrap.hasClass('closed') ) {
|
||||
// Lock all open sidebars min-height when starting to drag.
|
||||
// Prevents jumping when dragging a widget from an open sidebar to a closed sidebar below.
|
||||
height = ui.item.hasClass('ui-draggable') ? $this.height() : 1 + $this.height();
|
||||
$this.css( 'min-height', height + 'px' );
|
||||
}
|
||||
},
|
||||
|
||||
stop: function( event, ui ) {
|
||||
var addNew, widgetNumber, $sidebar, $children, child, item,
|
||||
$widget = ui.item,
|
||||
id = the_id;
|
||||
|
||||
// Reset the var to hold a previously closed sidebar.
|
||||
wpWidgets.hoveredSidebar = null;
|
||||
|
||||
if ( $widget.hasClass('deleting') ) {
|
||||
wpWidgets.save( $widget, 1, 0, 1 ); // delete widget
|
||||
$widget.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
addNew = $widget.find('input.add_new').val();
|
||||
widgetNumber = $widget.find('input.multi_number').val();
|
||||
|
||||
$widget.attr( 'style', '' ).removeClass('ui-draggable');
|
||||
the_id = '';
|
||||
|
||||
if ( addNew ) {
|
||||
if ( 'multi' === addNew ) {
|
||||
$widget.html(
|
||||
$widget.html().replace( /<[^<>]+>/g, function( tag ) {
|
||||
return tag.replace( /__i__|%i%/g, widgetNumber );
|
||||
})
|
||||
);
|
||||
|
||||
$widget.attr( 'id', id.replace( '__i__', widgetNumber ) );
|
||||
widgetNumber++;
|
||||
|
||||
$( 'div#' + id ).find( 'input.multi_number' ).val( widgetNumber );
|
||||
} else if ( 'single' === addNew ) {
|
||||
$widget.attr( 'id', 'new-' + id );
|
||||
rem = 'div#' + id;
|
||||
}
|
||||
|
||||
wpWidgets.save( $widget, 0, 0, 1 );
|
||||
$widget.find('input.add_new').val('');
|
||||
$document.trigger( 'widget-added', [ $widget ] );
|
||||
}
|
||||
|
||||
$sidebar = $widget.parent();
|
||||
|
||||
if ( $sidebar.parent().hasClass('closed') ) {
|
||||
$sidebar.parent()
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
|
||||
$children = $sidebar.children('.widget');
|
||||
|
||||
// Make sure the dropped widget is at the top
|
||||
if ( $children.length > 1 ) {
|
||||
child = $children.get(0);
|
||||
item = $widget.get(0);
|
||||
|
||||
if ( child.id && item.id && child.id !== item.id ) {
|
||||
$( child ).before( $widget );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( addNew ) {
|
||||
$widget.find( '.widget-action' ).trigger( 'click' );
|
||||
} else {
|
||||
wpWidgets.saveOrder( $sidebar.attr('id') );
|
||||
}
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
$(this).parent().addClass( 'widget-hover' );
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
// Remove all min-height added on "start"
|
||||
$(this).css( 'min-height', '' ).parent().removeClass( 'widget-hover' );
|
||||
},
|
||||
|
||||
receive: function( event, ui ) {
|
||||
var $sender = $( ui.sender );
|
||||
|
||||
// Don't add more widgets to orphaned sidebars
|
||||
if ( this.id.indexOf('orphaned_widgets') > -1 ) {
|
||||
$sender.sortable('cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
// If the last widget was moved out of an orphaned sidebar, close and remove it.
|
||||
if ( $sender.attr('id').indexOf('orphaned_widgets') > -1 && ! $sender.children('.widget').length ) {
|
||||
$sender.parents('.orphan-sidebar').slideUp( 400, function(){ $(this).remove(); } );
|
||||
}
|
||||
}
|
||||
}).sortable( 'option', 'connectWith', 'div.widgets-sortables' );
|
||||
|
||||
$('#available-widgets').droppable({
|
||||
tolerance: 'pointer',
|
||||
accept: function(o){
|
||||
return $(o).parent().attr('id') !== 'widget-list';
|
||||
},
|
||||
drop: function(e,ui) {
|
||||
ui.draggable.addClass('deleting');
|
||||
$('#removing-widget').hide().children('span').empty();
|
||||
},
|
||||
over: function(e,ui) {
|
||||
ui.draggable.addClass('deleting');
|
||||
$('div.widget-placeholder').hide();
|
||||
|
||||
if ( ui.draggable.hasClass('ui-sortable-helper') ) {
|
||||
$('#removing-widget').show().children('span')
|
||||
.html( ui.draggable.find( 'div.widget-title' ).children( 'h3' ).html() );
|
||||
}
|
||||
},
|
||||
out: function(e,ui) {
|
||||
ui.draggable.removeClass('deleting');
|
||||
$('div.widget-placeholder').show();
|
||||
$('#removing-widget').hide().children('span').empty();
|
||||
}
|
||||
});
|
||||
|
||||
// Area Chooser
|
||||
$( '#widgets-right .widgets-holder-wrap' ).each( function( index, element ) {
|
||||
var $element = $( element ),
|
||||
name = $element.find( '.sidebar-name h2' ).text(),
|
||||
ariaLabel = $element.find( '.sidebar-name' ).data( 'add-to' ),
|
||||
id = $element.find( '.widgets-sortables' ).attr( 'id' ),
|
||||
li = $( '<li>' ),
|
||||
button = $( '<button>', {
|
||||
type: 'button',
|
||||
'aria-pressed': 'false',
|
||||
'class': 'widgets-chooser-button',
|
||||
'aria-label': ariaLabel
|
||||
} ).text( $.trim( name ) );
|
||||
|
||||
li.append( button );
|
||||
|
||||
if ( index === 0 ) {
|
||||
li.addClass( 'widgets-chooser-selected' );
|
||||
button.attr( 'aria-pressed', 'true' );
|
||||
}
|
||||
|
||||
selectSidebar.append( li );
|
||||
li.data( 'sidebarId', id );
|
||||
});
|
||||
|
||||
$( '#available-widgets .widget .widget-top' ).on( 'click.widgets-chooser', function() {
|
||||
var $widget = $( this ).closest( '.widget' ),
|
||||
toggleButton = $( this ).find( '.widget-action' ),
|
||||
chooserButtons = selectSidebar.find( '.widgets-chooser-button' );
|
||||
|
||||
if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
|
||||
toggleButton.attr( 'aria-expanded', 'false' );
|
||||
self.closeChooser();
|
||||
} else {
|
||||
// Open the chooser
|
||||
self.clearWidgetSelection();
|
||||
$( '#widgets-left' ).addClass( 'chooser' );
|
||||
// Add CSS class and insert the chooser after the widget description.
|
||||
$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
|
||||
// Open the chooser with a slide down animation.
|
||||
chooser.slideDown( 300, function() {
|
||||
// Update the toggle button aria-expanded attribute after previous DOM manipulations.
|
||||
toggleButton.attr( 'aria-expanded', 'true' );
|
||||
});
|
||||
|
||||
chooserButtons.on( 'click.widgets-chooser', function() {
|
||||
selectSidebar.find( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' );
|
||||
chooserButtons.attr( 'aria-pressed', 'false' );
|
||||
$( this )
|
||||
.attr( 'aria-pressed', 'true' )
|
||||
.closest( 'li' ).addClass( 'widgets-chooser-selected' );
|
||||
} );
|
||||
}
|
||||
});
|
||||
|
||||
// Add event handlers
|
||||
chooser.on( 'click.widgets-chooser', function( event ) {
|
||||
var $target = $( event.target );
|
||||
|
||||
if ( $target.hasClass('button-primary') ) {
|
||||
self.addWidget( chooser );
|
||||
self.closeChooser();
|
||||
} else if ( $target.hasClass( 'widgets-chooser-cancel' ) ) {
|
||||
self.closeChooser();
|
||||
}
|
||||
}).on( 'keyup.widgets-chooser', function( event ) {
|
||||
if ( event.which === $.ui.keyCode.ESCAPE ) {
|
||||
self.closeChooser();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
saveOrder : function( sidebarId ) {
|
||||
var data = {
|
||||
action: 'widgets-order',
|
||||
savewidgets: $('#_wpnonce_widgets').val(),
|
||||
sidebars: []
|
||||
};
|
||||
|
||||
if ( sidebarId ) {
|
||||
$( '#' + sidebarId ).find( '.spinner:first' ).addClass( 'is-active' );
|
||||
}
|
||||
|
||||
$('div.widgets-sortables').each( function() {
|
||||
if ( $(this).sortable ) {
|
||||
data['sidebars[' + $(this).attr('id') + ']'] = $(this).sortable('toArray').join(',');
|
||||
}
|
||||
});
|
||||
|
||||
$.post( ajaxurl, data, function() {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
$( '.spinner' ).removeClass( 'is-active' );
|
||||
});
|
||||
},
|
||||
|
||||
save : function( widget, del, animate, order ) {
|
||||
var self = this, data, a,
|
||||
sidebarId = widget.closest( 'div.widgets-sortables' ).attr( 'id' ),
|
||||
form = widget.find( 'form' ),
|
||||
isAdd = widget.find( 'input.add_new' ).val();
|
||||
|
||||
if ( ! del && ! isAdd && form.prop( 'checkValidity' ) && ! form[0].checkValidity() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = form.serialize();
|
||||
|
||||
widget = $(widget);
|
||||
$( '.spinner', widget ).addClass( 'is-active' );
|
||||
|
||||
a = {
|
||||
action: 'save-widget',
|
||||
savewidgets: $('#_wpnonce_widgets').val(),
|
||||
sidebar: sidebarId
|
||||
};
|
||||
|
||||
if ( del ) {
|
||||
a.delete_widget = 1;
|
||||
}
|
||||
|
||||
data += '&' + $.param(a);
|
||||
|
||||
$.post( ajaxurl, data, function(r) {
|
||||
var id = $('input.widget-id', widget).val();
|
||||
|
||||
if ( del ) {
|
||||
if ( ! $('input.widget_number', widget).val() ) {
|
||||
$('#available-widgets').find('input.widget-id').each(function(){
|
||||
if ( $(this).val() === id ) {
|
||||
$(this).closest('div.widget').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( animate ) {
|
||||
order = 0;
|
||||
widget.slideUp( 'fast', function() {
|
||||
$( this ).remove();
|
||||
wpWidgets.saveOrder();
|
||||
delete self.dirtyWidgets[ id ];
|
||||
});
|
||||
} else {
|
||||
widget.remove();
|
||||
delete self.dirtyWidgets[ id ];
|
||||
|
||||
if ( sidebarId === 'wp_inactive_widgets' ) {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$( '.spinner' ).removeClass( 'is-active' );
|
||||
if ( r && r.length > 2 ) {
|
||||
$( 'div.widget-content', widget ).html( r );
|
||||
wpWidgets.appendTitle( widget );
|
||||
|
||||
// Re-disable the save button.
|
||||
widget.find( '.widget-control-save' ).prop( 'disabled', true ).val( wpWidgets.l10n.saved );
|
||||
|
||||
widget.removeClass( 'widget-dirty' );
|
||||
|
||||
// Clear the dirty flag from the widget.
|
||||
delete self.dirtyWidgets[ id ];
|
||||
|
||||
$document.trigger( 'widget-updated', [ widget ] );
|
||||
|
||||
if ( sidebarId === 'wp_inactive_widgets' ) {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( order ) {
|
||||
wpWidgets.saveOrder();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeInactiveWidgets : function() {
|
||||
var $element = $( '.remove-inactive-widgets' ), self = this, a, data;
|
||||
|
||||
$( '.spinner', $element ).addClass( 'is-active' );
|
||||
|
||||
a = {
|
||||
action : 'delete-inactive-widgets',
|
||||
removeinactivewidgets : $( '#_wpnonce_remove_inactive_widgets' ).val()
|
||||
};
|
||||
|
||||
data = $.param( a );
|
||||
|
||||
$.post( ajaxurl, data, function() {
|
||||
$( '#wp_inactive_widgets .widget' ).each(function() {
|
||||
var $widget = $( this );
|
||||
delete self.dirtyWidgets[ $widget.find( 'input.widget-id' ).val() ];
|
||||
$widget.remove();
|
||||
});
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled', true );
|
||||
$( '.spinner', $element ).removeClass( 'is-active' );
|
||||
} );
|
||||
},
|
||||
|
||||
appendTitle : function(widget) {
|
||||
var title = $('input[id*="-title"]', widget).val() || '';
|
||||
|
||||
if ( title ) {
|
||||
title = ': ' + title.replace(/<[^<>]+>/g, '').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
$(widget).children('.widget-top').children('.widget-title').children()
|
||||
.children('.in-widget-title').html(title);
|
||||
|
||||
},
|
||||
|
||||
close : function(widget) {
|
||||
widget.children('.widget-inside').slideUp('fast', function() {
|
||||
widget.attr( 'style', '' )
|
||||
.find( '.widget-top button.widget-action' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
});
|
||||
},
|
||||
|
||||
addWidget: function( chooser ) {
|
||||
var widget, widgetId, add, n, viewportTop, viewportBottom, sidebarBounds,
|
||||
sidebarId = chooser.find( '.widgets-chooser-selected' ).data('sidebarId'),
|
||||
sidebar = $( '#' + sidebarId );
|
||||
|
||||
widget = $('#available-widgets').find('.widget-in-question').clone();
|
||||
widgetId = widget.attr('id');
|
||||
add = widget.find( 'input.add_new' ).val();
|
||||
n = widget.find( 'input.multi_number' ).val();
|
||||
|
||||
// Remove the cloned chooser from the widget
|
||||
widget.find('.widgets-chooser').remove();
|
||||
|
||||
if ( 'multi' === add ) {
|
||||
widget.html(
|
||||
widget.html().replace( /<[^<>]+>/g, function(m) {
|
||||
return m.replace( /__i__|%i%/g, n );
|
||||
})
|
||||
);
|
||||
|
||||
widget.attr( 'id', widgetId.replace( '__i__', n ) );
|
||||
n++;
|
||||
$( '#' + widgetId ).find('input.multi_number').val(n);
|
||||
} else if ( 'single' === add ) {
|
||||
widget.attr( 'id', 'new-' + widgetId );
|
||||
$( '#' + widgetId ).hide();
|
||||
}
|
||||
|
||||
// Open the widgets container.
|
||||
sidebar.closest( '.widgets-holder-wrap' )
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
|
||||
sidebar.append( widget );
|
||||
sidebar.sortable('refresh');
|
||||
|
||||
wpWidgets.save( widget, 0, 0, 1 );
|
||||
// No longer "new" widget
|
||||
widget.find( 'input.add_new' ).val('');
|
||||
|
||||
$document.trigger( 'widget-added', [ widget ] );
|
||||
|
||||
/*
|
||||
* Check if any part of the sidebar is visible in the viewport. If it is, don't scroll.
|
||||
* Otherwise, scroll up to so the sidebar is in view.
|
||||
*
|
||||
* We do this by comparing the top and bottom, of the sidebar so see if they are within
|
||||
* the bounds of the viewport.
|
||||
*/
|
||||
viewportTop = $(window).scrollTop();
|
||||
viewportBottom = viewportTop + $(window).height();
|
||||
sidebarBounds = sidebar.offset();
|
||||
|
||||
sidebarBounds.bottom = sidebarBounds.top + sidebar.outerHeight();
|
||||
|
||||
if ( viewportTop > sidebarBounds.bottom || viewportBottom < sidebarBounds.top ) {
|
||||
$( 'html, body' ).animate({
|
||||
scrollTop: sidebarBounds.top - 130
|
||||
}, 200 );
|
||||
}
|
||||
|
||||
window.setTimeout( function() {
|
||||
// Cannot use a callback in the animation above as it fires twice,
|
||||
// have to queue this "by hand".
|
||||
widget.find( '.widget-title' ).trigger('click');
|
||||
// At the end of the animation, announce the widget has been added.
|
||||
window.wp.a11y.speak( wpWidgets.l10n.widgetAdded, 'assertive' );
|
||||
}, 250 );
|
||||
},
|
||||
|
||||
closeChooser: function() {
|
||||
var self = this,
|
||||
widgetInQuestion = $( '#available-widgets .widget-in-question' );
|
||||
|
||||
$( '.widgets-chooser' ).slideUp( 200, function() {
|
||||
$( '#wpbody-content' ).append( this );
|
||||
self.clearWidgetSelection();
|
||||
// Move focus back to the toggle button.
|
||||
widgetInQuestion.find( '.widget-action' ).attr( 'aria-expanded', 'false' ).focus();
|
||||
});
|
||||
},
|
||||
|
||||
clearWidgetSelection: function() {
|
||||
$( '#widgets-left' ).removeClass( 'chooser' );
|
||||
$( '.widget-in-question' ).removeClass( 'widget-in-question' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes a Sidebar that was previously closed, but opened by dragging a Widget over it.
|
||||
*
|
||||
* Used when a Widget gets dragged in/out of the Sidebar and never dropped.
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
closeSidebar: function( event ) {
|
||||
this.hoveredSidebar
|
||||
.addClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'false' );
|
||||
|
||||
$( event.target ).css( 'min-height', '' );
|
||||
this.hoveredSidebar = null;
|
||||
}
|
||||
};
|
||||
|
||||
$document.ready( function(){ wpWidgets.init(); } );
|
||||
|
||||
})(jQuery);
|
||||
1
wp-admin/js/widgets.min.js
vendored
Normal file
1
wp-admin/js/widgets.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
456
wp-admin/js/widgets/custom-html-widgets.js
Normal file
456
wp-admin/js/widgets/custom-html-widgets.js
Normal file
@@ -0,0 +1,456 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/custom-html-widgets.min.js
vendored
Normal file
1
wp-admin/js/widgets/custom-html-widgets.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
154
wp-admin/js/widgets/media-audio-widget.js
Normal file
154
wp-admin/js/widgets/media-audio-widget.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/media-audio-widget.min.js
vendored
Normal file
1
wp-admin/js/widgets/media-audio-widget.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!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);
|
||||
341
wp-admin/js/widgets/media-gallery-widget.js
Normal file
341
wp-admin/js/widgets/media-gallery-widget.js
Normal file
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/media-gallery-widget.min.js
vendored
Normal file
1
wp-admin/js/widgets/media-gallery-widget.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!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);
|
||||
170
wp-admin/js/widgets/media-image-widget.js
Normal file
170
wp-admin/js/widgets/media-image-widget.js
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/media-image-widget.min.js
vendored
Normal file
1
wp-admin/js/widgets/media-image-widget.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!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);
|
||||
256
wp-admin/js/widgets/media-video-widget.js
Normal file
256
wp-admin/js/widgets/media-video-widget.js
Normal file
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/media-video-widget.min.js
vendored
Normal file
1
wp-admin/js/widgets/media-video-widget.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!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);
|
||||
1330
wp-admin/js/widgets/media-widgets.js
Normal file
1330
wp-admin/js/widgets/media-widgets.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wp-admin/js/widgets/media-widgets.min.js
vendored
Normal file
1
wp-admin/js/widgets/media-widgets.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
552
wp-admin/js/widgets/text-widgets.js
Normal file
552
wp-admin/js/widgets/text-widgets.js
Normal file
@@ -0,0 +1,552 @@
|
||||
/**
|
||||
* @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 );
|
||||
1
wp-admin/js/widgets/text-widgets.min.js
vendored
Normal file
1
wp-admin/js/widgets/text-widgets.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
218
wp-admin/js/word-count.js
Normal file
218
wp-admin/js/word-count.js
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* Word or character counting functionality. Count words or characters in a
|
||||
* provided text string.
|
||||
*
|
||||
* @namespace wp.utils
|
||||
* @since 2.6.0
|
||||
* @output wp-admin/js/word-count.js
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Word counting utility
|
||||
*
|
||||
* @namespace wp.utils.wordcounter
|
||||
* @memberof wp.utils
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @param {Object} settings Optional. Key-value object containing overrides for
|
||||
* settings.
|
||||
* @param {RegExp} settings.HTMLRegExp Optional. Regular expression to find HTML elements.
|
||||
* @param {RegExp} settings.HTMLcommentRegExp Optional. Regular expression to find HTML comments.
|
||||
* @param {RegExp} settings.spaceRegExp Optional. Regular expression to find irregular space
|
||||
* characters.
|
||||
* @param {RegExp} settings.HTMLEntityRegExp Optional. Regular expression to find HTML entities.
|
||||
* @param {RegExp} settings.connectorRegExp Optional. Regular expression to find connectors that
|
||||
* split words.
|
||||
* @param {RegExp} settings.removeRegExp Optional. Regular expression to find remove unwanted
|
||||
* characters to reduce false-positives.
|
||||
* @param {RegExp} settings.astralRegExp Optional. Regular expression to find unwanted
|
||||
* characters when searching for non-words.
|
||||
* @param {RegExp} settings.wordsRegExp Optional. Regular expression to find words by spaces.
|
||||
* @param {RegExp} settings.characters_excluding_spacesRegExp Optional. Regular expression to find characters which
|
||||
* are non-spaces.
|
||||
* @param {RegExp} settings.characters_including_spacesRegExp Optional. Regular expression to find characters
|
||||
* including spaces.
|
||||
* @param {RegExp} settings.shortcodesRegExp Optional. Regular expression to find shortcodes.
|
||||
* @param {Object} settings.l10n Optional. Localization object containing specific
|
||||
* configuration for the current localization.
|
||||
* @param {String} settings.l10n.type Optional. Method of finding words to count.
|
||||
* @param {Array} settings.l10n.shortcodes Optional. Array of shortcodes that should be removed
|
||||
* from the text.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function WordCounter( settings ) {
|
||||
var key,
|
||||
shortcodes;
|
||||
|
||||
// Apply provided settings to object settings.
|
||||
if ( settings ) {
|
||||
for ( key in settings ) {
|
||||
|
||||
// Only apply valid settings.
|
||||
if ( settings.hasOwnProperty( key ) ) {
|
||||
this.settings[ key ] = settings[ key ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shortcodes = this.settings.l10n.shortcodes;
|
||||
|
||||
// If there are any localization shortcodes, add this as type in the settings.
|
||||
if ( shortcodes && shortcodes.length ) {
|
||||
this.settings.shortcodesRegExp = new RegExp( '\\[\\/?(?:' + shortcodes.join( '|' ) + ')[^\\]]*?\\]', 'g' );
|
||||
}
|
||||
}
|
||||
|
||||
// Default settings.
|
||||
WordCounter.prototype.settings = {
|
||||
HTMLRegExp: /<\/?[a-z][^>]*?>/gi,
|
||||
HTMLcommentRegExp: /<!--[\s\S]*?-->/g,
|
||||
spaceRegExp: / | /gi,
|
||||
HTMLEntityRegExp: /&\S+?;/g,
|
||||
|
||||
// \u2014 = em-dash
|
||||
connectorRegExp: /--|\u2014/g,
|
||||
|
||||
// Characters to be removed from input text.
|
||||
removeRegExp: new RegExp( [
|
||||
'[',
|
||||
|
||||
// Basic Latin (extract)
|
||||
'\u0021-\u0040\u005B-\u0060\u007B-\u007E',
|
||||
|
||||
// Latin-1 Supplement (extract)
|
||||
'\u0080-\u00BF\u00D7\u00F7',
|
||||
|
||||
/*
|
||||
* The following range consists of:
|
||||
* General Punctuation
|
||||
* Superscripts and Subscripts
|
||||
* Currency Symbols
|
||||
* Combining Diacritical Marks for Symbols
|
||||
* Letterlike Symbols
|
||||
* Number Forms
|
||||
* Arrows
|
||||
* Mathematical Operators
|
||||
* Miscellaneous Technical
|
||||
* Control Pictures
|
||||
* Optical Character Recognition
|
||||
* Enclosed Alphanumerics
|
||||
* Box Drawing
|
||||
* Block Elements
|
||||
* Geometric Shapes
|
||||
* Miscellaneous Symbols
|
||||
* Dingbats
|
||||
* Miscellaneous Mathematical Symbols-A
|
||||
* Supplemental Arrows-A
|
||||
* Braille Patterns
|
||||
* Supplemental Arrows-B
|
||||
* Miscellaneous Mathematical Symbols-B
|
||||
* Supplemental Mathematical Operators
|
||||
* Miscellaneous Symbols and Arrows
|
||||
*/
|
||||
'\u2000-\u2BFF',
|
||||
|
||||
// Supplemental Punctuation
|
||||
'\u2E00-\u2E7F',
|
||||
']'
|
||||
].join( '' ), 'g' ),
|
||||
|
||||
// Remove UTF-16 surrogate points, see https://en.wikipedia.org/wiki/UTF-16#U.2BD800_to_U.2BDFFF
|
||||
astralRegExp: /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
||||
wordsRegExp: /\S\s+/g,
|
||||
characters_excluding_spacesRegExp: /\S/g,
|
||||
|
||||
/*
|
||||
* Match anything that is not a formatting character, excluding:
|
||||
* \f = form feed
|
||||
* \n = new line
|
||||
* \r = carriage return
|
||||
* \t = tab
|
||||
* \v = vertical tab
|
||||
* \u00AD = soft hyphen
|
||||
* \u2028 = line separator
|
||||
* \u2029 = paragraph separator
|
||||
*/
|
||||
characters_including_spacesRegExp: /[^\f\n\r\t\v\u00AD\u2028\u2029]/g,
|
||||
l10n: window.wordCountL10n || {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Counts the number of words (or other specified type) in the specified text.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @memberof wp.utils.wordcounter
|
||||
*
|
||||
* @param {String} text Text to count elements in.
|
||||
* @param {String} type Optional. Specify type to use.
|
||||
*
|
||||
* @return {Number} The number of items counted.
|
||||
*/
|
||||
WordCounter.prototype.count = function( text, type ) {
|
||||
var count = 0;
|
||||
|
||||
// Use default type if none was provided.
|
||||
type = type || this.settings.l10n.type;
|
||||
|
||||
// Sanitize type to one of three possibilities: 'words', 'characters_excluding_spaces' or 'characters_including_spaces'.
|
||||
if ( type !== 'characters_excluding_spaces' && type !== 'characters_including_spaces' ) {
|
||||
type = 'words';
|
||||
}
|
||||
|
||||
// If we have any text at all.
|
||||
if ( text ) {
|
||||
text = text + '\n';
|
||||
|
||||
// Replace all HTML with a new-line.
|
||||
text = text.replace( this.settings.HTMLRegExp, '\n' );
|
||||
|
||||
// Remove all HTML comments.
|
||||
text = text.replace( this.settings.HTMLcommentRegExp, '' );
|
||||
|
||||
// If a shortcode regular expression has been provided use it to remove shortcodes.
|
||||
if ( this.settings.shortcodesRegExp ) {
|
||||
text = text.replace( this.settings.shortcodesRegExp, '\n' );
|
||||
}
|
||||
|
||||
// Normalize non-breaking space to a normal space.
|
||||
text = text.replace( this.settings.spaceRegExp, ' ' );
|
||||
|
||||
if ( type === 'words' ) {
|
||||
|
||||
// Remove HTML Entities.
|
||||
text = text.replace( this.settings.HTMLEntityRegExp, '' );
|
||||
|
||||
// Convert connectors to spaces to count attached text as words.
|
||||
text = text.replace( this.settings.connectorRegExp, ' ' );
|
||||
|
||||
// Remove unwanted characters.
|
||||
text = text.replace( this.settings.removeRegExp, '' );
|
||||
} else {
|
||||
|
||||
// Convert HTML Entities to "a".
|
||||
text = text.replace( this.settings.HTMLEntityRegExp, 'a' );
|
||||
|
||||
// Remove surrogate points.
|
||||
text = text.replace( this.settings.astralRegExp, 'a' );
|
||||
}
|
||||
|
||||
// Match with the selected type regular expression to count the items.
|
||||
text = text.match( this.settings[ type + 'RegExp' ] );
|
||||
|
||||
// If we have any matches, set the count to the number of items found.
|
||||
if ( text ) {
|
||||
count = text.length;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
// Add the WordCounter to the WP Utils.
|
||||
window.wp = window.wp || {};
|
||||
window.wp.utils = window.wp.utils || {};
|
||||
window.wp.utils.WordCounter = WordCounter;
|
||||
} )();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user