init
This commit is contained in:
commit
ff6f6c80cd
1709 changed files with 840760 additions and 0 deletions
93
wp-admin/js/accordion.js
Normal file
93
wp-admin/js/accordion.js
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
( 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(a){function b(a){var b=a.closest(".accordion-section"),c=b.find("[aria-expanded]").first(),d=b.closest(".accordion-container"),e=d.find(".open"),f=e.find("[aria-expanded]").first(),g=b.find(".accordion-section-content");b.hasClass("cannot-expand")||(d.addClass("opening"),b.hasClass("open")?(b.toggleClass("open"),g.toggle(!0).slideToggle(150)):(f.attr("aria-expanded","false"),e.removeClass("open"),e.find(".accordion-section-content").show().slideUp(150),g.toggle(!1).slideToggle(150),b.toggleClass("open")),setTimeout(function(){d.removeClass("opening")},150),c&&c.attr("aria-expanded",String("false"===c.attr("aria-expanded"))))}a(document).ready(function(){a(".accordion-container").on("click keydown",".accordion-section-title",function(c){"keydown"===c.type&&13!==c.which||(c.preventDefault(),b(a(this)))})})}(jQuery);
|
||||
329
wp-admin/js/code-editor.js
Normal file
329
wp-admin/js/code-editor.js
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
if ( 'undefined' === typeof window.wp ) {
|
||||
window.wp = {};
|
||||
}
|
||||
if ( 'undefined' === typeof window.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} 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 && 'application/x-httpd-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 @@
|
|||
"undefined"==typeof window.wp&&(window.wp={}),"undefined"==typeof window.wp.codeEditor&&(window.wp.codeEditor={}),function(a,b){"use strict";function c(b,c){function d(){c.onUpdateErrorNotice&&!_.isEqual(f,g)&&(c.onUpdateErrorNotice(f,b),g=f)}function e(){var e=b.getOption("lint");return!!e&&(!0===e?e={}:_.isObject(e)&&(e=a.extend({},e)),e.options||(e.options={}),"javascript"===c.codemirror.mode&&c.jshint&&a.extend(e.options,c.jshint),"css"===c.codemirror.mode&&c.csslint&&a.extend(e.options,c.csslint),"htmlmixed"===c.codemirror.mode&&c.htmlhint&&(e.options.rules=a.extend({},c.htmlhint),c.jshint&&(e.options.rules.jshint=c.jshint),c.csslint&&(e.options.rules.csslint=c.csslint)),e.onUpdateLinting=function(a){return function(e,h,i){var j=_.filter(e,function(a){return"error"===a.severity});a&&a.apply(e,h,i),_.isEqual(j,f)||(f=j,c.onChangeLintingErrors&&c.onChangeLintingErrors(j,e,h,i),(!b.state.focused||0===f.length||g.length>0)&&d())}}(e.onUpdateLinting),e)}var f=[],g=[];b.setOption("lint",e()),b.on("optionChange",function(a,c){var g,h,i="CodeMirror-lint-markers";"lint"===c&&(h=b.getOption("gutters")||[],g=b.getOption("lint"),!0===g?(_.contains(h,i)||b.setOption("gutters",[i].concat(h)),b.setOption("lint",e())):g||b.setOption("gutters",_.without(h,i)),b.getOption("lint")?b.performLint():(f=[],d()))}),b.on("blur",d),b.on("startCompletion",function(){b.off("blur",d)}),b.on("endCompletion",function(){var a=500;b.on("blur",d),_.delay(function(){b.state.focused||d()},a)}),a(document.body).on("mousedown",function(c){!b.state.focused||a.contains(b.display.wrapper,c.target)||a(c.target).hasClass("CodeMirror-hint")||d()})}function d(b,c){var d=a(b.getTextArea());b.on("blur",function(){d.data("next-tab-blurs",!1)}),b.on("keydown",function(a,e){var f=9,g=27;return g===e.keyCode?void d.data("next-tab-blurs",!0):void(f===e.keyCode&&d.data("next-tab-blurs")&&(e.shiftKey?c.onTabPrevious(b,e):c.onTabNext(b,e),d.data("next-tab-blurs",!1),e.preventDefault()))})}b.codeEditor.defaultSettings={codemirror:{},csslint:{},htmlhint:{},jshint:{},onTabNext:function(){},onTabPrevious:function(){},onChangeLintingErrors:function(){},onUpdateErrorNotice:function(){}},b.codeEditor.initialize=function(e,f){var g,h,i,j;return g=a("string"==typeof e?"#"+e:e),i=a.extend({},b.codeEditor.defaultSettings,f),i.codemirror=a.extend({},i.codemirror),h=b.CodeMirror.fromTextArea(g[0],i.codemirror),c(h,i),j={settings:i,codemirror:h},h.showHint&&h.on("keyup",function(a,c){var d,e,f,g,i=/^[a-zA-Z]$/.test(c.key);h.state.completionActive&&i||(g=h.getTokenAt(h.getCursor()),"string"!==g.type&&"comment"!==g.type&&(f=b.CodeMirror.innerMode(h.getMode(),g.state).mode.name,e=h.doc.getLine(h.doc.getCursor().line).substr(0,h.doc.getCursor().ch),"html"===f||"xml"===f?d="<"===c.key||"/"===c.key&&"tag"===g.type||i&&"tag"===g.type||i&&"attribute"===g.type||"="===g.string&&g.state.htmlState&&g.state.htmlState.tagName:"css"===f?d=i||":"===c.key||" "===c.key&&/:\s+$/.test(e):"javascript"===f?d=i||"."===c.key:"clike"===f&&"application/x-httpd-php"===h.options.mode&&(d="keyword"===g.type||"variable"===g.type),d&&h.showHint({completeSingle:!1})))}),d(h,f),j}}(window.jQuery,window.wp);
|
||||
363
wp-admin/js/color-picker.js
Normal file
363
wp-admin/js/color-picker.js
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/* 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>';
|
||||
|
||||
/**
|
||||
* @summary Creates a jQuery UI color picker.
|
||||
*
|
||||
* Creates a jQuery UI color picker that is used in the theme customizer.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
ColorPicker = {
|
||||
options: {
|
||||
defaultColor: false,
|
||||
change: false,
|
||||
clear: false,
|
||||
hide: true,
|
||||
palettes: true,
|
||||
width: 255,
|
||||
mode: 'hsv',
|
||||
type: 'full',
|
||||
slider: 'horizontal'
|
||||
},
|
||||
/**
|
||||
* @summary 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,
|
||||
/**
|
||||
* @summary Handles the onChange event if one has been defined in the options.
|
||||
*
|
||||
* @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
|
||||
} );
|
||||
},
|
||||
/**
|
||||
* @summary Creates the color picker.
|
||||
*
|
||||
* 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,
|
||||
/**
|
||||
* @summary Handles the onChange event if one has been defined in the options.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @summary Binds event listeners to the color picker.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_addListeners: function() {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Checks if value is empty when changing the color in the color picker.
|
||||
*
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Enables the user to clear or revert the color in the color picker.
|
||||
*
|
||||
* 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();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @summary 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 );
|
||||
},
|
||||
/**
|
||||
* @summary 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 );
|
||||
},
|
||||
/**
|
||||
* @summary Returns iris object or sets new color.
|
||||
*
|
||||
* 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 );
|
||||
},
|
||||
/**
|
||||
* @summary Returns iris object or sets new default color.
|
||||
*
|
||||
* 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(a,b){var c,d='<button type="button" class="button wp-color-result" aria-expanded="false"><span class="wp-color-result-text"></span></button>',e='<div class="wp-picker-holder" />',f='<div class="wp-picker-container" />',g='<input type="button" class="button button-small" />',h="<label></label>",i='<span class="screen-reader-text"></span>';c={options:{defaultColor:!1,change:!1,clear:!1,hide:!0,palettes:!0,width:255,mode:"hsv",type:"full",slider:"horizontal"},_createHueOnly:function(){var b,c=this,d=c.element;d.hide(),b="hsl("+d.val()+", 100, 50)",d.iris({mode:"hsl",type:"hue",hide:!1,color:b,change:function(b,d){a.isFunction(c.options.change)&&c.options.change.call(this,b,d)},width:c.options.width,slider:c.options.slider})},_create:function(){if(a.support.iris){var b=this,c=b.element;if(a.extend(b.options,c.data()),"hue"===b.options.type)return b._createHueOnly();b.close=a.proxy(b.close,b),b.initialValue=c.val(),c.addClass("wp-color-picker"),c.parent("label").length||(c.wrap(h),b.wrappingLabelText=a(i).insertBefore(c).text(wpColorPickerL10n.defaultLabel)),b.wrappingLabel=c.parent(),b.wrappingLabel.wrap(f),b.wrap=b.wrappingLabel.parent(),b.toggler=a(d).insertBefore(b.wrappingLabel).css({backgroundColor:b.initialValue}),b.toggler.find(".wp-color-result-text").text(wpColorPickerL10n.pick),b.pickerContainer=a(e).insertAfter(b.wrappingLabel),b.button=a(g),b.options.defaultColor?b.button.addClass("wp-picker-default").val(wpColorPickerL10n.defaultString).attr("aria-label",wpColorPickerL10n.defaultAriaLabel):b.button.addClass("wp-picker-clear").val(wpColorPickerL10n.clear).attr("aria-label",wpColorPickerL10n.clearAriaLabel),b.wrappingLabel.wrap('<span class="wp-picker-input-wrap hidden" />').after(b.button),b.inputWrapper=c.closest(".wp-picker-input-wrap"),c.iris({target:b.pickerContainer,hide:b.options.hide,width:b.options.width,mode:b.options.mode,palettes:b.options.palettes,change:function(c,d){b.toggler.css({backgroundColor:d.color.toString()}),a.isFunction(b.options.change)&&b.options.change.call(this,c,d)}}),c.val(b.initialValue),b._addListeners(),b.options.hide||b.toggler.click()}},_addListeners:function(){var b=this;b.wrap.on("click.wpcolorpicker",function(a){a.stopPropagation()}),b.toggler.click(function(){b.toggler.hasClass("wp-picker-open")?b.close():b.open()}),b.element.change(function(c){var d=a(this),e=d.val();""!==e&&"#"!==e||(b.toggler.css("backgroundColor",""),a.isFunction(b.options.clear)&&b.options.clear.call(this,c))}),b.button.click(function(c){var d=a(this);d.hasClass("wp-picker-clear")?(b.element.val(""),b.toggler.css("backgroundColor",""),a.isFunction(b.options.clear)&&b.options.clear.call(this,c)):d.hasClass("wp-picker-default")&&b.element.val(b.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"),a("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"),a("body").off("click.wpcolorpicker",this.close)},color:function(a){return a===b?this.element.iris("option","color"):void this.element.iris("option","color",a)},defaultColor:function(a){return a===b?this.options.defaultColor:void(this.options.defaultColor=a)}},a.widget("wp.wpColorPicker",c)}(jQuery);
|
||||
97
wp-admin/js/comment.js
Normal file
97
wp-admin/js/comment.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* global postboxes, commentL10n */
|
||||
|
||||
/**
|
||||
* @summary 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' );
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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(a){postboxes.add_postbox_toggles("comment");var b=a("#timestampdiv"),c=a("#timestamp"),d=c.html(),e=b.find(".timestamp-wrap"),f=b.siblings("a.edit-timestamp");f.click(function(c){b.is(":hidden")&&(b.slideDown("fast",function(){a("input, select",e).first().focus()}),a(this).hide()),c.preventDefault()}),b.find(".cancel-timestamp").click(function(e){f.show().focus(),b.slideUp("fast"),a("#mm").val(a("#hidden_mm").val()),a("#jj").val(a("#hidden_jj").val()),a("#aa").val(a("#hidden_aa").val()),a("#hh").val(a("#hidden_hh").val()),a("#mn").val(a("#hidden_mn").val()),c.html(d),e.preventDefault()}),b.find(".save-timestamp").click(function(d){var g=a("#aa").val(),h=a("#mm").val(),i=a("#jj").val(),j=a("#hh").val(),k=a("#mn").val(),l=new Date(g,h-1,i,j,k);return d.preventDefault(),l.getFullYear()!=g||1+l.getMonth()!=h||l.getDate()!=i||l.getMinutes()!=k?void e.addClass("form-invalid"):(e.removeClass("form-invalid"),c.html(commentL10n.submittedOn+" <b>"+commentL10n.dateFormat.replace("%1$s",a('option[value="'+h+'"]',"#mm").attr("data-text")).replace("%2$s",parseInt(i,10)).replace("%3$s",g).replace("%4$s",("00"+j).slice(-2)).replace("%5$s",("00"+k).slice(-2))+"</b> "),f.show().focus(),void b.slideUp("fast"))})});
|
||||
1152
wp-admin/js/common.js
Normal file
1152
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
141
wp-admin/js/custom-background.js
Normal file
141
wp-admin/js/custom-background.js
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* @summary Registers all events for customizing the background.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
var frame,
|
||||
bgImage = $( '#custom-background-image' );
|
||||
|
||||
/**
|
||||
* @summary 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', '');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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() );
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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() );
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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' );
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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' );
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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(a){a(document).ready(function(){var b,c=a("#custom-background-image");a("#background-color").wpColorPicker({change:function(a,b){c.css("background-color",b.color.toString())},clear:function(){c.css("background-color","")}}),a('select[name="background-size"]').change(function(){c.css("background-size",a(this).val())}),a('input[name="background-position"]').change(function(){c.css("background-position",a(this).val())}),a('input[name="background-repeat"]').change(function(){c.css("background-repeat",a(this).is(":checked")?"repeat":"no-repeat")}),a('input[name="background-attachment"]').change(function(){c.css("background-attachment",a(this).is(":checked")?"scroll":"fixed")}),a("#choose-from-library-link").click(function(c){var d=a(this);return c.preventDefault(),b?void b.open():(b=wp.media.frames.customBackground=wp.media({title:d.data("choose"),library:{type:"image"},button:{text:d.data("update"),close:!1}}),b.on("select",function(){var c=b.state().get("selection").first();a.post(ajaxurl,{action:"set-background-image",attachment_id:c.id,size:"full"}).done(function(){window.location.reload()})}),void b.open())})})}(jQuery);
|
||||
61
wp-admin/js/custom-header.js
Normal file
61
wp-admin/js/custom-header.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* global isRtl */
|
||||
(function($) {
|
||||
var frame;
|
||||
|
||||
$( function() {
|
||||
// Fetch available headers and apply jQuery.masonry
|
||||
// once the images have loaded.
|
||||
var $headers = $('.available-headers');
|
||||
|
||||
$headers.imagesLoaded( function() {
|
||||
$headers.masonry({
|
||||
itemSelector: '.default-header',
|
||||
isRTL: !! ( 'undefined' != typeof isRtl && isRtl )
|
||||
});
|
||||
});
|
||||
|
||||
// Build the choose from library frame.
|
||||
$('#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
|
||||
}
|
||||
});
|
||||
|
||||
// When an image is selected, run a callback.
|
||||
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));
|
||||
9297
wp-admin/js/customize-controls.js
Normal file
9297
wp-admin/js/customize-controls.js
Normal file
File diff suppressed because it is too large
Load diff
4
wp-admin/js/customize-controls.min.js
vendored
Normal file
4
wp-admin/js/customize-controls.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3449
wp-admin/js/customize-nav-menus.js
Normal file
3449
wp-admin/js/customize-nav-menus.js
Normal file
File diff suppressed because it is too large
Load diff
2
wp-admin/js/customize-nav-menus.min.js
vendored
Normal file
2
wp-admin/js/customize-nav-menus.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2338
wp-admin/js/customize-widgets.js
Normal file
2338
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
499
wp-admin/js/dashboard.js
Normal file
499
wp-admin/js/dashboard.js
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
/* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */
|
||||
var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad;
|
||||
window.wp = window.wp || {};
|
||||
|
||||
jQuery(document).ready( function($) {
|
||||
var welcomePanel = $( '#welcome-panel' ),
|
||||
welcomePanelHide = $('#wp_welcome_panel-hide'),
|
||||
updateWelcomePanel;
|
||||
|
||||
updateWelcomePanel = function( visible ) {
|
||||
$.post( ajaxurl, {
|
||||
action: 'update-welcome-panel',
|
||||
visible: visible,
|
||||
welcomepanelnonce: $( '#welcomepanelnonce' ).val()
|
||||
});
|
||||
};
|
||||
|
||||
if ( welcomePanel.hasClass('hidden') && welcomePanelHide.prop('checked') ) {
|
||||
welcomePanel.removeClass('hidden');
|
||||
}
|
||||
|
||||
$('.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);
|
||||
});
|
||||
|
||||
welcomePanelHide.click( function() {
|
||||
welcomePanel.toggleClass('hidden', ! this.checked );
|
||||
updateWelcomePanel( this.checked ? 1 : 0 );
|
||||
});
|
||||
|
||||
// These widgets are sometimes populated via ajax
|
||||
ajaxWidgets = ['dashboard_primary'];
|
||||
|
||||
ajaxPopulateWidgets = function(el) {
|
||||
function show(i, id) {
|
||||
var p, e = $('#' + id + ' div.inside:visible').find('.widget-loading');
|
||||
if ( e.length ) {
|
||||
p = e.parent();
|
||||
setTimeout( function(){
|
||||
p.load( ajaxurl + '?action=dashboard-widgets&widget=' + id + '&pagenow=' + pagenow, '', function() {
|
||||
p.hide().slideDown('normal', function(){
|
||||
$(this).css('display', '');
|
||||
});
|
||||
});
|
||||
}, i * 500 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( el ) {
|
||||
el = el.toString();
|
||||
if ( $.inArray(el, ajaxWidgets) !== -1 ) {
|
||||
show(0, el);
|
||||
}
|
||||
} else {
|
||||
$.each( ajaxWidgets, show );
|
||||
}
|
||||
};
|
||||
ajaxPopulateWidgets();
|
||||
|
||||
postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );
|
||||
|
||||
/* QuickPress */
|
||||
quickPressLoad = function() {
|
||||
var act = $('#quickpost-action'), t;
|
||||
|
||||
$( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );
|
||||
|
||||
t = $('#quick-press').submit( function( e ) {
|
||||
e.preventDefault();
|
||||
$('#dashboard_quick_press #publishing-action .spinner').show();
|
||||
$('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);
|
||||
|
||||
$.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();
|
||||
$('#title').focus();
|
||||
});
|
||||
|
||||
function highlightLatestPost () {
|
||||
var latestPost = $('.drafts ul li').first();
|
||||
latestPost.css('background', '#fffbe5');
|
||||
setTimeout(function () {
|
||||
latestPost.css('background', 'none');
|
||||
}, 1000);
|
||||
}
|
||||
} );
|
||||
|
||||
$('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );
|
||||
|
||||
$('#title, #tags-input, #content').each( function() {
|
||||
var input = $(this), prompt = $('#' + this.id + '-prompt-text');
|
||||
|
||||
if ( '' === this.value ) {
|
||||
prompt.removeClass('screen-reader-text');
|
||||
}
|
||||
|
||||
prompt.click( function() {
|
||||
$(this).addClass('screen-reader-text');
|
||||
input.focus();
|
||||
});
|
||||
|
||||
input.blur( function() {
|
||||
if ( '' === this.value ) {
|
||||
prompt.removeClass('screen-reader-text');
|
||||
}
|
||||
});
|
||||
|
||||
input.focus( function() {
|
||||
prompt.addClass('screen-reader-text');
|
||||
});
|
||||
});
|
||||
|
||||
$('#quick-press').on( 'click focusin', function() {
|
||||
wpActiveEditor = 'content';
|
||||
});
|
||||
|
||||
autoResizeTextarea();
|
||||
};
|
||||
quickPressLoad();
|
||||
|
||||
$( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );
|
||||
|
||||
function autoResizeTextarea() {
|
||||
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'
|
||||
});
|
||||
|
||||
// propertychange is for IE < 9
|
||||
editor.on('focus input propertychange', function() {
|
||||
var $this = $(this),
|
||||
// is to ensure that the height of a final trailing newline is included.
|
||||
textareaContent = $this.val() + ' ',
|
||||
// 2px is for border-top & border-bottom
|
||||
cloneHeight = clone.css('width', $this.css('width')).text(textareaContent).outerHeight() + 2;
|
||||
|
||||
// Default to having scrollbars
|
||||
editor.css('overflow-y', 'auto');
|
||||
|
||||
// Only change the height if it has indeed changed and both heights are below the max.
|
||||
if ( cloneHeight === editorHeight || ( cloneHeight >= editorMaxHeight && editorHeight >= editorMaxHeight ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't allow editor to exceed height of 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;
|
||||
}
|
||||
|
||||
// No scrollbars as we change height, not for IE < 9
|
||||
editor.css('overflow', 'hidden');
|
||||
|
||||
$this.css('height', editorHeight + 'px');
|
||||
});
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
jQuery( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var communityEventsData = window.communityEventsData || {},
|
||||
app;
|
||||
|
||||
app = window.wp.communityEvents = {
|
||||
initialized: false,
|
||||
model: null,
|
||||
|
||||
/**
|
||||
* Initializes the wp.communityEvents object.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
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 );
|
||||
|
||||
$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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
976
wp-admin/js/edit-comments.js
Normal file
976
wp-admin/js/edit-comments.js
Normal file
|
|
@ -0,0 +1,976 @@
|
|||
/* global adminCommentsL10n, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */
|
||||
var setCommentsList, theList, theExtraList, commentReply;
|
||||
|
||||
(function($) {
|
||||
var getCount, updateCount, updateCountText, updatePending, updateApproved,
|
||||
updateHtmlTitle, updateDashboardText, adminTitle = document.title,
|
||||
isDashboard = $('#dashboard_right_now').length,
|
||||
titleDiv, titleRegEx;
|
||||
|
||||
getCount = function(el) {
|
||||
var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 );
|
||||
if ( isNaN(n) ) {
|
||||
return 0;
|
||||
}
|
||||
return n;
|
||||
};
|
||||
|
||||
updateCount = function(el, n) {
|
||||
var n1 = '';
|
||||
if ( isNaN(n) ) {
|
||||
return;
|
||||
}
|
||||
n = n < 1 ? '0' : n.toString();
|
||||
if ( n.length > 3 ) {
|
||||
while ( n.length > 3 ) {
|
||||
n1 = thousandsSeparator + n.substr(n.length - 3) + n1;
|
||||
n = n.substr(0, n.length - 3);
|
||||
}
|
||||
n = n + n1;
|
||||
}
|
||||
el.html(n);
|
||||
};
|
||||
|
||||
updateApproved = function( diff, commentPostId ) {
|
||||
var postSelector = '.post-com-count-' + commentPostId,
|
||||
noClass = 'comment-count-no-comments',
|
||||
approvedClass = 'comment-count-approved',
|
||||
approved,
|
||||
noComments;
|
||||
|
||||
updateCountText( 'span.approved-count', diff );
|
||||
|
||||
if ( ! commentPostId ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cache selectors to not get dupes
|
||||
approved = $( 'span.' + approvedClass, postSelector );
|
||||
noComments = $( 'span.' + noClass, postSelector );
|
||||
|
||||
approved.each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
|
||||
if ( 0 === n ) {
|
||||
a.removeClass( approvedClass ).addClass( noClass );
|
||||
} else {
|
||||
a.addClass( approvedClass ).removeClass( noClass );
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
noComments.each(function() {
|
||||
var a = $(this);
|
||||
if ( diff > 0 ) {
|
||||
a.removeClass( noClass ).addClass( approvedClass );
|
||||
} else {
|
||||
a.addClass( noClass ).removeClass( approvedClass );
|
||||
}
|
||||
updateCount( a, diff );
|
||||
});
|
||||
};
|
||||
|
||||
updateCountText = function( selector, diff ) {
|
||||
$( selector ).each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 ) {
|
||||
n = 0;
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
};
|
||||
|
||||
updateDashboardText = function ( response ) {
|
||||
if ( ! isDashboard || ! response || ! response.i18n_comments_text ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rightNow = $( '#dashboard_right_now' );
|
||||
|
||||
$( '.comment-count a', rightNow ).text( response.i18n_comments_text );
|
||||
$( '.comment-mod-count a', rightNow ).text( response.i18n_moderation_text )
|
||||
.parent()
|
||||
[ response.in_moderation > 0 ? 'removeClass' : 'addClass' ]( 'hidden' );
|
||||
};
|
||||
|
||||
updateHtmlTitle = function ( diff ) {
|
||||
var newTitle, regExMatch, titleCount, commentFrag;
|
||||
|
||||
titleRegEx = titleRegEx || new RegExp( adminCommentsL10n.docTitleCommentsCount.replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' );
|
||||
// count funcs operate on a $'d element
|
||||
titleDiv = titleDiv || $( '<div />' );
|
||||
newTitle = adminTitle;
|
||||
|
||||
commentFrag = titleRegEx.exec( document.title );
|
||||
if ( commentFrag ) {
|
||||
commentFrag = commentFrag[0];
|
||||
titleDiv.html( commentFrag );
|
||||
titleCount = getCount( titleDiv ) + diff;
|
||||
} else {
|
||||
titleDiv.html( 0 );
|
||||
titleCount = diff;
|
||||
}
|
||||
|
||||
if ( titleCount >= 1 ) {
|
||||
updateCount( titleDiv, titleCount );
|
||||
regExMatch = titleRegEx.exec( document.title );
|
||||
if ( regExMatch ) {
|
||||
newTitle = document.title.replace( regExMatch[0], adminCommentsL10n.docTitleCommentsCount.replace( '%s', titleDiv.text() ) + ' ' );
|
||||
}
|
||||
} else {
|
||||
regExMatch = titleRegEx.exec( newTitle );
|
||||
if ( regExMatch ) {
|
||||
newTitle = newTitle.replace( regExMatch[0], adminCommentsL10n.docTitleComments );
|
||||
}
|
||||
}
|
||||
document.title = newTitle;
|
||||
};
|
||||
|
||||
updatePending = function( diff, commentPostId ) {
|
||||
var postSelector = '.post-com-count-' + commentPostId,
|
||||
noClass = 'comment-count-no-pending',
|
||||
noParentClass = 'post-com-count-no-pending',
|
||||
pendingClass = 'comment-count-pending',
|
||||
pending,
|
||||
noPending;
|
||||
|
||||
if ( ! isDashboard ) {
|
||||
updateHtmlTitle( diff );
|
||||
}
|
||||
|
||||
$( 'span.pending-count' ).each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
a.closest('.awaiting-mod')[ 0 === n ? 'addClass' : 'removeClass' ]('count-0');
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
if ( ! commentPostId ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cache selectors to not get dupes
|
||||
pending = $( 'span.' + pendingClass, postSelector );
|
||||
noPending = $( 'span.' + noClass, postSelector );
|
||||
|
||||
pending.each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
|
||||
if ( 0 === n ) {
|
||||
a.parent().addClass( noParentClass );
|
||||
a.removeClass( pendingClass ).addClass( noClass );
|
||||
} else {
|
||||
a.parent().removeClass( noParentClass );
|
||||
a.addClass( pendingClass ).removeClass( noClass );
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
noPending.each(function() {
|
||||
var a = $(this);
|
||||
if ( diff > 0 ) {
|
||||
a.parent().removeClass( noParentClass );
|
||||
a.removeClass( noClass ).addClass( pendingClass );
|
||||
} else {
|
||||
a.parent().addClass( noParentClass );
|
||||
a.addClass( noClass ).removeClass( pendingClass );
|
||||
}
|
||||
updateCount( a, diff );
|
||||
});
|
||||
};
|
||||
|
||||
setCommentsList = function() {
|
||||
var totalInput, perPageInput, pageInput, dimAfter, delBefore, updateTotalCount, delAfter, refillTheExtraList, diff,
|
||||
lastConfidentTime = 0;
|
||||
|
||||
totalInput = $('input[name="_total"]', '#comments-form');
|
||||
perPageInput = $('input[name="_per_page"]', '#comments-form');
|
||||
pageInput = $('input[name="_page"]', '#comments-form');
|
||||
|
||||
// Updates the current total (stored in the _total input)
|
||||
updateTotalCount = function( total, time, setConfidentTime ) {
|
||||
if ( time < lastConfidentTime )
|
||||
return;
|
||||
|
||||
if ( setConfidentTime )
|
||||
lastConfidentTime = time;
|
||||
|
||||
totalInput.val( total.toString() );
|
||||
};
|
||||
|
||||
// this fires when viewing "All"
|
||||
dimAfter = function( r, settings ) {
|
||||
var editRow, replyID, replyButton, response,
|
||||
c = $( '#' + settings.element );
|
||||
|
||||
if ( true !== settings.parsed ) {
|
||||
response = settings.parsed.responses[0];
|
||||
}
|
||||
|
||||
editRow = $('#replyrow');
|
||||
replyID = $('#comment_ID', editRow).val();
|
||||
replyButton = $('#replybtn', editRow);
|
||||
|
||||
if ( c.is('.unapproved') ) {
|
||||
if ( settings.data.id == replyID )
|
||||
replyButton.text(adminCommentsL10n.replyApprove);
|
||||
|
||||
c.find( '.row-actions span.view' ).addClass( 'hidden' ).end()
|
||||
.find( 'div.comment_status' ).html( '0' );
|
||||
|
||||
} else {
|
||||
if ( settings.data.id == replyID )
|
||||
replyButton.text(adminCommentsL10n.reply);
|
||||
|
||||
c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end()
|
||||
.find( 'div.comment_status' ).html( '1' );
|
||||
}
|
||||
|
||||
diff = $('#' + settings.element).is('.' + settings.dimClass) ? 1 : -1;
|
||||
if ( response ) {
|
||||
updateDashboardText( response.supplemental );
|
||||
updatePending( diff, response.supplemental.postId );
|
||||
updateApproved( -1 * diff, response.supplemental.postId );
|
||||
} else {
|
||||
updatePending( diff );
|
||||
updateApproved( -1 * diff );
|
||||
}
|
||||
};
|
||||
|
||||
// Send current total, page, per_page and url
|
||||
delBefore = function( settings, list ) {
|
||||
var note, id, el, n, h, a, author,
|
||||
action = false,
|
||||
wpListsData = $( settings.target ).attr( 'data-wp-lists' );
|
||||
|
||||
settings.data._total = totalInput.val() || 0;
|
||||
settings.data._per_page = perPageInput.val() || 0;
|
||||
settings.data._page = pageInput.val() || 0;
|
||||
settings.data._url = document.location.href;
|
||||
settings.data.comment_status = $('input[name="comment_status"]', '#comments-form').val();
|
||||
|
||||
if ( wpListsData.indexOf(':trash=1') != -1 )
|
||||
action = 'trash';
|
||||
else if ( wpListsData.indexOf(':spam=1') != -1 )
|
||||
action = 'spam';
|
||||
|
||||
if ( action ) {
|
||||
id = wpListsData.replace(/.*?comment-([0-9]+).*/, '$1');
|
||||
el = $('#comment-' + id);
|
||||
note = $('#' + action + '-undo-holder').html();
|
||||
|
||||
el.find('.check-column :checkbox').prop('checked', false); // Uncheck the row so as not to be affected by Bulk Edits.
|
||||
|
||||
if ( el.siblings('#replyrow').length && commentReply.cid == id )
|
||||
commentReply.close();
|
||||
|
||||
if ( el.is('tr') ) {
|
||||
n = el.children(':visible').length;
|
||||
author = $('.author strong', el).text();
|
||||
h = $('<tr id="undo-' + id + '" class="undo un' + action + '" style="display:none;"><td colspan="' + n + '">' + note + '</td></tr>');
|
||||
} else {
|
||||
author = $('.comment-author', el).text();
|
||||
h = $('<div id="undo-' + id + '" style="display:none;" class="undo un' + action + '">' + note + '</div>');
|
||||
}
|
||||
|
||||
el.before(h);
|
||||
|
||||
$('strong', '#undo-' + id).text(author);
|
||||
a = $('.undo a', '#undo-' + id);
|
||||
a.attr('href', 'comment.php?action=un' + action + 'comment&c=' + id + '&_wpnonce=' + settings.data._ajax_nonce);
|
||||
a.attr('data-wp-lists', 'delete:the-comment-list:comment-' + id + '::un' + action + '=1');
|
||||
a.attr('class', 'vim-z vim-destructive');
|
||||
$('.avatar', el).first().clone().prependTo('#undo-' + id + ' .' + action + '-undo-inside');
|
||||
|
||||
a.click(function( e ){
|
||||
e.preventDefault();
|
||||
e.stopPropagation(); // ticket #35904
|
||||
list.wpList.del(this);
|
||||
$('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){
|
||||
$(this).remove();
|
||||
$('#comment-' + id).css('backgroundColor', '').fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return settings;
|
||||
};
|
||||
|
||||
// In admin-ajax.php, we send back the unix time stamp instead of 1 on success
|
||||
delAfter = function( r, settings ) {
|
||||
var total_items_i18n, total, animated, animatedCallback,
|
||||
response = true === settings.parsed ? {} : settings.parsed.responses[0],
|
||||
commentStatus = true === settings.parsed ? '' : response.supplemental.status,
|
||||
commentPostId = true === settings.parsed ? '' : response.supplemental.postId,
|
||||
newTotal = true === settings.parsed ? '' : response.supplemental,
|
||||
|
||||
targetParent = $( settings.target ).parent(),
|
||||
commentRow = $('#' + settings.element),
|
||||
|
||||
spamDiff, trashDiff, pendingDiff, approvedDiff,
|
||||
|
||||
approved = commentRow.hasClass( 'approved' ),
|
||||
unapproved = commentRow.hasClass( 'unapproved' ),
|
||||
spammed = commentRow.hasClass( 'spam' ),
|
||||
trashed = commentRow.hasClass( 'trash' ),
|
||||
undoing = false; // ticket #35904
|
||||
|
||||
updateDashboardText( newTotal );
|
||||
|
||||
// the order of these checks is important
|
||||
// .unspam can also have .approve or .unapprove
|
||||
// .untrash can also have .approve or .unapprove
|
||||
|
||||
if ( targetParent.is( 'span.undo' ) ) {
|
||||
// the comment was spammed
|
||||
if ( targetParent.hasClass( 'unspam' ) ) {
|
||||
spamDiff = -1;
|
||||
|
||||
if ( 'trash' === commentStatus ) {
|
||||
trashDiff = 1;
|
||||
} else if ( '1' === commentStatus ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( '0' === commentStatus ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
|
||||
// the comment was trashed
|
||||
} else if ( targetParent.hasClass( 'untrash' ) ) {
|
||||
trashDiff = -1;
|
||||
|
||||
if ( 'spam' === commentStatus ) {
|
||||
spamDiff = 1;
|
||||
} else if ( '1' === commentStatus ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( '0' === commentStatus ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
|
||||
undoing = true;
|
||||
|
||||
// user clicked "Spam"
|
||||
} else if ( targetParent.is( 'span.spam' ) ) {
|
||||
// the comment is currently approved
|
||||
if ( approved ) {
|
||||
approvedDiff = -1;
|
||||
// the comment is currently pending
|
||||
} else if ( unapproved ) {
|
||||
pendingDiff = -1;
|
||||
// the comment was in the trash
|
||||
} else if ( trashed ) {
|
||||
trashDiff = -1;
|
||||
}
|
||||
// you can't spam an item on the spam screen
|
||||
spamDiff = 1;
|
||||
|
||||
// user clicked "Unspam"
|
||||
} else if ( targetParent.is( 'span.unspam' ) ) {
|
||||
if ( approved ) {
|
||||
pendingDiff = 1;
|
||||
} else if ( unapproved ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( trashed ) {
|
||||
// the comment was previously approved
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
// the comment was previously pending
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
} else if ( spammed ) {
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
// you can Unspam an item on the spam screen
|
||||
spamDiff = -1;
|
||||
|
||||
// user clicked "Trash"
|
||||
} else if ( targetParent.is( 'span.trash' ) ) {
|
||||
if ( approved ) {
|
||||
approvedDiff = -1;
|
||||
} else if ( unapproved ) {
|
||||
pendingDiff = -1;
|
||||
// the comment was in the spam queue
|
||||
} else if ( spammed ) {
|
||||
spamDiff = -1;
|
||||
}
|
||||
// you can't trash an item on the trash screen
|
||||
trashDiff = 1;
|
||||
|
||||
// user clicked "Restore"
|
||||
} else if ( targetParent.is( 'span.untrash' ) ) {
|
||||
if ( approved ) {
|
||||
pendingDiff = 1;
|
||||
} else if ( unapproved ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( trashed ) {
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
// you can't go from trash to spam
|
||||
// you can untrash on the trash screen
|
||||
trashDiff = -1;
|
||||
|
||||
// User clicked "Approve"
|
||||
} else if ( targetParent.is( 'span.approve:not(.unspam):not(.untrash)' ) ) {
|
||||
approvedDiff = 1;
|
||||
pendingDiff = -1;
|
||||
|
||||
// User clicked "Unapprove"
|
||||
} else if ( targetParent.is( 'span.unapprove:not(.unspam):not(.untrash)' ) ) {
|
||||
approvedDiff = -1;
|
||||
pendingDiff = 1;
|
||||
|
||||
// User clicked "Delete Permanently"
|
||||
} else if ( targetParent.is( 'span.delete' ) ) {
|
||||
if ( spammed ) {
|
||||
spamDiff = -1;
|
||||
} else if ( trashed ) {
|
||||
trashDiff = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pendingDiff ) {
|
||||
updatePending( pendingDiff, commentPostId );
|
||||
updateCountText( 'span.all-count', pendingDiff );
|
||||
}
|
||||
|
||||
if ( approvedDiff ) {
|
||||
updateApproved( approvedDiff, commentPostId );
|
||||
updateCountText( 'span.all-count', approvedDiff );
|
||||
}
|
||||
|
||||
if ( spamDiff ) {
|
||||
updateCountText( 'span.spam-count', spamDiff );
|
||||
}
|
||||
|
||||
if ( trashDiff ) {
|
||||
updateCountText( 'span.trash-count', trashDiff );
|
||||
}
|
||||
|
||||
if (
|
||||
( ( 'trash' === settings.data.comment_status ) && !getCount( $( 'span.trash-count' ) ) ) ||
|
||||
( ( 'spam' === settings.data.comment_status ) && !getCount( $( 'span.spam-count' ) ) )
|
||||
) {
|
||||
$( '#delete_all' ).hide();
|
||||
}
|
||||
|
||||
if ( ! isDashboard ) {
|
||||
total = totalInput.val() ? parseInt( totalInput.val(), 10 ) : 0;
|
||||
if ( $(settings.target).parent().is('span.undo') )
|
||||
total++;
|
||||
else
|
||||
total--;
|
||||
|
||||
if ( total < 0 )
|
||||
total = 0;
|
||||
|
||||
if ( 'object' === typeof r ) {
|
||||
if ( response.supplemental.total_items_i18n && lastConfidentTime < response.supplemental.time ) {
|
||||
total_items_i18n = response.supplemental.total_items_i18n || '';
|
||||
if ( total_items_i18n ) {
|
||||
$('.displaying-num').text( total_items_i18n );
|
||||
$('.total-pages').text( response.supplemental.total_pages_i18n );
|
||||
$('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', response.supplemental.total_pages == $('.current-page').val());
|
||||
}
|
||||
updateTotalCount( total, response.supplemental.time, true );
|
||||
} else if ( response.supplemental.time ) {
|
||||
updateTotalCount( total, response.supplemental.time, false );
|
||||
}
|
||||
} else {
|
||||
updateTotalCount( total, r, false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! theExtraList || theExtraList.length === 0 || theExtraList.children().length === 0 || undoing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
theList.get(0).wpList.add( theExtraList.children( ':eq(0):not(.no-items)' ).remove().clone() );
|
||||
|
||||
refillTheExtraList();
|
||||
|
||||
animated = $( ':animated', '#the-comment-list' );
|
||||
animatedCallback = function () {
|
||||
if ( ! $( '#the-comment-list tr:visible' ).length ) {
|
||||
theList.get(0).wpList.add( theExtraList.find( '.no-items' ).clone() );
|
||||
}
|
||||
};
|
||||
|
||||
if ( animated.length ) {
|
||||
animated.promise().done( animatedCallback );
|
||||
} else {
|
||||
animatedCallback();
|
||||
}
|
||||
};
|
||||
|
||||
refillTheExtraList = function(ev) {
|
||||
var args = $.query.get(), total_pages = $('.total-pages').text(), per_page = $('input[name="_per_page"]', '#comments-form').val();
|
||||
|
||||
if (! args.paged)
|
||||
args.paged = 1;
|
||||
|
||||
if (args.paged > total_pages) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev) {
|
||||
theExtraList.empty();
|
||||
args.number = Math.min(8, per_page); // see WP_Comments_List_Table::prepare_items() @ class-wp-comments-list-table.php
|
||||
} else {
|
||||
args.number = 1;
|
||||
args.offset = Math.min(8, per_page) - 1; // fetch only the next item on the extra list
|
||||
}
|
||||
|
||||
args.no_placeholder = true;
|
||||
|
||||
args.paged ++;
|
||||
|
||||
// $.query.get() needs some correction to be sent into an ajax request
|
||||
if ( true === args.comment_type )
|
||||
args.comment_type = '';
|
||||
|
||||
args = $.extend(args, {
|
||||
'action': 'fetch-list',
|
||||
'list_args': list_args,
|
||||
'_ajax_fetch_list_nonce': $('#_ajax_fetch_list_nonce').val()
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
global: false,
|
||||
dataType: 'json',
|
||||
data: args,
|
||||
success: function(response) {
|
||||
theExtraList.get(0).wpList.add( response.rows );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } );
|
||||
theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } )
|
||||
.bind('wpListDelEnd', function(e, s){
|
||||
var wpListsData = $(s.target).attr('data-wp-lists'), id = s.element.replace(/[^0-9]+/g, '');
|
||||
|
||||
if ( wpListsData.indexOf(':trash=1') != -1 || wpListsData.indexOf(':spam=1') != -1 )
|
||||
$('#undo-' + id).fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
};
|
||||
|
||||
commentReply = {
|
||||
cid : '',
|
||||
act : '',
|
||||
originalContent : '',
|
||||
|
||||
init : function() {
|
||||
var row = $('#replyrow');
|
||||
|
||||
$('a.cancel', row).click(function() { return commentReply.revert(); });
|
||||
$('a.save', row).click(function() { return commentReply.send(); });
|
||||
$( 'input#author-name, input#author-email, input#author-url', row ).keypress( function( e ) {
|
||||
if ( e.which == 13 ) {
|
||||
commentReply.send();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// add events
|
||||
$('#the-comment-list .column-comment > p').dblclick(function(){
|
||||
commentReply.toggle($(this).parent());
|
||||
});
|
||||
|
||||
$('#doaction, #doaction2, #post-query-submit').click(function(){
|
||||
if ( $('#the-comment-list #replyrow').length > 0 )
|
||||
commentReply.close();
|
||||
});
|
||||
|
||||
this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || '';
|
||||
|
||||
/* $(listTable).bind('beforeChangePage', function(){
|
||||
commentReply.close();
|
||||
}); */
|
||||
},
|
||||
|
||||
addEvents : function(r) {
|
||||
r.each(function() {
|
||||
$(this).find('.column-comment > p').dblclick(function(){
|
||||
commentReply.toggle($(this).parent());
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
toggle : function(el) {
|
||||
if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( adminCommentsL10n.warnQuickEdit ) ) ) {
|
||||
$( el ).find( 'a.vim-q' ).click();
|
||||
}
|
||||
},
|
||||
|
||||
revert : function() {
|
||||
|
||||
if ( $('#the-comment-list #replyrow').length < 1 )
|
||||
return false;
|
||||
|
||||
$('#replyrow').fadeOut('fast', function(){
|
||||
commentReply.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close : function() {
|
||||
var c, replyrow = $('#replyrow');
|
||||
|
||||
// replyrow is not showing?
|
||||
if ( replyrow.parent().is('#com-reply') )
|
||||
return;
|
||||
|
||||
if ( this.cid && this.act == 'edit-comment' ) {
|
||||
c = $('#comment-' + this.cid);
|
||||
c.fadeIn(300, function(){ c.show(); }).css('backgroundColor', '');
|
||||
}
|
||||
|
||||
// reset the Quicktags buttons
|
||||
if ( typeof QTags != 'undefined' )
|
||||
QTags.closeAllTags('replycontent');
|
||||
|
||||
$('#add-new-comment').css('display', '');
|
||||
|
||||
replyrow.hide();
|
||||
$('#com-reply').append( replyrow );
|
||||
$('#replycontent').css('height', '').val('');
|
||||
$('#edithead input').val('');
|
||||
$( '.notice-error', replyrow )
|
||||
.addClass( 'hidden' )
|
||||
.find( '.error' ).empty();
|
||||
$( '.spinner', replyrow ).removeClass( 'is-active' );
|
||||
|
||||
this.cid = '';
|
||||
this.originalContent = '';
|
||||
},
|
||||
|
||||
open : function(comment_id, post_id, action) {
|
||||
var editRow, rowData, act, replyButton, editHeight,
|
||||
t = this,
|
||||
c = $('#comment-' + comment_id),
|
||||
h = c.height(),
|
||||
colspanVal = 0;
|
||||
|
||||
if ( ! this.discardCommentChanges() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
t.close();
|
||||
t.cid = comment_id;
|
||||
|
||||
editRow = $('#replyrow');
|
||||
rowData = $('#inline-'+comment_id);
|
||||
action = action || 'replyto';
|
||||
act = 'edit' == action ? 'edit' : 'replyto';
|
||||
act = t.act = act + '-comment';
|
||||
t.originalContent = $('textarea.comment', rowData).val();
|
||||
colspanVal = $( '> th:visible, > td:visible', c ).length;
|
||||
|
||||
// Make sure it's actually a table and there's a `colspan` value to apply.
|
||||
if ( editRow.hasClass( 'inline-edit-row' ) && 0 !== colspanVal ) {
|
||||
$( 'td', editRow ).attr( 'colspan', colspanVal );
|
||||
}
|
||||
|
||||
$('#action', editRow).val(act);
|
||||
$('#comment_post_ID', editRow).val(post_id);
|
||||
$('#comment_ID', editRow).val(comment_id);
|
||||
|
||||
if ( action == 'edit' ) {
|
||||
$( '#author-name', editRow ).val( $( 'div.author', rowData ).text() );
|
||||
$('#author-email', editRow).val( $('div.author-email', rowData).text() );
|
||||
$('#author-url', editRow).val( $('div.author-url', rowData).text() );
|
||||
$('#status', editRow).val( $('div.comment_status', rowData).text() );
|
||||
$('#replycontent', editRow).val( $('textarea.comment', rowData).val() );
|
||||
$( '#edithead, #editlegend, #savebtn', editRow ).show();
|
||||
$('#replyhead, #replybtn, #addhead, #addbtn', editRow).hide();
|
||||
|
||||
if ( h > 120 ) {
|
||||
// Limit the maximum height when editing very long comments to make it more manageable.
|
||||
// The textarea is resizable in most browsers, so the user can adjust it if needed.
|
||||
editHeight = h > 500 ? 500 : h;
|
||||
$('#replycontent', editRow).css('height', editHeight + 'px');
|
||||
}
|
||||
|
||||
c.after( editRow ).fadeOut('fast', function(){
|
||||
$('#replyrow').fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
} else if ( action == 'add' ) {
|
||||
$('#addhead, #addbtn', editRow).show();
|
||||
$( '#replyhead, #replybtn, #edithead, #editlegend, #savebtn', editRow ) .hide();
|
||||
$('#the-comment-list').prepend(editRow);
|
||||
$('#replyrow').fadeIn(300);
|
||||
} else {
|
||||
replyButton = $('#replybtn', editRow);
|
||||
$( '#edithead, #editlegend, #savebtn, #addhead, #addbtn', editRow ).hide();
|
||||
$('#replyhead, #replybtn', editRow).show();
|
||||
c.after(editRow);
|
||||
|
||||
if ( c.hasClass('unapproved') ) {
|
||||
replyButton.text(adminCommentsL10n.replyApprove);
|
||||
} else {
|
||||
replyButton.text(adminCommentsL10n.reply);
|
||||
}
|
||||
|
||||
$('#replyrow').fadeIn(300, function(){ $(this).show(); });
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
var rtop, rbottom, scrollTop, vp, scrollBottom;
|
||||
|
||||
rtop = $('#replyrow').offset().top;
|
||||
rbottom = rtop + $('#replyrow').height();
|
||||
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
vp = document.documentElement.clientHeight || window.innerHeight || 0;
|
||||
scrollBottom = scrollTop + vp;
|
||||
|
||||
if ( scrollBottom - 20 < rbottom )
|
||||
window.scroll(0, rbottom - vp + 35);
|
||||
else if ( rtop - 20 < scrollTop )
|
||||
window.scroll(0, rtop - 35);
|
||||
|
||||
$('#replycontent').focus().keyup(function(e){
|
||||
if ( e.which == 27 )
|
||||
commentReply.revert(); // close on Escape
|
||||
});
|
||||
}, 600);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
send : function() {
|
||||
var post = {},
|
||||
$errorNotice = $( '#replysubmit .error-notice' );
|
||||
|
||||
$errorNotice.addClass( 'hidden' );
|
||||
$( '#replysubmit .spinner' ).addClass( 'is-active' );
|
||||
|
||||
$('#replyrow input').not(':button').each(function() {
|
||||
var t = $(this);
|
||||
post[ t.attr('name') ] = t.val();
|
||||
});
|
||||
|
||||
post.content = $('#replycontent').val();
|
||||
post.id = post.comment_post_ID;
|
||||
post.comments_listing = this.comments_listing;
|
||||
post.p = $('[name="p"]').val();
|
||||
|
||||
if ( $('#comment-' + $('#comment_ID').val()).hasClass('unapproved') )
|
||||
post.approve_parent = 1;
|
||||
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : ajaxurl,
|
||||
data : post,
|
||||
success : function(x) { commentReply.show(x); },
|
||||
error : function(r) { commentReply.error(r); }
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
show : function(xml) {
|
||||
var t = this, r, c, id, bg, pid;
|
||||
|
||||
if ( typeof(xml) == 'string' ) {
|
||||
t.error({'responseText': xml});
|
||||
return false;
|
||||
}
|
||||
|
||||
r = wpAjax.parseAjaxResponse(xml);
|
||||
if ( r.errors ) {
|
||||
t.error({'responseText': wpAjax.broken});
|
||||
return false;
|
||||
}
|
||||
|
||||
t.revert();
|
||||
|
||||
r = r.responses[0];
|
||||
id = '#comment-' + r.id;
|
||||
|
||||
if ( 'edit-comment' == t.act )
|
||||
$(id).remove();
|
||||
|
||||
if ( r.supplemental.parent_approved ) {
|
||||
pid = $('#comment-' + r.supplemental.parent_approved);
|
||||
updatePending( -1, r.supplemental.parent_post_id );
|
||||
|
||||
if ( this.comments_listing == 'moderated' ) {
|
||||
pid.animate( { 'backgroundColor':'#CCEEBB' }, 400, function(){
|
||||
pid.fadeOut();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( r.supplemental.i18n_comments_text ) {
|
||||
if ( isDashboard ) {
|
||||
updateDashboardText( r.supplemental );
|
||||
} else {
|
||||
updateApproved( 1, r.supplemental.parent_post_id );
|
||||
updateCountText( 'span.all-count', 1 );
|
||||
}
|
||||
}
|
||||
|
||||
c = $.trim(r.data); // Trim leading whitespaces
|
||||
$(c).hide();
|
||||
$('#replyrow').after(c);
|
||||
|
||||
id = $(id);
|
||||
t.addEvents(id);
|
||||
bg = id.hasClass('unapproved') ? '#FFFFE0' : id.closest('.widefat, .postbox').css('backgroundColor');
|
||||
|
||||
id.animate( { 'backgroundColor':'#CCEEBB' }, 300 )
|
||||
.animate( { 'backgroundColor': bg }, 300, function() {
|
||||
if ( pid && pid.length ) {
|
||||
pid.animate( { 'backgroundColor':'#CCEEBB' }, 300 )
|
||||
.animate( { 'backgroundColor': bg }, 300 )
|
||||
.removeClass('unapproved').addClass('approved')
|
||||
.find('div.comment_status').html('1');
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error : function(r) {
|
||||
var er = r.statusText,
|
||||
$errorNotice = $( '#replysubmit .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( '#replysubmit .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
if ( r.responseText )
|
||||
er = r.responseText.replace( /<.[^<>]*?>/g, '' );
|
||||
|
||||
if ( er ) {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( er );
|
||||
}
|
||||
},
|
||||
|
||||
addcomment: function(post_id) {
|
||||
var t = this;
|
||||
|
||||
$('#add-new-comment').fadeOut(200, function(){
|
||||
t.open(0, post_id, 'add');
|
||||
$('table.comments-box').css('display', '');
|
||||
$('#no-comments').remove();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Alert the user if they have unsaved changes on a comment that will be
|
||||
* lost if they proceed.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
discardCommentChanges: function() {
|
||||
var editRow = $( '#replyrow' );
|
||||
|
||||
if ( this.originalContent === $( '#replycontent', editRow ).val() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return window.confirm( adminCommentsL10n.warnCommentChanges );
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
var make_hotkeys_redirect, edit_comment, toggle_all, make_bulk;
|
||||
|
||||
setCommentsList();
|
||||
commentReply.init();
|
||||
|
||||
$(document).on( 'click', 'span.delete a.delete', function( e ) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if ( typeof $.table_hotkeys != 'undefined' ) {
|
||||
make_hotkeys_redirect = function(which) {
|
||||
return function() {
|
||||
var first_last, l;
|
||||
|
||||
first_last = 'next' == which? 'first' : 'last';
|
||||
l = $('.tablenav-pages .'+which+'-page:not(.disabled)');
|
||||
if (l.length)
|
||||
window.location = l[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g, '')+'&hotkeys_highlight_'+first_last+'=1';
|
||||
};
|
||||
};
|
||||
|
||||
edit_comment = function(event, current_row) {
|
||||
window.location = $('span.edit a', current_row).attr('href');
|
||||
};
|
||||
|
||||
toggle_all = function() {
|
||||
$('#cb-select-all-1').data( 'wp-toggle', 1 ).trigger( 'click' ).removeData( 'wp-toggle' );
|
||||
};
|
||||
|
||||
make_bulk = function(value) {
|
||||
return function() {
|
||||
var scope = $('select[name="action"]');
|
||||
$('option[value="' + value + '"]', scope).prop('selected', true);
|
||||
$('#doaction').click();
|
||||
};
|
||||
};
|
||||
|
||||
$.table_hotkeys(
|
||||
$('table.widefat'),
|
||||
[
|
||||
'a', 'u', 's', 'd', 'r', 'q', 'z',
|
||||
['e', edit_comment],
|
||||
['shift+x', toggle_all],
|
||||
['shift+a', make_bulk('approve')],
|
||||
['shift+s', make_bulk('spam')],
|
||||
['shift+d', make_bulk('delete')],
|
||||
['shift+t', make_bulk('trash')],
|
||||
['shift+z', make_bulk('untrash')],
|
||||
['shift+u', make_bulk('unapprove')]
|
||||
],
|
||||
{
|
||||
highlight_first: adminCommentsL10n.hotkeys_highlight_first,
|
||||
highlight_last: adminCommentsL10n.hotkeys_highlight_last,
|
||||
prev_page_link_cb: make_hotkeys_redirect('prev'),
|
||||
next_page_link_cb: make_hotkeys_redirect('next'),
|
||||
hotkeys_opts: {
|
||||
disableInInput: true,
|
||||
type: 'keypress',
|
||||
noDisable: '.check-column input[type="checkbox"]'
|
||||
},
|
||||
cycle_expr: '#the-comment-list tr',
|
||||
start_row_index: 0
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Quick Edit and Reply have an inline comment editor.
|
||||
$( '#the-comment-list' ).on( 'click', '.comment-inline', function (e) {
|
||||
e.preventDefault();
|
||||
var $el = $( this ),
|
||||
action = 'replyto';
|
||||
|
||||
if ( 'undefined' !== typeof $el.data( 'action' ) ) {
|
||||
action = $el.data( 'action' );
|
||||
}
|
||||
|
||||
commentReply.open( $el.data( 'commentId' ), $el.data( 'postId' ), action );
|
||||
} );
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
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
1604
wp-admin/js/editor-expand.js
Normal file
1604
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
1409
wp-admin/js/editor.js
Normal file
1409
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);
|
||||
237
wp-admin/js/gallery.js
Normal file
237
wp-admin/js/gallery.js
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/* global unescape, getUserSetting, setUserSetting */
|
||||
|
||||
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 () { tinymce = tinyMCE = wpgallery = null; } ); // Cleanup
|
||||
|
||||
/* gallery settings */
|
||||
var tinymce = null, tinyMCE, wpgallery;
|
||||
|
||||
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
|
||||
tinymce = w.tinymce;
|
||||
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(a){var b,c,d,e,f,g=!1;c=function(){b=a("#media-items").sortable({items:"div.media-item",placeholder:"sorthelper",axis:"y",distance:2,handle:"div.filename",stop:function(){var b=a("#media-items").sortable("toArray"),c=b.length;a.each(b,function(b,d){var e=g?c-b:1+b;a("#"+d+" .menu_order input").val(e)})}})},d=function(){var b=a(".menu_order_input"),c=b.length;b.each(function(b){var d=g?c-b:1+b;a(this).val(d)})},e=function(b){b=b||0,a(".menu_order_input").each(function(){("0"===this.value||b)&&(this.value="")})},a("#asc").click(function(a){a.preventDefault(),g=!1,d()}),a("#desc").click(function(a){a.preventDefault(),g=!0,d()}),a("#clear").click(function(a){a.preventDefault(),e(1)}),a("#showall").click(function(b){b.preventDefault(),a("#sort-buttons span a").toggle(),a("a.describe-toggle-on").hide(),a("a.describe-toggle-off, table.slidetoggle").show(),a("img.pinkynail").toggle(!1)}),a("#hideall").click(function(b){b.preventDefault(),a("#sort-buttons span a").toggle(),a("a.describe-toggle-on").show(),a("a.describe-toggle-off, table.slidetoggle").hide(),a("img.pinkynail").toggle(!0)}),c(),e(),a("#media-items>*").length>1&&(f=wpgallery.getWin(),a("#save-all, #gallery-settings").show(),"undefined"!=typeof f.tinyMCE&&f.tinyMCE.activeEditor&&!f.tinyMCE.activeEditor.isHidden()?(wpgallery.mcemode=!0,wpgallery.init()):a("#insert-gallery").show())}),jQuery(window).unload(function(){tinymce=tinyMCE=wpgallery=null});var tinymce=null,tinyMCE,wpgallery;wpgallery={mcemode:!1,editor:{},dom:{},is_update:!1,el:{},I:function(a){return document.getElementById(a)},init:function(){var a,b,c,d,e=this,f=e.getWin();if(e.mcemode){for(a=(""+document.location.search).replace(/^\?/,"").split("&"),b={},c=0;c<a.length;c++)d=a[c].split("="),b[unescape(d[0])]=unescape(d[1]);b.mce_rdomain&&(document.domain=b.mce_rdomain),tinymce=f.tinymce,tinyMCE=f.tinyMCE,e.editor=tinymce.EditorManager.activeEditor,e.setup()}},getWin:function(){return window.dialogArguments||opener||parent||top},setup:function(){var a,b,c,d,e,f,g=this,h=g.editor;if(g.mcemode){if(g.el=h.selection.getNode(),"IMG"!==g.el.nodeName||!h.dom.hasClass(g.el,"wpGallery")){if(!(b=h.dom.select("img.wpGallery"))||!b[0])return"1"===getUserSetting("galfile")&&(g.I("linkto-file").checked="checked"),"1"===getUserSetting("galdesc")&&(g.I("order-desc").checked="checked"),getUserSetting("galcols")&&(g.I("columns").value=getUserSetting("galcols")),getUserSetting("galord")&&(g.I("orderby").value=getUserSetting("galord")),void jQuery("#insert-gallery").show();g.el=b[0]}a=h.dom.getAttrib(g.el,"title"),a=h.dom.decode(a),a?(jQuery("#update-gallery").show(),g.is_update=!0,c=a.match(/columns=['"]([0-9]+)['"]/),d=a.match(/link=['"]([^'"]+)['"]/i),e=a.match(/order=['"]([^'"]+)['"]/i),f=a.match(/orderby=['"]([^'"]+)['"]/i),d&&d[1]&&(g.I("linkto-file").checked="checked"),e&&e[1]&&(g.I("order-desc").checked="checked"),c&&c[1]&&(g.I("columns").value=""+c[1]),f&&f[1]&&(g.I("orderby").value=f[1])):jQuery("#insert-gallery").show()}},update:function(){var a,b=this,c=b.editor,d="";return b.mcemode&&b.is_update?void("IMG"===b.el.nodeName&&(d=c.dom.decode(c.dom.getAttrib(b.el,"title")),d=d.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi,""),d+=b.getSettings(),c.dom.setAttrib(b.el,"title",d),b.getWin().tb_remove())):(a="[gallery"+b.getSettings()+"]",void b.getWin().send_to_editor(a))},getSettings:function(){var a=this.I,b="";return a("linkto-file").checked&&(b+=' link="file"',setUserSetting("galfile","1")),a("order-desc").checked&&(b+=' order="DESC"',setUserSetting("galdesc","1")),3!==a("columns").value&&(b+=' columns="'+a("columns").value+'"',setUserSetting("galcols",a("columns").value)),"menu_order"!==a("orderby").value&&(b+=' orderby="'+a("orderby").value+'"',setUserSetting("galord",a("orderby").value)),b}};
|
||||
1092
wp-admin/js/image-edit.js
Normal file
1092
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
553
wp-admin/js/inline-edit-post.js
Normal file
553
wp-admin/js/inline-edit-post.js
Normal file
|
|
@ -0,0 +1,553 @@
|
|||
/* global inlineEditL10n, ajaxurl, typenow */
|
||||
/**
|
||||
* This file contains the functions needed for the inline editing of posts.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Manages the quick edit and bulk edit windows for editing posts or pages.
|
||||
*
|
||||
* @namespace
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @type {Object}
|
||||
*
|
||||
* @property {string} type The type of inline editor.
|
||||
* @property {string} what The prefix before the post id.
|
||||
*
|
||||
*/
|
||||
var inlineEditPost;
|
||||
( function( $, wp ) {
|
||||
|
||||
inlineEditPost = {
|
||||
|
||||
/**
|
||||
* @summary 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-';
|
||||
|
||||
/**
|
||||
* @summary Bind 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Bind 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Revert 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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Save 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);
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Revert 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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Bind click event to the .editinline link which opens the quick editor.
|
||||
*/
|
||||
$('#the-list').on( 'click', 'a.editinline', function( e ) {
|
||||
e.preventDefault();
|
||||
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();
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Toggles the quick edit window.
|
||||
*
|
||||
* Hides the window when it's active and shows the window 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 );
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
|
||||
/**
|
||||
* @summary Create a HTML div with the title and a delete link(cross-icon) for each selected post.
|
||||
*
|
||||
* Get the selected posts based on the checked checkboxes in the post table.
|
||||
* Create a HTML div with the title and a link(delete-icon) for each selected post.
|
||||
*/
|
||||
$( '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);
|
||||
/**
|
||||
* @summary 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' );
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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);
|
||||
|
||||
/**
|
||||
* @summary 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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary 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(','));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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;
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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 link. $( this ) is the row being animated.
|
||||
$( this ).find( '.editinline' ).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;
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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 link.
|
||||
$( this.what + id ).show().find( '.editinline' ).focus();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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') ) {
|
||||
// Make room for the CSS animation
|
||||
row.removeClass('wp-locked').delay(1000).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
290
wp-admin/js/inline-edit-tax.js
Normal file
290
wp-admin/js/inline-edit-tax.js
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/* global inlineEditL10n, ajaxurl */
|
||||
/**
|
||||
* This file is used on the term overview page to power quick-editing terms.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
var inlineEditTax;
|
||||
|
||||
( function( $, wp ) {
|
||||
|
||||
inlineEditTax = {
|
||||
|
||||
/**
|
||||
* @summary Initializes the inline taxonomy editor.
|
||||
*
|
||||
* Adds 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', 'a.editinline', function(){
|
||||
inlineEditTax.edit(this);
|
||||
return false;
|
||||
});
|
||||
|
||||
/*
|
||||
* @summary 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Cancels inline editing when clicking the cancel button.
|
||||
*/
|
||||
$( '.cancel', row ).click( function() {
|
||||
return inlineEditTax.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Saves the inline edits when clicking the save button.
|
||||
*/
|
||||
$( '.save', row ).click( function() {
|
||||
return inlineEditTax.save(this);
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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 );
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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;
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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,
|
||||
/**
|
||||
* @summary 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 link.
|
||||
row.find( '.editinline' ).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 link.
|
||||
$( this.what + id ).show().find( '.editinline' ).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||{};var inlineEditTax;!function(a,b){inlineEditTax={init:function(){var b=this,c=a("#inline-edit");b.type=a("#the-list").attr("data-wp-lists").substr(5),b.what="#"+b.type+"-",a("#the-list").on("click","a.editinline",function(){return inlineEditTax.edit(this),!1}),c.keyup(function(a){if(27===a.which)return inlineEditTax.revert()}),a(".cancel",c).click(function(){return inlineEditTax.revert()}),a(".save",c).click(function(){return inlineEditTax.save(this)}),a("input, select",c).keydown(function(a){if(13===a.which)return inlineEditTax.save(this)}),a('#posts-filter input[type="submit"]').mousedown(function(){b.revert()})},toggle:function(b){var c=this;"none"===a(c.what+c.getId(b)).css("display")?c.revert():c.edit(b)},edit:function(b){var c,d,e,f=this;return f.revert(),"object"==typeof b&&(b=f.getId(b)),c=a("#inline-edit").clone(!0),d=a("#inline_"+b),a("td",c).attr("colspan",a("th:visible, td:visible",".wp-list-table.widefat:first thead").length),a(f.what+b).hide().after(c).after('<tr class="hidden"></tr>'),e=a(".name",d),e.find("img").replaceWith(function(){return this.alt}),e=e.text(),a(':input[name="name"]',c).val(e),e=a(".slug",d),e.find("img").replaceWith(function(){return this.alt}),e=e.text(),a(':input[name="slug"]',c).val(e),a(c).attr("id","edit-"+b).addClass("inline-editor").show(),a(".ptitle",c).eq(0).focus(),!1},save:function(c){var d,e,f=a('input[name="taxonomy"]').val()||"";return"object"==typeof c&&(c=this.getId(c)),a("table.widefat .spinner").addClass("is-active"),d={action:"inline-save-tax",tax_type:this.type,tax_ID:c,taxonomy:f},e=a("#edit-"+c).find(":input").serialize(),d=e+"&"+a.param(d),a.post(ajaxurl,d,function(d){var e,f,g,h=a("#edit-"+c+" .inline-edit-save .notice-error"),i=h.find(".error");a("table.widefat .spinner").removeClass("is-active"),d?-1!==d.indexOf("<tr")?(a(inlineEditTax.what+c).siblings("tr.hidden").addBack().remove(),f=a(d).attr("id"),a("#edit-"+c).before(d).remove(),f?(g=f.replace(inlineEditTax.type+"-",""),e=a("#"+f)):(g=c,e=a(inlineEditTax.what+c)),a("#parent").find("option[value="+g+"]").text(e.find(".row-title").text()),e.hide().fadeIn(400,function(){e.find(".editinline").focus(),b.a11y.speak(inlineEditL10n.saved)})):(h.removeClass("hidden"),i.html(d),b.a11y.speak(i.text())):(h.removeClass("hidden"),i.html(inlineEditL10n.error),b.a11y.speak(inlineEditL10n.error))}),!1},revert:function(){var b=a("table.widefat tr.inline-editor").attr("id");b&&(a("table.widefat .spinner").removeClass("is-active"),a("#"+b).siblings("tr.hidden").addBack().remove(),b=b.substr(b.lastIndexOf("-")+1),a(this.what+b).show().find(".editinline").focus())},getId:function(b){var c="TR"===b.tagName?b.id:a(b).parents("tr").attr("id"),d=c.split("-");return d[d.length-1]}},a(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
26
wp-admin/js/language-chooser.js
Normal file
26
wp-admin/js/language-chooser.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
jQuery( function($) {
|
||||
|
||||
var select = $( '#language' ),
|
||||
submit = $( '#language-continue' );
|
||||
|
||||
if ( ! $( 'body' ).hasClass( 'language-chooser' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
select.focus().on( 'change', function() {
|
||||
var option = select.children( 'option:selected' );
|
||||
submit.attr({
|
||||
value: option.data( 'continue' ),
|
||||
lang: option.attr( 'lang' )
|
||||
});
|
||||
});
|
||||
|
||||
$( 'form' ).submit( function() {
|
||||
// Don't show a spinner for English and installed languages,
|
||||
// as there is nothing to download.
|
||||
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(a){var b=a("#language"),c=a("#language-continue");a("body").hasClass("language-chooser")&&(b.focus().on("change",function(){var a=b.children("option:selected");c.attr({value:a.data("continue"),lang:a.attr("lang")})}),a("form").submit(function(){b.children("option:selected").data("installed")||a(this).find(".step .spinner").css("visibility","visible")}))});
|
||||
69
wp-admin/js/link.js
Normal file
69
wp-admin/js/link.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* global postboxes, deleteUserSetting, setUserSetting, getUserSetting */
|
||||
|
||||
jQuery(document).ready( function($) {
|
||||
|
||||
var newCat, noSyncChecks = false, syncChecks, catAddAfter;
|
||||
|
||||
$('#link_name').focus();
|
||||
// postboxes
|
||||
postboxes.add_postbox_toggles('link');
|
||||
|
||||
// category tabs
|
||||
$('#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' ); } );
|
||||
$('#link-category-add-submit').click( function() { newCat.focus(); } );
|
||||
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;
|
||||
};
|
||||
|
||||
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 );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
$('#categorychecklist').wpList( {
|
||||
alt: '',
|
||||
what: 'link-category',
|
||||
response: 'category-ajax-response',
|
||||
addAfter: catAddAfter
|
||||
} );
|
||||
|
||||
$('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');});
|
||||
$('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');});
|
||||
if ( 'pop' == getUserSetting('cats') )
|
||||
$('a[href="#categories-pop"]').click();
|
||||
|
||||
$('#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(a){var b,c,d,e=!1;a("#link_name").focus(),postboxes.add_postbox_toggles("link"),a("#category-tabs a").click(function(){var b=a(this).attr("href");return a(this).parent().addClass("tabs").siblings("li").removeClass("tabs"),a(".tabs-panel").hide(),a(b).show(),"#categories-all"==b?deleteUserSetting("cats"):setUserSetting("cats","pop"),!1}),getUserSetting("cats")&&a('#category-tabs a[href="#categories-pop"]').click(),b=a("#newcat").one("focus",function(){a(this).val("").removeClass("form-input-tip")}),a("#link-category-add-submit").click(function(){b.focus()}),c=function(){if(!e){e=!0;var b=a(this),c=b.is(":checked"),d=b.val().toString();a("#in-link-category-"+d+", #in-popular-link_category-"+d).prop("checked",c),e=!1}},d=function(b,d){a(d.what+" response_data",b).each(function(){var b=a(a(this).text());b.find("label").each(function(){var b,d=a(this),e=d.find("input").val(),f=d.find("input")[0].id,g=a.trim(d.text());a("#"+f).change(c),b=a('<option value="'+parseInt(e,10)+'"></option>').text(g)})})},a("#categorychecklist").wpList({alt:"",what:"link-category",response:"category-ajax-response",addAfter:d}),a('a[href="#categories-all"]').click(function(){deleteUserSetting("cats")}),a('a[href="#categories-pop"]').click(function(){setUserSetting("cats","pop")}),"pop"==getUserSetting("cats")&&a('a[href="#categories-pop"]').click(),a("#category-add-toggle").click(function(){return a(this).parents("div:first").toggleClass("wp-hidden-children"),a('#category-tabs a[href="#categories-all"]').click(),a("#newcategory").focus(),!1}),a(".categorychecklist :checkbox").change(c).filter(":checked").change()});
|
||||
39
wp-admin/js/media-gallery.js
Normal file
39
wp-admin/js/media-gallery.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* This file is used on media-upload.php which has been replaced by media-new.php and upload.php
|
||||
* Deprecated since 3.5.0
|
||||
*/
|
||||
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(a){a("body").bind("click.wp-gallery",function(b){var c,d,e=a(b.target);e.hasClass("wp-set-header")?((window.dialogArguments||opener||parent||top).location.href=e.data("location"),b.preventDefault()):e.hasClass("wp-set-background")&&(c=e.data("attachment-id"),d=a('input[name="attachments['+c+'][image-size]"]:checked').val(),jQuery.post(ajaxurl,{action:"set-background-image",attachment_id:c,size:d},function(){var a=window.dialogArguments||opener||parent||top;a.tb_remove(),a.location.reload()}),b.preventDefault())})});
|
||||
69
wp-admin/js/media-upload.js
Normal file
69
wp-admin/js/media-upload.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* global tinymce, QTags */
|
||||
// send html to the post editor
|
||||
|
||||
var wpActiveEditor, send_to_editor;
|
||||
|
||||
send_to_editor = function( html ) {
|
||||
var editor,
|
||||
hasTinymce = typeof tinymce !== 'undefined',
|
||||
hasQuicktags = typeof QTags !== 'undefined';
|
||||
|
||||
if ( ! wpActiveEditor ) {
|
||||
if ( hasTinymce && tinymce.activeEditor ) {
|
||||
editor = tinymce.activeEditor;
|
||||
wpActiveEditor = editor.id;
|
||||
} else if ( ! hasQuicktags ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( hasTinymce ) {
|
||||
editor = tinymce.get( wpActiveEditor );
|
||||
}
|
||||
|
||||
if ( editor && ! editor.isHidden() ) {
|
||||
editor.execCommand( 'mceInsertContent', false, html );
|
||||
} else if ( hasQuicktags ) {
|
||||
QTags.insertContent( html );
|
||||
} else {
|
||||
document.getElementById( wpActiveEditor ).value += html;
|
||||
}
|
||||
|
||||
// If the old thickbox remove function exists, call it
|
||||
if ( window.tb_remove ) {
|
||||
try { window.tb_remove(); } catch( e ) {}
|
||||
}
|
||||
};
|
||||
|
||||
// thickbox settings
|
||||
var tb_position;
|
||||
(function($) {
|
||||
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'});
|
||||
}
|
||||
|
||||
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 ) );
|
||||
});
|
||||
};
|
||||
|
||||
$(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 @@
|
|||
var wpActiveEditor,send_to_editor;send_to_editor=function(a){var b,c="undefined"!=typeof tinymce,d="undefined"!=typeof QTags;if(wpActiveEditor)c&&(b=tinymce.get(wpActiveEditor));else if(c&&tinymce.activeEditor)b=tinymce.activeEditor,wpActiveEditor=b.id;else if(!d)return!1;if(b&&!b.isHidden()?b.execCommand("mceInsertContent",!1,a):d?QTags.insertContent(a):document.getElementById(wpActiveEditor).value+=a,window.tb_remove)try{window.tb_remove()}catch(e){}};var tb_position;!function(a){tb_position=function(){var b=a("#TB_window"),c=a(window).width(),d=a(window).height(),e=833<c?833:c,f=0;return a("#wpadminbar").length&&(f=parseInt(a("#wpadminbar").css("height"),10)),b.length&&(b.width(e-50).height(d-45-f),a("#TB_iframeContent").width(e-50).height(d-75-f),b.css({"margin-left":"-"+parseInt((e-50)/2,10)+"px"}),"undefined"!=typeof document.body.style.maxWidth&&b.css({top:20+f+"px","margin-top":"0"})),a("a.thickbox").each(function(){var b=a(this).attr("href");b&&(b=b.replace(/&width=[0-9]+/g,""),b=b.replace(/&height=[0-9]+/g,""),a(this).attr("href",b+"&width="+(e-80)+"&height="+(d-85-f)))})},a(window).resize(function(){tb_position()})}(jQuery);
|
||||
204
wp-admin/js/media.js
Normal file
204
wp-admin/js/media.js
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/* global ajaxurl, attachMediaBoxL10n, _wpMediaGridSettings, showNotice */
|
||||
|
||||
/**
|
||||
* @summary Creates a dialog containing posts that can have a particular media attached to it.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global
|
||||
* @namespace
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
var findPosts;
|
||||
|
||||
( function( $ ){
|
||||
findPosts = {
|
||||
/**
|
||||
* @summary 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;
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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 );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary 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();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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 @@
|
|||
var findPosts;!function(a){findPosts={open:function(b,c){var d=a(".ui-find-overlay");return 0===d.length&&(a("body").append('<div class="ui-find-overlay"></div>'),findPosts.overlay()),d.show(),b&&c&&a("#affected").attr("name",b).val(c),a("#find-posts").show(),a("#find-posts-input").focus().keyup(function(a){27==a.which&&findPosts.close()}),findPosts.send(),!1},close:function(){a("#find-posts-response").empty(),a("#find-posts").hide(),a(".ui-find-overlay").hide()},overlay:function(){a(".ui-find-overlay").on("click",function(){findPosts.close()})},send:function(){var b={ps:a("#find-posts-input").val(),action:"find_posts",_ajax_nonce:a("#_ajax_nonce").val()},c=a(".find-box-search .spinner");c.addClass("is-active"),a.ajax(ajaxurl,{type:"POST",data:b,dataType:"json"}).always(function(){c.removeClass("is-active")}).done(function(b){b.success||a("#find-posts-response").text(attachMediaBoxL10n.error),a("#find-posts-response").html(b.data)}).fail(function(){a("#find-posts-response").text(attachMediaBoxL10n.error)})}},a(document).ready(function(){var b,c=a("#wp-media-grid");c.length&&window.wp&&window.wp.media&&(b=_wpMediaGridSettings,window.wp.media({frame:"manage",container:c,library:b.queryVars}).open()),a("#find-posts-submit").click(function(b){a('#find-posts-response input[type="radio"]:checked').length||b.preventDefault()}),a("#find-posts .find-box-search :input").keypress(function(a){if(13==a.which)return findPosts.send(),!1}),a("#find-posts-search").click(findPosts.send),a("#find-posts-close").click(findPosts.close),a("#doaction, #doaction2").click(function(b){a('select[name^="action"]').each(function(){var c=a(this).val();"attach"===c?(b.preventDefault(),findPosts.open()):"delete"===c&&(showNotice.warn()||b.preventDefault())})}),a(".find-box-inside").on("click","tr",function(){a(this).find(".found-radio input").prop("checked",!0)})})}(jQuery);
|
||||
1294
wp-admin/js/nav-menu.js
Normal file
1294
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
80
wp-admin/js/password-strength-meter.js
Normal file
80
wp-admin/js/password-strength-meter.js
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* global zxcvbn */
|
||||
window.wp = window.wp || {};
|
||||
|
||||
var passwordStrength;
|
||||
(function($){
|
||||
wp.passwordStrength = {
|
||||
/**
|
||||
* Determine the strength of a given password
|
||||
*
|
||||
* @param string password1 The password
|
||||
* @param array blacklist An array of words that will lower the entropy of the password
|
||||
* @param string password2 The confirmed password
|
||||
*/
|
||||
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 data that should be penalized, because it would lower the entropy of a password if it were used
|
||||
*
|
||||
* @return array The array of data 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;
|
||||
}
|
||||
};
|
||||
|
||||
// Back-compat.
|
||||
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||{};var passwordStrength;!function(a){wp.passwordStrength={meter:function(b,c,d){if(a.isArray(c)||(c=[c.toString()]),b!=d&&d&&d.length>0)return 5;if("undefined"==typeof window.zxcvbn)return-1;var e=zxcvbn(b,c);return e.score},userInputBlacklist:function(){var b,c,d,e,f=[],g=[],h=["user_login","first_name","last_name","nickname","display_name","email","url","description","weblog_title","admin_email"];for(f.push(document.title),f.push(document.URL),c=h.length,b=0;b<c;b++)e=a("#"+h[b]),0!==e.length&&(f.push(e[0].defaultValue),f.push(e.val()));for(d=f.length,b=0;b<d;b++)f[b]&&(g=g.concat(f[b].replace(/\W/g," ").split(" ")));return g=a.grep(g,function(b,c){return!(""===b||4>b.length)&&a.inArray(b,g)===c})}},passwordStrength=wp.passwordStrength.meter}(jQuery);
|
||||
220
wp-admin/js/plugin-install.js
Normal file
220
wp-admin/js/plugin-install.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/* global plugininstallL10n, tb_click, tb_remove */
|
||||
|
||||
/**
|
||||
* Functionality for the plugin install screens.
|
||||
*/
|
||||
var tb_position;
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
|
||||
var tbWindow,
|
||||
$iframeBody,
|
||||
$tabbables,
|
||||
$firstTabbable,
|
||||
$lastTabbable,
|
||||
$focusedBefore = $(),
|
||||
$uploadViewToggle = $( '.upload-view-toggle' ),
|
||||
$wrap = $ ( '.wrap' ),
|
||||
$body = $( document.body );
|
||||
|
||||
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 @@
|
|||
var tb_position;jQuery(document).ready(function(a){function b(){var b=e.find("#TB_iframeContent");f=b.contents().find("body"),c(),h.focus(),a("#plugin-information-tabs a",f).on("click",function(){c()}),f.on("keydown",function(a){27===a.which&&tb_remove()})}function c(){var b;g=a(":tabbable",f),h=e.find("#TB_closeWindowButton"),i=g.last(),b=h.add(i),b.off("keydown.wp-plugin-details"),b.on("keydown.wp-plugin-details",function(a){d(a)})}function d(a){9===a.which&&(i[0]!==a.target||a.shiftKey?h[0]===a.target&&a.shiftKey&&(a.preventDefault(),i.focus()):(a.preventDefault(),h.focus()))}var e,f,g,h,i,j=a(),k=a(".upload-view-toggle"),l=a(".wrap"),m=a(document.body);tb_position=function(){var b=a(window).width(),c=a(window).height()-(792<b?60:20),d=792<b?772:b-20;return e=a("#TB_window"),e.length&&(e.width(d).height(c),a("#TB_iframeContent").width(d).height(c),e.css({"margin-left":"-"+parseInt(d/2,10)+"px"}),"undefined"!=typeof document.body.style.maxWidth&&e.css({top:"30px","margin-top":"0"})),a("a.thickbox").each(function(){var b=a(this).attr("href");b&&(b=b.replace(/&width=[0-9]+/g,""),b=b.replace(/&height=[0-9]+/g,""),a(this).attr("href",b+"&width="+d+"&height="+c))})},a(window).resize(function(){tb_position()}),m.on("thickbox:iframe:loaded",e,function(){e.hasClass("plugin-details-modal")&&b()}).on("thickbox:removed",function(){j.focus()}),a(".wrap").on("click",".thickbox.open-plugin-details-modal",function(b){var c=a(this).data("title")?plugininstallL10n.plugin_information+" "+a(this).data("title"):plugininstallL10n.plugin_modal_label;b.preventDefault(),b.stopPropagation(),j=a(this),tb_click.call(this),e.attr({role:"dialog","aria-label":plugininstallL10n.plugin_modal_label}).addClass("plugin-details-modal"),e.find("#TB_iframeContent").attr("title",c)}),a("#plugin-information-tabs a").click(function(b){var c=a(this).attr("name");b.preventDefault(),a("#plugin-information-tabs a.current").removeClass("current"),a(this).addClass("current"),"description"!==c&&a(window).width()<772?a("#plugin-information-content").find(".fyi").hide():a("#plugin-information-content").find(".fyi").show(),a("#section-holder div.section").hide(),a("#section-"+c).show()}),l.hasClass("plugin-install-tab-upload")||k.attr({role:"button","aria-expanded":"false"}).on("click",function(a){a.preventDefault(),m.toggleClass("show-upload-view"),k.attr("aria-expanded",m.hasClass("show-upload-view"))})});
|
||||
1268
wp-admin/js/post.js
Normal file
1268
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
443
wp-admin/js/postbox.js
Normal file
443
wp-admin/js/postbox.js
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/**
|
||||
* Contains the postboxes logic, opening and closing postboxes, reordering and saving
|
||||
* the state and ordering to the database.
|
||||
*
|
||||
* @summary Contains postboxes logic
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @requires jQuery
|
||||
*/
|
||||
|
||||
/* global ajaxurl, postBoxL10n */
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
var postboxes;
|
||||
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
postboxes = {
|
||||
|
||||
/**
|
||||
* @summary 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 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Fires when a postbox has been opened or closed.
|
||||
*
|
||||
* Contains a jQuery object with the relevant postbox element.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @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();
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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');
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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
|
||||
* @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 );
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary 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 );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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' ) );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Saves the state of the postboxes to the server.
|
||||
*
|
||||
* 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
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Saves the order of the postboxes to the server.
|
||||
*
|
||||
* 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 );
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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
|
||||
* @event postboxes#postboxes-columnchange
|
||||
*/
|
||||
$( document ).trigger( 'postboxes-columnchange' );
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary 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 @@
|
|||
var postboxes;!function(a){var b=a(document);postboxes={handle_click:function(){var c,d=a(this),e=d.parent(".postbox"),f=e.attr("id");"dashboard_browser_nag"!==f&&(e.toggleClass("closed"),c=!e.hasClass("closed"),d.hasClass("handlediv")?d.attr("aria-expanded",c):d.closest(".postbox").find("button.handlediv").attr("aria-expanded",c),"press-this"!==postboxes.page&&postboxes.save_state(postboxes.page),f&&(!e.hasClass("closed")&&a.isFunction(postboxes.pbshow)?postboxes.pbshow(f):e.hasClass("closed")&&a.isFunction(postboxes.pbhide)&&postboxes.pbhide(f)),b.trigger("postbox-toggled",e))},add_postbox_toggles:function(c,d){var e=a(".postbox .hndle, .postbox .handlediv");this.page=c,this.init(c,d),e.on("click.postboxes",this.handle_click),a(".postbox .hndle a").click(function(a){a.stopPropagation()}),a(".postbox a.dismiss").on("click.postboxes",function(b){var c=a(this).parents(".postbox").attr("id")+"-hide";b.preventDefault(),a("#"+c).prop("checked",!1).triggerHandler("click")}),a(".hide-postbox-tog").bind("click.postboxes",function(){var d=a(this),e=d.val(),f=a("#"+e);d.prop("checked")?(f.show(),a.isFunction(postboxes.pbshow)&&postboxes.pbshow(e)):(f.hide(),a.isFunction(postboxes.pbhide)&&postboxes.pbhide(e)),postboxes.save_state(c),postboxes._mark_area(),b.trigger("postbox-toggled",f)}),a('.columns-prefs input[type="radio"]').bind("click.postboxes",function(){var b=parseInt(a(this).val(),10);b&&(postboxes._pb_edit(b),postboxes.save_order(c))})},init:function(c,d){var e=a(document.body).hasClass("mobile"),f=a(".postbox .handlediv");a.extend(this,d||{}),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:e?200:0,distance:2,tolerance:"pointer",forcePlaceholderSize:!0,helper:function(a,b){return b.clone().find(":input").attr("name",function(a,b){return"sort_"+parseInt(1e5*Math.random(),10).toString()+"_"+b}).end()},opacity:.65,stop:function(){var b=a(this);return b.find("#dashboard_browser_nag").is(":visible")&&"dashboard_browser_nag"!=this.firstChild.id?void b.sortable("cancel"):void postboxes.save_order(c)},receive:function(c,d){"dashboard_browser_nag"==d.item[0].id&&a(d.sender).sortable("cancel"),postboxes._mark_area(),b.trigger("postbox-moved",d.item)}}),e&&(a(document.body).bind("orientationchange.postboxes",function(){postboxes._pb_change()}),this._pb_change()),this._mark_area(),f.each(function(){var b=a(this);b.attr("aria-expanded",!b.parent(".postbox").hasClass("closed"))})},save_state:function(b){var c,d;"nav-menus"!==b&&(c=a(".postbox").filter(".closed").map(function(){return this.id}).get().join(","),d=a(".postbox").filter(":hidden").map(function(){return this.id}).get().join(","),a.post(ajaxurl,{action:"closed-postboxes",closed:c,hidden:d,closedpostboxesnonce:jQuery("#closedpostboxesnonce").val(),page:b}))},save_order:function(b){var c,d=a(".columns-prefs input:checked").val()||0;c={action:"meta-box-order",_ajax_nonce:a("#meta-box-order-nonce").val(),page_columns:d,page:b},a(".meta-box-sortables").each(function(){c["order["+this.id.split("-")[0]+"]"]=a(this).sortable("toArray").join(",")}),a.post(ajaxurl,c)},_mark_area:function(){var b=a("div.postbox:visible").length,c=a("#post-body #side-sortables");a("#dashboard-widgets .meta-box-sortables:visible").each(function(){var c=a(this);1==b||c.children(".postbox:visible").length?c.removeClass("empty-container"):(c.addClass("empty-container"),c.attr("data-emptyString",postBoxL10n.postBoxEmptyString))}),c.length&&(c.children(".postbox:visible").length?c.removeClass("empty-container"):"280px"==a("#postbox-container-1").css("width")&&c.addClass("empty-container"))},_pb_edit:function(b){var c=a(".metabox-holder").get(0);c&&(c.className=c.className.replace(/columns-\d+/,"columns-"+b)),a(document).trigger("postboxes-columnchange")},_pb_change:function(){var b=a('label.columns-prefs-1 input[type="radio"]');switch(window.orientation){case 90:case-90:b.length&&b.is(":checked")||this._pb_edit(2);break;case 0:case 180:a("#poststuff").length?this._pb_edit(1):b.length&&b.is(":checked")||this._pb_edit(2)}},pbshow:!1,pbhide:!1}}(jQuery);
|
||||
1169
wp-admin/js/revisions.js
Normal file
1169
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
24
wp-admin/js/set-post-thumbnail.js
Normal file
24
wp-admin/js/set-post-thumbnail.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* global setPostThumbnailL10n, ajaxurl, post_id, alert */
|
||||
/* exported WPSetAsThumbnail */
|
||||
|
||||
function WPSetAsThumbnail( 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 @@
|
|||
function WPSetAsThumbnail(a,b){var c=jQuery("a#wp-post-thumbnail-"+a);c.text(setPostThumbnailL10n.saving),jQuery.post(ajaxurl,{action:"set-post-thumbnail",post_id:post_id,thumbnail_id:a,_ajax_nonce:b,cookie:encodeURIComponent(document.cookie)},function(b){var d=window.dialogArguments||opener||parent||top;c.text(setPostThumbnailL10n.setThumbnail),"0"==b?alert(setPostThumbnailL10n.error):(jQuery("a.wp-post-thumbnail").show(),c.text(setPostThumbnailL10n.done),c.fadeOut(2e3),d.WPSetThumbnailID(a),d.WPSetThumbnailHTML(b))})}
|
||||
240
wp-admin/js/svg-painter.js
Normal file
240
wp-admin/js/svg-painter.js
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/**
|
||||
* Attempt to re-color SVG icons used in the admin menu or the toolbar
|
||||
*
|
||||
*/
|
||||
|
||||
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,b,c,d){"use strict";var e,f,g,h={},i=[];return a(c).ready(function(){c.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")&&(a(c.body).removeClass("no-svg").addClass("svg"),wp.svgPainter.init())}),f=function(){function a(){for(;j<256;)e=String.fromCharCode(j),g+=e,i[j]=j,h[j]=f.indexOf(e),++j}function b(a,b,c,d,f,g){var h,i,j=0,k=0,l="",m=0;for(a=String(a),i=a.length;k<i;){for(e=a.charCodeAt(k),e=e<256?c[e]:-1,j=(j<<f)+e,m+=f;m>=g;)m-=g,h=j>>m,l+=d.charAt(h),j^=h<<m;++k}return!b&&m>0&&(l+=d.charAt(j<<g-m)),l}function c(c){return e||a(),c=b(c,!1,i,f,8,6),c+"====".slice(c.length%4||4)}function d(c){var d;e||a(),c=c.replace(/[^A-Za-z0-9\+\/\=]/g,""),c=String(c).split("="),d=c.length;do--d,c[d]=b(c[d],!0,h,g,6,8);while(d>0);return c=c.join("")}var e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g="",h=[256],i=[256],j=0;return{atob:d,btoa:c}}(),{init:function(){g=this,e=a("#adminmenu .wp-menu-image, #wpadminbar .ab-item"),this.setColors(),this.findElements(),this.paint()},setColors:function(a){"undefined"==typeof a&&"undefined"!=typeof b._wpColorScheme&&(a=b._wpColorScheme),a&&a.icons&&a.icons.base&&a.icons.current&&a.icons.focus&&(h=a.icons)},findElements:function(){e.each(function(){var b=a(this),c=b.css("background-image");c&&c.indexOf("data:image/svg+xml;base64")!=-1&&i.push(b)})},paint:function(){a.each(i,function(a,c){var d=c.parent().parent();d.hasClass("current")||d.hasClass("wp-has-current-submenu")?g.paintElement(c,"current"):(g.paintElement(c,"base"),d.hover(function(){g.paintElement(c,"focus")},function(){b.setTimeout(function(){g.paintElement(c,"base")},100)}))})},paintElement:function(a,c){var d,e,g;if(c&&h.hasOwnProperty(c)&&(g=h[c],g.match(/^(#[0-9a-f]{3}|#[0-9a-f]{6})$/i)&&(d=a.data("wp-ui-svg-"+g),"none"!==d))){if(!d){if(e=a.css("background-image").match(/.+data:image\/svg\+xml;base64,([A-Za-z0-9\+\/\=]+)/),!e||!e[1])return void a.data("wp-ui-svg-"+g,"none");try{d="atob"in b?b.atob(e[1]):f.atob(e[1])}catch(i){}if(!d)return void a.data("wp-ui-svg-"+g,"none");d=d.replace(/fill="(.+?)"/g,'fill="'+g+'"'),d=d.replace(/style="(.+?)"/g,'style="fill:'+g+'"'),d=d.replace(/fill:.*?;/g,"fill: "+g+";"),d="btoa"in b?b.btoa(d):f.btoa(d),a.data("wp-ui-svg-"+g,d)}a.attr("style",'background-image: url("data:image/svg+xml;base64,'+d+'") !important;')}}}}(jQuery,window,document);
|
||||
263
wp-admin/js/tags-box.js
Normal file
263
wp-admin/js/tags-box.js
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/* jshint curly: false, eqeqeq: false */
|
||||
/* global ajaxurl */
|
||||
|
||||
var tagBox, array_unique_noempty;
|
||||
|
||||
( function( $ ) {
|
||||
var tagDelimiter = ( window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter ) || ',';
|
||||
|
||||
// Return an array with any duplicate, whitespace or empty values removed
|
||||
array_unique_noempty = function( array ) {
|
||||
var out = [];
|
||||
|
||||
$.each( array, function( key, val ) {
|
||||
val = $.trim( val );
|
||||
|
||||
if ( val && $.inArray( val, out ) === -1 ) {
|
||||
out.push( val );
|
||||
}
|
||||
} );
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
tagBox = {
|
||||
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;
|
||||
},
|
||||
|
||||
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];
|
||||
|
||||
$.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;
|
||||
},
|
||||
|
||||
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();
|
||||
|
||||
$.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>' );
|
||||
|
||||
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();
|
||||
},
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
get : function( id ) {
|
||||
var tax = id.substr( id.indexOf('-') + 1 );
|
||||
|
||||
$.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>' );
|
||||
|
||||
$( '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: '',
|
||||
|
||||
/**
|
||||
* Dispatch an audible message to screen readers.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*/
|
||||
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' );
|
||||
},
|
||||
|
||||
init : function() {
|
||||
var ajaxtag = $('div.ajaxtag');
|
||||
|
||||
$('.tagsdiv').each( function() {
|
||||
tagBox.quickClicks( this );
|
||||
});
|
||||
|
||||
$( '.tagadd', ajaxtag ).click( function() {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
});
|
||||
|
||||
$( 'input.newtag', ajaxtag ).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}).each( function( i, element ) {
|
||||
$( element ).wpTagsSuggest();
|
||||
});
|
||||
|
||||
// save tags on post save/publish
|
||||
$('#post').submit(function(){
|
||||
$('div.tagsdiv').each( function() {
|
||||
tagBox.flushTags(this, false, 1);
|
||||
});
|
||||
});
|
||||
|
||||
// Fetch and toggle the Tag cloud.
|
||||
$('.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 @@
|
|||
var tagBox,array_unique_noempty;!function(a){var b=window.tagsSuggestL10n&&window.tagsSuggestL10n.tagDelimiter||",";array_unique_noempty=function(b){var c=[];return a.each(b,function(b,d){d=a.trim(d),d&&a.inArray(d,c)===-1&&c.push(d)}),c},tagBox={clean:function(a){return","!==b&&(a=a.replace(new RegExp(b,"g"),",")),a=a.replace(/\s*,\s*/g,",").replace(/,+/g,",").replace(/[,\s]+$/,"").replace(/^[,\s]+/,""),","!==b&&(a=a.replace(/,/g,b)),a},parseTags:function(c){var d=c.id,e=d.split("-check-num-")[1],f=a(c).closest(".tagsdiv"),g=f.find(".the-tags"),h=g.val().split(b),i=[];return delete h[e],a.each(h,function(b,c){c=a.trim(c),c&&i.push(c)}),g.val(this.clean(i.join(b))),this.quickClicks(f),!1},quickClicks:function(c){var d,e,f=a(".the-tags",c),g=a(".tagchecklist",c),h=a(c).attr("id");f.length&&(e=f.prop("disabled"),d=f.val().split(b),g.empty(),a.each(d,function(b,c){var d,f;c=a.trim(c),c&&(d=a("<li />").text(c),e||(f=a('<button type="button" id="'+h+"-check-num-"+b+'" class="ntdelbutton"><span class="remove-tag-icon" aria-hidden="true"></span><span class="screen-reader-text">'+window.tagsSuggestL10n.removeTerm+" "+d.html()+"</span></button>"),f.on("click keypress",function(b){"click"!==b.type&&13!==b.keyCode&&32!==b.keyCode||(13!==b.keyCode&&32!==b.keyCode||a(this).closest(".tagsdiv").find("input.newtag").focus(),tagBox.userAction="remove",tagBox.parseTags(this))}),d.prepend(" ").prepend(f)),g.append(d))}),tagBox.screenReadersMessage())},flushTags:function(c,d,e){var f,g,h,i=a(".the-tags",c),j=a("input.newtag",c);return d=d||!1,h=d?a(d).text():j.val(),"undefined"!=typeof h&&""!==h&&(f=i.val(),g=f?f+b+h:h,g=this.clean(g),g=array_unique_noempty(g.split(b)).join(b),i.val(g),this.quickClicks(c),d||j.val(""),"undefined"==typeof e&&j.focus(),!1)},get:function(b){var c=b.substr(b.indexOf("-")+1);a.post(ajaxurl,{action:"get-tagcloud",tax:c},function(d,e){0!==d&&"success"==e&&(d=a('<div id="tagcloud-'+c+'" class="the-tagcloud">'+d+"</div>"),a("a",d).click(function(){return tagBox.userAction="add",tagBox.flushTags(a("#"+c),this),!1}),a("#"+b).after(d))})},userAction:"",screenReadersMessage:function(){var a;switch(this.userAction){case"remove":a=window.tagsSuggestL10n.termRemoved;break;case"add":a=window.tagsSuggestL10n.termAdded;break;default:return}window.wp.a11y.speak(a,"assertive")},init:function(){var b=a("div.ajaxtag");a(".tagsdiv").each(function(){tagBox.quickClicks(this)}),a(".tagadd",b).click(function(){tagBox.userAction="add",tagBox.flushTags(a(this).closest(".tagsdiv"))}),a("input.newtag",b).keypress(function(b){13==b.which&&(tagBox.userAction="add",tagBox.flushTags(a(this).closest(".tagsdiv")),b.preventDefault(),b.stopPropagation())}).keypress(function(a){13==a.which&&(a.preventDefault(),a.stopPropagation())}).each(function(b,c){a(c).wpTagsSuggest()}),a("#post").submit(function(){a("div.tagsdiv").each(function(){tagBox.flushTags(this,!1,1)})}),a(".tagcloud-link").click(function(){tagBox.get(a(this).attr("id")),a(this).attr("aria-expanded","true").unbind().click(function(){a(this).attr("aria-expanded","false"===a(this).attr("aria-expanded")?"true":"false").siblings(".the-tagcloud").toggle()})})}}}(jQuery);
|
||||
185
wp-admin/js/tags-suggest.js
Normal file
185
wp-admin/js/tags-suggest.js
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/**
|
||||
* Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
|
||||
*/
|
||||
( 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 ) {
|
||||
// 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(a){function b(a){return a.split(new RegExp(e+"\\s*"))}function c(a){return b(a).pop()}if("undefined"!=typeof window.tagsSuggestL10n&&"undefined"!=typeof window.uiAutocompleteL10n){var d=0,e=window.tagsSuggestL10n.tagDelimiter||",";a.fn.wpTagsSuggest=function(f){var g,h,i=a(this);f=f||{};var j=f.taxonomy||i.attr("data-wp-taxonomy")||"post_tag";return delete f.taxonomy,f=a.extend({source:function(b,e){var f;return h===b.term?void e(g):(f=c(b.term),a.get(window.ajaxurl,{action:"ajax-tag-search",tax:j,q:f}).always(function(){i.removeClass("ui-autocomplete-loading")}).done(function(a){var b,c=[];if(a){a=a.split("\n");for(b in a){var f=++d;c.push({id:f,name:a[b]})}g=c,e(c)}else e(c)}),void(h=b.term))},focus:function(a,b){i.attr("aria-activedescendant","wp-tags-autocomplete-"+b.item.id),a.preventDefault()},select:function(c,d){var f=b(i.val());return f.pop(),f.push(d.item.name,""),i.val(f.join(e+" ")),a.ui.keyCode.TAB===c.keyCode?(window.wp.a11y.speak(window.tagsSuggestL10n.termSelected,"assertive"),c.preventDefault()):a.ui.keyCode.ENTER===c.keyCode&&(c.preventDefault(),c.stopPropagation()),!1},open:function(){i.attr("aria-expanded","true")},close:function(){i.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2",at:"left bottom",collision:"none"},messages:{noResults:window.uiAutocompleteL10n.noResults,results:function(a){return a>1?window.uiAutocompleteL10n.manyResults.replace("%d",a):window.uiAutocompleteL10n.oneResult}}},f),i.on("keydown",function(){i.removeAttr("aria-activedescendant")}).autocomplete(f).autocomplete("instance")._renderItem=function(b,c){return a('<li role="option" id="wp-tags-autocomplete-'+c.id+'">').text(c.name).appendTo(b)},i.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":i.autocomplete("widget").attr("id")}).on("focus",function(){var a=b(i.val()).pop();a&&i.autocomplete("search")}).autocomplete("widget").addClass("wp-tags-autocomplete").attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")}),this}}}(jQuery);
|
||||
146
wp-admin/js/tags.js
Normal file
146
wp-admin/js/tags.js
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/* global ajaxurl, wpAjax, tagsl10n, showNotice, validateForm */
|
||||
/**
|
||||
* Contains logic for both adding and deleting 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.
|
||||
*
|
||||
* @summary Contains logic for deleting and adding tags
|
||||
*/
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
/**
|
||||
* @summary Adds an event handler to the delete term link on the term overview page.
|
||||
*
|
||||
* 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');
|
||||
|
||||
/**
|
||||
* @summary 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(); });
|
||||
|
||||
/**
|
||||
* @summary Remove 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @summary Adds an event handler tot he 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
$('#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(a){a("#the-list").on("click",".delete-tag",function(){var b,c=a(this),d=c.parents("tr"),e=!0;return"undefined"!=showNotice&&(e=showNotice.warn()),e&&(b=c.attr("href").replace(/[^?]*\?/,"").replace(/action=delete/,"action=delete-tag"),a.post(ajaxurl,b,function(c){"1"==c?(a("#ajax-response").empty(),d.fadeOut("normal",function(){d.remove()}),a('select#parent option[value="'+b.match(/tag_ID=(\d+)/)[1]+'"]').remove(),a("a.tag-link-"+b.match(/tag_ID=(\d+)/)[1]).remove()):"-1"==c?(a("#ajax-response").empty().append('<div class="error"><p>'+tagsl10n.noPerm+"</p></div>"),d.children().css("backgroundColor","")):(a("#ajax-response").empty().append('<div class="error"><p>'+tagsl10n.broken+"</p></div>"),d.children().css("backgroundColor",""))}),d.children().css("backgroundColor","#f33")),!1}),a("#edittag").on("click",".delete",function(a){if("undefined"==typeof showNotice)return!0;var b=showNotice.warn();b||a.preventDefault()}),a("#submit").click(function(){var b=a(this).parents("form");return!!validateForm(b)&&(a.post(ajaxurl,a("#addtag").serialize(),function(c){var d,e,f,g,h;if(a("#ajax-response").empty(),d=wpAjax.parseAjaxResponse(c,"ajax-response"),d&&!d.errors){if(e=b.find("select#parent").val(),e>0&&a("#tag-"+e).length>0?a(".tags #tag-"+e).after(d.responses[0].supplemental.noparents):a(".tags").prepend(d.responses[0].supplemental.parents),a(".tags .no-items").remove(),b.find("select#parent")){for(f=d.responses[1].supplemental,g="",h=0;h<d.responses[1].position;h++)g+=" ";b.find("select#parent option:selected").after('<option value="'+f.term_id+'">'+g+f.name+"</option>")}a('input[type="text"]:visible, textarea:visible',b).val("")}}),!1)})});
|
||||
991
wp-admin/js/theme-plugin-editor.js
Normal file
991
wp-admin/js/theme-plugin-editor.js
Normal file
|
|
@ -0,0 +1,991 @@
|
|||
/* eslint no-magic-numbers: ["error", { "ignore": [-1, 0, 1] }] */
|
||||
|
||||
if ( ! window.wp ) {
|
||||
window.wp = {};
|
||||
}
|
||||
|
||||
wp.themePluginEditor = (function( $ ) {
|
||||
'use strict';
|
||||
var component, TreeLinks;
|
||||
|
||||
component = {
|
||||
l10n: {
|
||||
lintError: {
|
||||
singular: '',
|
||||
plural: ''
|
||||
},
|
||||
saveAlert: '',
|
||||
saveError: ''
|
||||
},
|
||||
codeEditor: {},
|
||||
instance: null,
|
||||
noticeElements: {},
|
||||
dirty: false,
|
||||
lintErrors: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize component.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {jQuery} form - Form element.
|
||||
* @param {object} settings - Settings.
|
||||
* @param {object|boolean} settings.codeEditor - Code editor settings (or `false` if syntax highlighting is disabled).
|
||||
* @returns {void}
|
||||
*/
|
||||
component.init = function init( form, settings ) {
|
||||
|
||||
component.form = form;
|
||||
if ( settings ) {
|
||||
$.extend( component, settings );
|
||||
}
|
||||
|
||||
component.noticeTemplate = wp.template( 'wp-file-editor-notice' );
|
||||
component.noticesContainer = component.form.find( '.editor-notices' );
|
||||
component.submitButton = component.form.find( ':input[name=submit]' );
|
||||
component.spinner = component.form.find( '.submit .spinner' );
|
||||
component.form.on( 'submit', component.submit );
|
||||
component.textarea = component.form.find( '#newcontent' );
|
||||
component.textarea.on( 'change', component.onChange );
|
||||
component.warning = $( '.file-editor-warning' );
|
||||
|
||||
if ( component.warning.length > 0 ) {
|
||||
component.showWarning();
|
||||
}
|
||||
|
||||
if ( false !== component.codeEditor ) {
|
||||
/*
|
||||
* Defer adding notices until after DOM ready as workaround for WP Admin injecting
|
||||
* its own managed dismiss buttons and also to prevent the editor from showing a notice
|
||||
* when the file had linting errors to begin with.
|
||||
*/
|
||||
_.defer( function() {
|
||||
component.initCodeEditor();
|
||||
} );
|
||||
}
|
||||
|
||||
$( component.initFileBrowser );
|
||||
|
||||
$( window ).on( 'beforeunload', function() {
|
||||
if ( component.dirty ) {
|
||||
return component.l10n.saveAlert;
|
||||
}
|
||||
return undefined;
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up and display the warning modal.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
component.showWarning = function() {
|
||||
// Get the text within the modal.
|
||||
var rawMessage = component.warning.find( '.file-editor-warning-message' ).text();
|
||||
// Hide all the #wpwrap content from assistive technologies.
|
||||
$( '#wpwrap' ).attr( 'aria-hidden', 'true' );
|
||||
// Detach the warning modal from its position and append it to the body.
|
||||
$( document.body )
|
||||
.addClass( 'modal-open' )
|
||||
.append( component.warning.detach() );
|
||||
// Reveal the modal and set focus on the go back button.
|
||||
component.warning
|
||||
.removeClass( 'hidden' )
|
||||
.find( '.file-editor-warning-go-back' ).focus();
|
||||
// Get the links and buttons within the modal.
|
||||
component.warningTabbables = component.warning.find( 'a, button' );
|
||||
// Attach event handlers.
|
||||
component.warningTabbables.on( 'keydown', component.constrainTabbing );
|
||||
component.warning.on( 'click', '.file-editor-warning-dismiss', component.dismissWarning );
|
||||
// Make screen readers announce the warning message after a short delay (necessary for some screen readers).
|
||||
setTimeout( function() {
|
||||
wp.a11y.speak( wp.sanitize.stripTags( rawMessage.replace( /\s+/g, ' ' ) ), 'assertive' );
|
||||
}, 1000 );
|
||||
};
|
||||
|
||||
/**
|
||||
* Constrain tabbing within the warning modal.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @param {object} event jQuery event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
component.constrainTabbing = function( event ) {
|
||||
var firstTabbable, lastTabbable;
|
||||
|
||||
if ( 9 !== event.which ) {
|
||||
return;
|
||||
}
|
||||
|
||||
firstTabbable = component.warningTabbables.first()[0];
|
||||
lastTabbable = component.warningTabbables.last()[0];
|
||||
|
||||
if ( lastTabbable === event.target && ! event.shiftKey ) {
|
||||
firstTabbable.focus();
|
||||
event.preventDefault();
|
||||
} else if ( firstTabbable === event.target && event.shiftKey ) {
|
||||
lastTabbable.focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dismiss the warning modal.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
component.dismissWarning = function() {
|
||||
|
||||
wp.ajax.post( 'dismiss-wp-pointer', {
|
||||
pointer: component.themeOrPlugin + '_editor_notice'
|
||||
});
|
||||
|
||||
// Hide modal.
|
||||
component.warning.remove();
|
||||
$( '#wpwrap' ).removeAttr( 'aria-hidden' );
|
||||
$( 'body' ).removeClass( 'modal-open' );
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for when a change happens.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
component.onChange = function() {
|
||||
component.dirty = true;
|
||||
component.removeNotice( 'file_saved' );
|
||||
};
|
||||
|
||||
/**
|
||||
* Submit file via Ajax.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @param {jQuery.Event} event - Event.
|
||||
* @returns {void}
|
||||
*/
|
||||
component.submit = function( event ) {
|
||||
var data = {}, request;
|
||||
event.preventDefault(); // Prevent form submission in favor of Ajax below.
|
||||
$.each( component.form.serializeArray(), function() {
|
||||
data[ this.name ] = this.value;
|
||||
} );
|
||||
|
||||
// Use value from codemirror if present.
|
||||
if ( component.instance ) {
|
||||
data.newcontent = component.instance.codemirror.getValue();
|
||||
}
|
||||
|
||||
if ( component.isSaving ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Scroll ot the line that has the error.
|
||||
if ( component.lintErrors.length ) {
|
||||
component.instance.codemirror.setCursor( component.lintErrors[0].from.line );
|
||||
return;
|
||||
}
|
||||
|
||||
component.isSaving = true;
|
||||
component.textarea.prop( 'readonly', true );
|
||||
if ( component.instance ) {
|
||||
component.instance.codemirror.setOption( 'readOnly', true );
|
||||
}
|
||||
|
||||
component.spinner.addClass( 'is-active' );
|
||||
request = wp.ajax.post( 'edit-theme-plugin-file', data );
|
||||
|
||||
// Remove previous save notice before saving.
|
||||
if ( component.lastSaveNoticeCode ) {
|
||||
component.removeNotice( component.lastSaveNoticeCode );
|
||||
}
|
||||
|
||||
request.done( function( response ) {
|
||||
component.lastSaveNoticeCode = 'file_saved';
|
||||
component.addNotice({
|
||||
code: component.lastSaveNoticeCode,
|
||||
type: 'success',
|
||||
message: response.message,
|
||||
dismissible: true
|
||||
});
|
||||
component.dirty = false;
|
||||
} );
|
||||
|
||||
request.fail( function( response ) {
|
||||
var notice = $.extend(
|
||||
{
|
||||
code: 'save_error',
|
||||
message: component.l10n.saveError
|
||||
},
|
||||
response,
|
||||
{
|
||||
type: 'error',
|
||||
dismissible: true
|
||||
}
|
||||
);
|
||||
component.lastSaveNoticeCode = notice.code;
|
||||
component.addNotice( notice );
|
||||
} );
|
||||
|
||||
request.always( function() {
|
||||
component.spinner.removeClass( 'is-active' );
|
||||
component.isSaving = false;
|
||||
|
||||
component.textarea.prop( 'readonly', false );
|
||||
if ( component.instance ) {
|
||||
component.instance.codemirror.setOption( 'readOnly', false );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Add notice.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {object} notice - Notice.
|
||||
* @param {string} notice.code - Code.
|
||||
* @param {string} notice.type - Type.
|
||||
* @param {string} notice.message - Message.
|
||||
* @param {boolean} [notice.dismissible=false] - Dismissible.
|
||||
* @param {Function} [notice.onDismiss] - Callback for when a user dismisses the notice.
|
||||
* @returns {jQuery} Notice element.
|
||||
*/
|
||||
component.addNotice = function( notice ) {
|
||||
var noticeElement;
|
||||
|
||||
if ( ! notice.code ) {
|
||||
throw new Error( 'Missing code.' );
|
||||
}
|
||||
|
||||
// Only let one notice of a given type be displayed at a time.
|
||||
component.removeNotice( notice.code );
|
||||
|
||||
noticeElement = $( component.noticeTemplate( notice ) );
|
||||
noticeElement.hide();
|
||||
|
||||
noticeElement.find( '.notice-dismiss' ).on( 'click', function() {
|
||||
component.removeNotice( notice.code );
|
||||
if ( notice.onDismiss ) {
|
||||
notice.onDismiss( notice );
|
||||
}
|
||||
} );
|
||||
|
||||
wp.a11y.speak( notice.message );
|
||||
|
||||
component.noticesContainer.append( noticeElement );
|
||||
noticeElement.slideDown( 'fast' );
|
||||
component.noticeElements[ notice.code ] = noticeElement;
|
||||
return noticeElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove notice.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {string} code - Notice code.
|
||||
* @returns {boolean} Whether a notice was removed.
|
||||
*/
|
||||
component.removeNotice = function( code ) {
|
||||
if ( component.noticeElements[ code ] ) {
|
||||
component.noticeElements[ code ].slideUp( 'fast', function() {
|
||||
$( this ).remove();
|
||||
} );
|
||||
delete component.noticeElements[ code ];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize code editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
component.initCodeEditor = function initCodeEditor() {
|
||||
var codeEditorSettings, editor;
|
||||
|
||||
codeEditorSettings = $.extend( {}, component.codeEditor );
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field before the editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
codeEditorSettings.onTabPrevious = function() {
|
||||
$( '#templateside' ).find( ':tabbable' ).last().focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field after the editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
codeEditorSettings.onTabNext = function() {
|
||||
$( '#template' ).find( ':tabbable:not(.CodeMirror-code)' ).first().focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle change to the linting errors.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {Array} errors - List of linting errors.
|
||||
* @returns {void}
|
||||
*/
|
||||
codeEditorSettings.onChangeLintingErrors = function( errors ) {
|
||||
component.lintErrors = errors;
|
||||
|
||||
// Only disable the button in onUpdateErrorNotice when there are errors so users can still feel they can click the button.
|
||||
if ( 0 === errors.length ) {
|
||||
component.submitButton.toggleClass( 'disabled', false );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update error notice.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @param {Array} errorAnnotations - Error annotations.
|
||||
* @returns {void}
|
||||
*/
|
||||
codeEditorSettings.onUpdateErrorNotice = function onUpdateErrorNotice( errorAnnotations ) {
|
||||
var message, noticeElement;
|
||||
|
||||
component.submitButton.toggleClass( 'disabled', errorAnnotations.length > 0 );
|
||||
|
||||
if ( 0 !== errorAnnotations.length ) {
|
||||
if ( 1 === errorAnnotations.length ) {
|
||||
message = component.l10n.lintError.singular.replace( '%d', '1' );
|
||||
} else {
|
||||
message = component.l10n.lintError.plural.replace( '%d', String( errorAnnotations.length ) );
|
||||
}
|
||||
noticeElement = component.addNotice({
|
||||
code: 'lint_errors',
|
||||
type: 'error',
|
||||
message: message,
|
||||
dismissible: false
|
||||
});
|
||||
noticeElement.find( 'input[type=checkbox]' ).on( 'click', function() {
|
||||
codeEditorSettings.onChangeLintingErrors( [] );
|
||||
component.removeNotice( 'lint_errors' );
|
||||
} );
|
||||
} else {
|
||||
component.removeNotice( 'lint_errors' );
|
||||
}
|
||||
};
|
||||
|
||||
editor = wp.codeEditor.initialize( $( '#newcontent' ), codeEditorSettings );
|
||||
editor.codemirror.on( 'change', component.onChange );
|
||||
|
||||
// Improve the editor accessibility.
|
||||
$( editor.codemirror.display.lineDiv )
|
||||
.attr({
|
||||
role: 'textbox',
|
||||
'aria-multiline': 'true',
|
||||
'aria-labelledby': 'theme-plugin-editor-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.
|
||||
$( '#theme-plugin-editor-label' ).on( 'click', function() {
|
||||
editor.codemirror.focus();
|
||||
});
|
||||
|
||||
component.instance = editor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialization of the file browser's folder states.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
component.initFileBrowser = function initFileBrowser() {
|
||||
|
||||
var $templateside = $( '#templateside' );
|
||||
|
||||
// Collapse all folders.
|
||||
$templateside.find( '[role="group"]' ).parent().attr( 'aria-expanded', false );
|
||||
|
||||
// Expand ancestors to the current file.
|
||||
$templateside.find( '.notice' ).parents( '[aria-expanded]' ).attr( 'aria-expanded', true );
|
||||
|
||||
// Find Tree elements and enhance them.
|
||||
$templateside.find( '[role="tree"]' ).each( function() {
|
||||
var treeLinks = new TreeLinks( this );
|
||||
treeLinks.init();
|
||||
} );
|
||||
|
||||
// Scroll the current file into view.
|
||||
$templateside.find( '.current-file:first' ).each( function() {
|
||||
if ( this.scrollIntoViewIfNeeded ) {
|
||||
this.scrollIntoViewIfNeeded();
|
||||
} else {
|
||||
this.scrollIntoView( false );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/* jshint ignore:start */
|
||||
/* jscs:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Creates a new TreeitemLink.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @class
|
||||
* @private
|
||||
* @see {@link https://www.w3.org/TR/wai-aria-practices-1.1/examples/treeview/treeview-2/treeview-2b.html|W3C Treeview Example}
|
||||
* @license W3C-20150513
|
||||
*/
|
||||
var TreeitemLink = (function () {
|
||||
/**
|
||||
* This content is licensed according to the W3C Software License at
|
||||
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
||||
*
|
||||
* File: TreeitemLink.js
|
||||
*
|
||||
* Desc: Treeitem widget that implements ARIA Authoring Practices
|
||||
* for a tree being used as a file viewer
|
||||
*
|
||||
* Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @desc
|
||||
* Treeitem object for representing the state and user interactions for a
|
||||
* treeItem widget
|
||||
*
|
||||
* @param node
|
||||
* An element with the role=tree attribute
|
||||
*/
|
||||
|
||||
var TreeitemLink = function (node, treeObj, group) {
|
||||
|
||||
// Check whether node is a DOM element
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
node.tabIndex = -1;
|
||||
this.tree = treeObj;
|
||||
this.groupTreeitem = group;
|
||||
this.domNode = node;
|
||||
this.label = node.textContent.trim();
|
||||
this.stopDefaultClick = false;
|
||||
|
||||
if (node.getAttribute('aria-label')) {
|
||||
this.label = node.getAttribute('aria-label').trim();
|
||||
}
|
||||
|
||||
this.isExpandable = false;
|
||||
this.isVisible = false;
|
||||
this.inGroup = false;
|
||||
|
||||
if (group) {
|
||||
this.inGroup = true;
|
||||
}
|
||||
|
||||
var elem = node.firstElementChild;
|
||||
|
||||
while (elem) {
|
||||
|
||||
if (elem.tagName.toLowerCase() == 'ul') {
|
||||
elem.setAttribute('role', 'group');
|
||||
this.isExpandable = true;
|
||||
break;
|
||||
}
|
||||
|
||||
elem = elem.nextElementSibling;
|
||||
}
|
||||
|
||||
this.keyCode = Object.freeze({
|
||||
RETURN: 13,
|
||||
SPACE: 32,
|
||||
PAGEUP: 33,
|
||||
PAGEDOWN: 34,
|
||||
END: 35,
|
||||
HOME: 36,
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40
|
||||
});
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.init = function () {
|
||||
this.domNode.tabIndex = -1;
|
||||
|
||||
if (!this.domNode.getAttribute('role')) {
|
||||
this.domNode.setAttribute('role', 'treeitem');
|
||||
}
|
||||
|
||||
this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
|
||||
this.domNode.addEventListener('click', this.handleClick.bind(this));
|
||||
this.domNode.addEventListener('focus', this.handleFocus.bind(this));
|
||||
this.domNode.addEventListener('blur', this.handleBlur.bind(this));
|
||||
|
||||
if (this.isExpandable) {
|
||||
this.domNode.firstElementChild.addEventListener('mouseover', this.handleMouseOver.bind(this));
|
||||
this.domNode.firstElementChild.addEventListener('mouseout', this.handleMouseOut.bind(this));
|
||||
}
|
||||
else {
|
||||
this.domNode.addEventListener('mouseover', this.handleMouseOver.bind(this));
|
||||
this.domNode.addEventListener('mouseout', this.handleMouseOut.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.isExpanded = function () {
|
||||
|
||||
if (this.isExpandable) {
|
||||
return this.domNode.getAttribute('aria-expanded') === 'true';
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
/* EVENT HANDLERS */
|
||||
|
||||
TreeitemLink.prototype.handleKeydown = function (event) {
|
||||
var tgt = event.currentTarget,
|
||||
flag = false,
|
||||
_char = event.key,
|
||||
clickEvent;
|
||||
|
||||
function isPrintableCharacter(str) {
|
||||
return str.length === 1 && str.match(/\S/);
|
||||
}
|
||||
|
||||
function printableCharacter(item) {
|
||||
if (_char == '*') {
|
||||
item.tree.expandAllSiblingItems(item);
|
||||
flag = true;
|
||||
}
|
||||
else {
|
||||
if (isPrintableCharacter(_char)) {
|
||||
item.tree.setFocusByFirstCharacter(item, _char);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.stopDefaultClick = false;
|
||||
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.shift) {
|
||||
if (event.keyCode == this.keyCode.SPACE || event.keyCode == this.keyCode.RETURN) {
|
||||
event.stopPropagation();
|
||||
this.stopDefaultClick = true;
|
||||
}
|
||||
else {
|
||||
if (isPrintableCharacter(_char)) {
|
||||
printableCharacter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (event.keyCode) {
|
||||
case this.keyCode.SPACE:
|
||||
case this.keyCode.RETURN:
|
||||
if (this.isExpandable) {
|
||||
if (this.isExpanded()) {
|
||||
this.tree.collapseTreeitem(this);
|
||||
}
|
||||
else {
|
||||
this.tree.expandTreeitem(this);
|
||||
}
|
||||
flag = true;
|
||||
}
|
||||
else {
|
||||
event.stopPropagation();
|
||||
this.stopDefaultClick = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case this.keyCode.UP:
|
||||
this.tree.setFocusToPreviousItem(this);
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case this.keyCode.DOWN:
|
||||
this.tree.setFocusToNextItem(this);
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case this.keyCode.RIGHT:
|
||||
if (this.isExpandable) {
|
||||
if (this.isExpanded()) {
|
||||
this.tree.setFocusToNextItem(this);
|
||||
}
|
||||
else {
|
||||
this.tree.expandTreeitem(this);
|
||||
}
|
||||
}
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case this.keyCode.LEFT:
|
||||
if (this.isExpandable && this.isExpanded()) {
|
||||
this.tree.collapseTreeitem(this);
|
||||
flag = true;
|
||||
}
|
||||
else {
|
||||
if (this.inGroup) {
|
||||
this.tree.setFocusToParentItem(this);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case this.keyCode.HOME:
|
||||
this.tree.setFocusToFirstItem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case this.keyCode.END:
|
||||
this.tree.setFocusToLastItem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isPrintableCharacter(_char)) {
|
||||
printableCharacter(this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.handleClick = function (event) {
|
||||
|
||||
// only process click events that directly happened on this treeitem
|
||||
if (event.target !== this.domNode && event.target !== this.domNode.firstElementChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isExpandable) {
|
||||
if (this.isExpanded()) {
|
||||
this.tree.collapseTreeitem(this);
|
||||
}
|
||||
else {
|
||||
this.tree.expandTreeitem(this);
|
||||
}
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.handleFocus = function (event) {
|
||||
var node = this.domNode;
|
||||
if (this.isExpandable) {
|
||||
node = node.firstElementChild;
|
||||
}
|
||||
node.classList.add('focus');
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.handleBlur = function (event) {
|
||||
var node = this.domNode;
|
||||
if (this.isExpandable) {
|
||||
node = node.firstElementChild;
|
||||
}
|
||||
node.classList.remove('focus');
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.handleMouseOver = function (event) {
|
||||
event.currentTarget.classList.add('hover');
|
||||
};
|
||||
|
||||
TreeitemLink.prototype.handleMouseOut = function (event) {
|
||||
event.currentTarget.classList.remove('hover');
|
||||
};
|
||||
|
||||
return TreeitemLink;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Creates a new TreeLinks.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @class
|
||||
* @private
|
||||
* @see {@link https://www.w3.org/TR/wai-aria-practices-1.1/examples/treeview/treeview-2/treeview-2b.html|W3C Treeview Example}
|
||||
* @license W3C-20150513
|
||||
*/
|
||||
TreeLinks = (function () {
|
||||
/*
|
||||
* This content is licensed according to the W3C Software License at
|
||||
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
||||
*
|
||||
* File: TreeLinks.js
|
||||
*
|
||||
* Desc: Tree widget that implements ARIA Authoring Practices
|
||||
* for a tree being used as a file viewer
|
||||
*
|
||||
* Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt
|
||||
*/
|
||||
|
||||
/*
|
||||
* @constructor
|
||||
*
|
||||
* @desc
|
||||
* Tree item object for representing the state and user interactions for a
|
||||
* tree widget
|
||||
*
|
||||
* @param node
|
||||
* An element with the role=tree attribute
|
||||
*/
|
||||
|
||||
var TreeLinks = function (node) {
|
||||
// Check whether node is a DOM element
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.domNode = node;
|
||||
|
||||
this.treeitems = [];
|
||||
this.firstChars = [];
|
||||
|
||||
this.firstTreeitem = null;
|
||||
this.lastTreeitem = null;
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.init = function () {
|
||||
|
||||
function findTreeitems(node, tree, group) {
|
||||
|
||||
var elem = node.firstElementChild;
|
||||
var ti = group;
|
||||
|
||||
while (elem) {
|
||||
|
||||
if ((elem.tagName.toLowerCase() === 'li' && elem.firstElementChild.tagName.toLowerCase() === 'span') || elem.tagName.toLowerCase() === 'a') {
|
||||
ti = new TreeitemLink(elem, tree, group);
|
||||
ti.init();
|
||||
tree.treeitems.push(ti);
|
||||
tree.firstChars.push(ti.label.substring(0, 1).toLowerCase());
|
||||
}
|
||||
|
||||
if (elem.firstElementChild) {
|
||||
findTreeitems(elem, tree, ti);
|
||||
}
|
||||
|
||||
elem = elem.nextElementSibling;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize pop up menus
|
||||
if (!this.domNode.getAttribute('role')) {
|
||||
this.domNode.setAttribute('role', 'tree');
|
||||
}
|
||||
|
||||
findTreeitems(this.domNode, this, false);
|
||||
|
||||
this.updateVisibleTreeitems();
|
||||
|
||||
this.firstTreeitem.domNode.tabIndex = 0;
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToItem = function (treeitem) {
|
||||
|
||||
for (var i = 0; i < this.treeitems.length; i++) {
|
||||
var ti = this.treeitems[i];
|
||||
|
||||
if (ti === treeitem) {
|
||||
ti.domNode.tabIndex = 0;
|
||||
ti.domNode.focus();
|
||||
}
|
||||
else {
|
||||
ti.domNode.tabIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToNextItem = function (currentItem) {
|
||||
|
||||
var nextItem = false;
|
||||
|
||||
for (var i = (this.treeitems.length - 1); i >= 0; i--) {
|
||||
var ti = this.treeitems[i];
|
||||
if (ti === currentItem) {
|
||||
break;
|
||||
}
|
||||
if (ti.isVisible) {
|
||||
nextItem = ti;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextItem) {
|
||||
this.setFocusToItem(nextItem);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToPreviousItem = function (currentItem) {
|
||||
|
||||
var prevItem = false;
|
||||
|
||||
for (var i = 0; i < this.treeitems.length; i++) {
|
||||
var ti = this.treeitems[i];
|
||||
if (ti === currentItem) {
|
||||
break;
|
||||
}
|
||||
if (ti.isVisible) {
|
||||
prevItem = ti;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevItem) {
|
||||
this.setFocusToItem(prevItem);
|
||||
}
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToParentItem = function (currentItem) {
|
||||
|
||||
if (currentItem.groupTreeitem) {
|
||||
this.setFocusToItem(currentItem.groupTreeitem);
|
||||
}
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToFirstItem = function () {
|
||||
this.setFocusToItem(this.firstTreeitem);
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusToLastItem = function () {
|
||||
this.setFocusToItem(this.lastTreeitem);
|
||||
};
|
||||
|
||||
TreeLinks.prototype.expandTreeitem = function (currentItem) {
|
||||
|
||||
if (currentItem.isExpandable) {
|
||||
currentItem.domNode.setAttribute('aria-expanded', true);
|
||||
this.updateVisibleTreeitems();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.expandAllSiblingItems = function (currentItem) {
|
||||
for (var i = 0; i < this.treeitems.length; i++) {
|
||||
var ti = this.treeitems[i];
|
||||
|
||||
if ((ti.groupTreeitem === currentItem.groupTreeitem) && ti.isExpandable) {
|
||||
this.expandTreeitem(ti);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.collapseTreeitem = function (currentItem) {
|
||||
|
||||
var groupTreeitem = false;
|
||||
|
||||
if (currentItem.isExpanded()) {
|
||||
groupTreeitem = currentItem;
|
||||
}
|
||||
else {
|
||||
groupTreeitem = currentItem.groupTreeitem;
|
||||
}
|
||||
|
||||
if (groupTreeitem) {
|
||||
groupTreeitem.domNode.setAttribute('aria-expanded', false);
|
||||
this.updateVisibleTreeitems();
|
||||
this.setFocusToItem(groupTreeitem);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.updateVisibleTreeitems = function () {
|
||||
|
||||
this.firstTreeitem = this.treeitems[0];
|
||||
|
||||
for (var i = 0; i < this.treeitems.length; i++) {
|
||||
var ti = this.treeitems[i];
|
||||
|
||||
var parent = ti.domNode.parentNode;
|
||||
|
||||
ti.isVisible = true;
|
||||
|
||||
while (parent && (parent !== this.domNode)) {
|
||||
|
||||
if (parent.getAttribute('aria-expanded') == 'false') {
|
||||
ti.isVisible = false;
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
if (ti.isVisible) {
|
||||
this.lastTreeitem = ti;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TreeLinks.prototype.setFocusByFirstCharacter = function (currentItem, _char) {
|
||||
var start, index;
|
||||
_char = _char.toLowerCase();
|
||||
|
||||
// Get start index for search based on position of currentItem
|
||||
start = this.treeitems.indexOf(currentItem) + 1;
|
||||
if (start === this.treeitems.length) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
// Check remaining slots in the menu
|
||||
index = this.getIndexFirstChars(start, _char);
|
||||
|
||||
// If not found in remaining slots, check from beginning
|
||||
if (index === -1) {
|
||||
index = this.getIndexFirstChars(0, _char);
|
||||
}
|
||||
|
||||
// If match was found...
|
||||
if (index > -1) {
|
||||
this.setFocusToItem(this.treeitems[index]);
|
||||
}
|
||||
};
|
||||
|
||||
TreeLinks.prototype.getIndexFirstChars = function (startIndex, _char) {
|
||||
for (var i = startIndex; i < this.firstChars.length; i++) {
|
||||
if (this.treeitems[i].isVisible) {
|
||||
if (_char === this.firstChars[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
return TreeLinks;
|
||||
})();
|
||||
|
||||
/* jshint ignore:end */
|
||||
/* jscs:enable */
|
||||
/* eslint-enable */
|
||||
|
||||
return component;
|
||||
})( jQuery );
|
||||
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
2065
wp-admin/js/theme.js
Normal file
2065
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
2480
wp-admin/js/updates.js
Normal file
2480
wp-admin/js/updates.js
Normal file
File diff suppressed because it is too large
Load diff
2
wp-admin/js/updates.min.js
vendored
Normal file
2
wp-admin/js/updates.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
470
wp-admin/js/user-profile.js
Normal file
470
wp-admin/js/user-profile.js
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
/* global ajaxurl, pwsL10n, userProfileL10n */
|
||||
(function($) {
|
||||
var updateLock = false,
|
||||
|
||||
$pass1Row,
|
||||
$pass1Wrap,
|
||||
$pass1,
|
||||
$pass1Text,
|
||||
$pass1Label,
|
||||
$pass2,
|
||||
$weakRow,
|
||||
$weakCheckbox,
|
||||
$toggleButton,
|
||||
$submitButtons,
|
||||
$submitButton,
|
||||
currentPass,
|
||||
inputEvent;
|
||||
|
||||
/*
|
||||
* Use feature detection to determine whether password inputs should use
|
||||
* the `keyup` or `input` event. Input is preferred but lacks support
|
||||
* in legacy browsers.
|
||||
*/
|
||||
if ( 'oninput' in document.createElement( 'input' ) ) {
|
||||
inputEvent = 'input';
|
||||
} else {
|
||||
inputEvent = 'keyup';
|
||||
}
|
||||
|
||||
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 ) ) {
|
||||
$pass1Wrap.addClass( 'show-password' );
|
||||
} else {
|
||||
$toggleButton.trigger( 'click' );
|
||||
}
|
||||
|
||||
// Once zxcvbn loads, passwords strength is known.
|
||||
$( '#pw-weak-text-label' ).html( userProfileL10n.warnWeak );
|
||||
}
|
||||
|
||||
function bindPass1() {
|
||||
currentPass = $pass1.val();
|
||||
|
||||
$pass1Wrap = $pass1.parent();
|
||||
|
||||
$pass1Text = $( '<input type="text"/>' )
|
||||
.attr( {
|
||||
'id': 'pass1-text',
|
||||
'name': 'pass1-text',
|
||||
'autocomplete': 'off'
|
||||
} )
|
||||
.addClass( $pass1[0].className )
|
||||
.data( 'pw', $pass1.data( 'pw' ) )
|
||||
.val( $pass1.val() )
|
||||
.on( inputEvent, function () {
|
||||
if ( $pass1Text.val() === currentPass ) {
|
||||
return;
|
||||
}
|
||||
$pass2.val( $pass1Text.val() );
|
||||
$pass1.val( $pass1Text.val() ).trigger( 'pwupdate' );
|
||||
currentPass = $pass1Text.val();
|
||||
} );
|
||||
|
||||
$pass1.after( $pass1Text );
|
||||
|
||||
if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
|
||||
generatePassword();
|
||||
}
|
||||
|
||||
$pass1.on( inputEvent + ' pwupdate', function () {
|
||||
if ( $pass1.val() === currentPass ) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentPass = $pass1.val();
|
||||
if ( $pass1Text.val() !== currentPass ) {
|
||||
$pass1Text.val( currentPass );
|
||||
}
|
||||
$pass1.add( $pass1Text ).removeClass( 'short bad good strong' );
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
} );
|
||||
}
|
||||
|
||||
function resetToggle() {
|
||||
$toggleButton
|
||||
.data( 'toggle', 0 )
|
||||
.attr({
|
||||
'aria-label': userProfileL10n.ariaHide
|
||||
})
|
||||
.find( '.text' )
|
||||
.text( userProfileL10n.hide )
|
||||
.end()
|
||||
.find( '.dashicons' )
|
||||
.removeClass( 'dashicons-visibility' )
|
||||
.addClass( 'dashicons-hidden' );
|
||||
|
||||
$pass1Text.focus();
|
||||
|
||||
$pass1Label.attr( 'for', 'pass1-text' );
|
||||
}
|
||||
|
||||
function bindToggleButton() {
|
||||
$toggleButton = $pass1Row.find('.wp-hide-pw');
|
||||
$toggleButton.show().on( 'click', function () {
|
||||
if ( 1 === parseInt( $toggleButton.data( 'toggle' ), 10 ) ) {
|
||||
$pass1Wrap.addClass( 'show-password' );
|
||||
|
||||
resetToggle();
|
||||
|
||||
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
|
||||
$pass1Text[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
} else {
|
||||
$pass1Wrap.removeClass( 'show-password' );
|
||||
$toggleButton
|
||||
.data( 'toggle', 1 )
|
||||
.attr({
|
||||
'aria-label': userProfileL10n.ariaShow
|
||||
})
|
||||
.find( '.text' )
|
||||
.text( userProfileL10n.show )
|
||||
.end()
|
||||
.find( '.dashicons' )
|
||||
.removeClass('dashicons-hidden')
|
||||
.addClass('dashicons-visibility');
|
||||
|
||||
$pass1.focus();
|
||||
|
||||
$pass1Label.attr( 'for', 'pass1' );
|
||||
|
||||
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
|
||||
$pass1[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindPasswordForm() {
|
||||
var $passwordWrapper,
|
||||
$generateButton,
|
||||
$cancelButton;
|
||||
|
||||
$pass1Row = $('.user-pass1-wrap');
|
||||
$pass1Label = $pass1Row.find('th label').attr( 'for', 'pass1-text' );
|
||||
|
||||
// hide this
|
||||
$('.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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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( inputEvent, 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 );
|
||||
$pass1Text.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 );
|
||||
$pass1Text.attr( 'disabled', false );
|
||||
|
||||
if ( $pass1Text.val().length === 0 ) {
|
||||
generatePassword();
|
||||
}
|
||||
|
||||
_.defer( function() {
|
||||
$pass1Text.focus();
|
||||
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
|
||||
$pass1Text[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
}, 0 );
|
||||
} );
|
||||
|
||||
$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
|
||||
$cancelButton.on( 'click', function () {
|
||||
updateLock = false;
|
||||
|
||||
// Clear any entered password.
|
||||
$pass1Text.val( '' );
|
||||
|
||||
// Generate a new password.
|
||||
wp.ajax.post( 'generate-password' )
|
||||
.done( function( data ) {
|
||||
$pass1.data( 'pw', data );
|
||||
} );
|
||||
|
||||
$generateButton.show();
|
||||
$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 );
|
||||
$pass1Text.prop( 'disabled', true );
|
||||
|
||||
resetToggle();
|
||||
|
||||
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() );
|
||||
$pass1Wrap.removeClass( 'show-password' );
|
||||
});
|
||||
}
|
||||
|
||||
function check_pass_strength() {
|
||||
var pass1 = $('#pass1').val(), strength;
|
||||
|
||||
$('#pass-strength-result').removeClass('short bad good strong');
|
||||
if ( ! pass1 ) {
|
||||
$('#pass-strength-result').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.add( $pass1Text ).addClass( passStrength.className );
|
||||
if ( $( passStrength ).is( '.short, .bad' ) ) {
|
||||
if ( ! $weakCheckbox.prop( 'checked' ) ) {
|
||||
$submitButtons.prop( 'disabled', true );
|
||||
}
|
||||
$weakRow.show();
|
||||
} 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( inputEvent + ' 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
30
wp-admin/js/user-suggest.js
Normal file
30
wp-admin/js/user-suggest.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* 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';
|
||||
}
|
||||
$( '.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(a){var b="undefined"!=typeof current_site_id?"&site_id="+current_site_id:"";a(document).ready(function(){var c={offset:"0, -1"};"undefined"!=typeof isRtl&&isRtl&&(c.my="right top",c.at="right bottom"),a(".wp-suggest-user").each(function(){var d=a(this),e="undefined"!=typeof d.data("autocompleteType")?d.data("autocompleteType"):"add",f="undefined"!=typeof d.data("autocompleteField")?d.data("autocompleteField"):"user_login";d.autocomplete({source:ajaxurl+"?action=autocomplete-user&autocomplete_type="+e+"&autocomplete_field="+f+b,delay:500,minLength:2,position:c,open:function(){a(this).addClass("open")},close:function(){a(this).removeClass("open")}})})})}(jQuery);
|
||||
740
wp-admin/js/widgets.js
Normal file
740
wp-admin/js/widgets.js
Normal file
|
|
@ -0,0 +1,740 @@
|
|||
/*global ajaxurl, isRtl */
|
||||
var wpWidgets;
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
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}'
|
||||
},
|
||||
|
||||
/**
|
||||
* 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' );
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
} 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 );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-close') ) {
|
||||
widget = target.closest('div.widget');
|
||||
widget.removeClass( 'open' );
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
wpWidgets.close( widget );
|
||||
e.preventDefault();
|
||||
} 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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(),
|
||||
id = $element.find( '.widgets-sortables' ).attr( 'id' ),
|
||||
li = $('<li tabindex="0">').text( $.trim( name ) );
|
||||
|
||||
if ( index === 0 ) {
|
||||
li.addClass( 'widgets-chooser-selected' );
|
||||
}
|
||||
|
||||
selectSidebar.append( li );
|
||||
li.data( 'sidebarId', id );
|
||||
});
|
||||
|
||||
$( '#available-widgets .widget .widget-title' ).on( 'click.widgets-chooser', function() {
|
||||
var $widget = $(this).closest( '.widget' );
|
||||
|
||||
if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
|
||||
self.closeChooser();
|
||||
} else {
|
||||
// Open the chooser
|
||||
self.clearWidgetSelection();
|
||||
$( '#widgets-left' ).addClass( 'chooser' );
|
||||
$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
|
||||
|
||||
chooser.slideDown( 300, function() {
|
||||
selectSidebar.find('.widgets-chooser-selected').focus();
|
||||
});
|
||||
|
||||
selectSidebar.find( 'li' ).on( 'focusin.widgets-chooser', function() {
|
||||
selectSidebar.find('.widgets-chooser-selected').removeClass( 'widgets-chooser-selected' );
|
||||
$(this).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.ENTER ) {
|
||||
if ( $( event.target ).hasClass( 'widgets-chooser-cancel' ) ) {
|
||||
// Close instead of adding when pressing Enter on the Cancel button
|
||||
self.closeChooser();
|
||||
} else {
|
||||
self.addWidget( chooser );
|
||||
self.closeChooser();
|
||||
}
|
||||
} else 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');
|
||||
}, 250 );
|
||||
},
|
||||
|
||||
closeChooser: function() {
|
||||
var self = this;
|
||||
|
||||
$( '.widgets-chooser' ).slideUp( 200, function() {
|
||||
$( '#wpbody-content' ).append( this );
|
||||
self.clearWidgetSelection();
|
||||
});
|
||||
},
|
||||
|
||||
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
429
wp-admin/js/widgets/custom-html-widgets.js
Normal file
429
wp-admin/js/widgets/custom-html-widgets.js
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
/* global wp */
|
||||
/* eslint consistent-this: [ "error", "control" ] */
|
||||
/* eslint no-magic-numbers: ["error", { "ignore": [0,1,-1] }] */
|
||||
wp.customHtmlWidgets = ( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var component = {
|
||||
idBases: [ 'custom_html' ],
|
||||
codeEditorSettings: {},
|
||||
l10n: {
|
||||
errorNotice: {
|
||||
singular: '',
|
||||
plural: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Text widget control.
|
||||
*
|
||||
* @class CustomHtmlWidgetControl
|
||||
* @constructor
|
||||
* @abstract
|
||||
*/
|
||||
component.CustomHtmlWidgetControl = Backbone.View.extend({
|
||||
|
||||
/**
|
||||
* View events.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
events: {},
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @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;
|
||||
if ( ! control.contentUpdateBypassed ) {
|
||||
syncInput = control.syncContainer.find( '.sync-input.content' );
|
||||
control.fields.content.val( syncInput.val() ).trigger( 'change' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onTabPrevious: function onTabPrevious() {
|
||||
control.fields.title.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field after the editor.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @param {Array} errorAnnotations - Error notifications.
|
||||
* @returns {void}
|
||||
*/
|
||||
onChangeLintingErrors: function onChangeLintingErrors( errorAnnotations ) {
|
||||
control.currentErrorAnnotations = errorAnnotations;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update error notice.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @type {Object.<string, wp.textWidgets.CustomHtmlWidgetControl>}
|
||||
*/
|
||||
component.widgetControls = {};
|
||||
|
||||
/**
|
||||
* Handle widget being added or initialized for the first time at the widget-added event.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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().
|
||||
*
|
||||
* @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
150
wp-admin/js/widgets/media-audio-widget.js
Normal file
150
wp-admin/js/widgets/media-audio-widget.js
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/* eslint consistent-this: [ "error", "control" ] */
|
||||
(function( component ) {
|
||||
'use strict';
|
||||
|
||||
var AudioWidgetModel, AudioWidgetControl, AudioDetailsMediaFrame;
|
||||
|
||||
/**
|
||||
* Custom audio details frame that removes the replace-audio state.
|
||||
*
|
||||
* @class AudioDetailsMediaFrame
|
||||
* @constructor
|
||||
*/
|
||||
AudioDetailsMediaFrame = wp.media.view.MediaFrame.AudioDetails.extend({
|
||||
|
||||
/**
|
||||
* 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 AudioWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
AudioWidgetModel = component.MediaWidgetModel.extend({});
|
||||
|
||||
/**
|
||||
* Audio widget control.
|
||||
*
|
||||
* See WP_Widget_Audio::enqueue_admin_scripts() for amending prototype from PHP exports.
|
||||
*
|
||||
* @class AudioWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
AudioWidgetControl = component.MediaWidgetControl.extend({
|
||||
|
||||
/**
|
||||
* 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(a){"use strict";var b,c,d;d=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})])}}),b=a.MediaWidgetModel.extend({}),c=a.MediaWidgetControl.extend({showDisplaySettings:!1,mapModelToMediaFrameProps:function(b){var c,d=this;return c=a.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call(d,b),c.link="embed",c},renderPreview:function(){var a,b,c,d,e=this;c=e.model.get("attachment_id"),d=e.model.get("url"),(c||d)&&(a=e.$el.find(".media-widget-preview"),b=wp.template("wp-media-widget-audio-preview"),a.html(b({model:{attachment_id:e.model.get("attachment_id"),src:d},error:e.model.get("error")})),wp.mediaelement.initialize())},editMedia:function(){var a,b,c,e=this;b=e.mapModelToMediaFrameProps(e.model.toJSON()),a=new d({frame:"audio",state:"audio-details",metadata:b}),wp.media.frame=a,a.$el.addClass("media-widget"),c=function(a){e.selectedAttachment.set(a),e.model.set(_.extend(e.model.defaults(),e.mapMediaToModelProps(a),{error:!1}))},a.state("audio-details").on("update",c),a.state("replace-audio").on("replace",c),a.on("close",function(){a.detach()}),a.open()}}),a.controlConstructors.media_audio=c,a.modelConstructors.media_audio=b}(wp.mediaWidgets);
|
||||
340
wp-admin/js/widgets/media-gallery-widget.js
Normal file
340
wp-admin/js/widgets/media-gallery-widget.js
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* eslint consistent-this: [ "error", "control" ] */
|
||||
(function( component ) {
|
||||
'use strict';
|
||||
|
||||
var GalleryWidgetModel, GalleryWidgetControl, GalleryDetailsMediaFrame;
|
||||
|
||||
/**
|
||||
* Custom gallery details frame.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @class GalleryDetailsMediaFrame
|
||||
* @constructor
|
||||
*/
|
||||
GalleryDetailsMediaFrame = wp.media.view.MediaFrame.Post.extend( {
|
||||
|
||||
/**
|
||||
* 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 GalleryWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
GalleryWidgetModel = component.MediaWidgetModel.extend( {} );
|
||||
|
||||
/**
|
||||
* Gallery widget control.
|
||||
*
|
||||
* See WP_Widget_Gallery::enqueue_admin_scripts() for amending prototype from PHP exports.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @class GalleryWidgetControl
|
||||
* @constructor
|
||||
*/
|
||||
GalleryWidgetControl = component.MediaWidgetControl.extend( {
|
||||
|
||||
/**
|
||||
* View events.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @type {object}
|
||||
*/
|
||||
events: _.extend( {}, component.MediaWidgetControl.prototype.events, {
|
||||
'click .media-widget-gallery-preview': 'editMedia'
|
||||
} ),
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @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(a){"use strict";var b,c,d;d=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])}}),b=a.MediaWidgetModel.extend({}),c=a.MediaWidgetControl.extend({events:_.extend({},a.MediaWidgetControl.prototype.events,{"click .media-widget-gallery-preview":"editMedia"}),initialize:function(b){var c=this;a.MediaWidgetControl.prototype.initialize.call(c,b),_.bindAll(c,"updateSelectedAttachments","handleAttachmentDestroy"),c.selectedAttachments=new wp.media.model.Attachments,c.model.on("change:ids",c.updateSelectedAttachments),c.selectedAttachments.on("change",c.renderPreview),c.selectedAttachments.on("reset",c.renderPreview),c.updateSelectedAttachments(),wp.customize&&wp.customize.previewer&&c.selectedAttachments.on("change",function(){wp.customize.previewer.send("refresh-widget-partial",c.model.get("widget_id"))})},updateSelectedAttachments:function(){var a,b,c,d,e,f=this;a=f.model.get("ids"),b=_.pluck(f.selectedAttachments.models,"id"),c=_.difference(b,a),_.each(c,function(a){f.selectedAttachments.remove(f.selectedAttachments.get(a))}),d=_.difference(a,b),d.length&&(e=wp.media.query({order:"ASC",orderby:"post__in",perPage:-1,post__in:a,query:!0,type:"image"}),e.more().done(function(){f.selectedAttachments.reset(e.models)}))},renderPreview:function(){var a,b,c,d=this;a=d.$el.find(".media-widget-preview"),b=wp.template("wp-media-widget-gallery-preview"),c=d.previewTemplateProps.toJSON(),c.attachments={},d.selectedAttachments.each(function(a){c.attachments[a.id]=a.toJSON()}),a.html(b(c))},isSelected:function(){var a=this;return!a.model.get("error")&&a.model.get("ids").length>0},editMedia:function(){var a,b,c,e=this;a=new wp.media.model.Selection(e.selectedAttachments.models,{multiple:!0}),c=e.mapModelToMediaFrameProps(e.model.toJSON()),a.gallery=new Backbone.Model(c),c.size&&e.displaySettings.set("size",c.size),b=new d({frame:"manage",text:e.l10n.add_to_widget,selection:a,mimeType:e.mime_type,selectedDisplaySettings:e.displaySettings,showDisplaySettings:e.showDisplaySettings,metadata:c,editing:!0,multiple:!0,state:"gallery-edit"}),wp.media.frame=b,b.on("update",function(a){var c,d=b.state();c=a||d.get("selection"),c&&(c.gallery&&e.model.set(e.mapMediaToModelProps(c.gallery.toJSON())),e.selectedAttachments.reset(c.models),e.model.set({ids:_.pluck(c.models,"id")}))}),b.$el.addClass("media-widget"),b.open(),a&&a.on("destroy",e.handleAttachmentDestroy)},selectMedia:function(){var a,b,c,e=this;a=new wp.media.model.Selection(e.selectedAttachments.models,{multiple:!0}),c=e.mapModelToMediaFrameProps(e.model.toJSON()),c.size&&e.displaySettings.set("size",c.size),b=new d({frame:"select",text:e.l10n.add_to_widget,selection:a,mimeType:e.mime_type,selectedDisplaySettings:e.displaySettings,showDisplaySettings:e.showDisplaySettings,metadata:c,state:"gallery"}),wp.media.frame=b,b.on("update",function(a){var c,d=b.state();c=a||d.get("selection"),c&&(c.gallery&&e.model.set(e.mapMediaToModelProps(c.gallery.toJSON())),e.selectedAttachments.reset(c.models),e.model.set({ids:_.pluck(c.models,"id")}))}),b.$el.addClass("media-widget"),b.open(),a&&a.on("destroy",e.handleAttachmentDestroy),b.$el.find(":focusable:first").focus()},handleAttachmentDestroy:function(a){var b=this;b.model.set({ids:_.difference(b.model.get("ids"),[a.id])})}}),a.controlConstructors.media_gallery=c,a.modelConstructors.media_gallery=b}(wp.mediaWidgets);
|
||||
166
wp-admin/js/widgets/media-image-widget.js
Normal file
166
wp-admin/js/widgets/media-image-widget.js
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/* 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 ImageWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
ImageWidgetModel = component.MediaWidgetModel.extend({});
|
||||
|
||||
/**
|
||||
* Image widget control.
|
||||
*
|
||||
* See WP_Widget_Media_Image::enqueue_admin_scripts() for amending prototype from PHP exports.
|
||||
*
|
||||
* @class ImageWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
ImageWidgetControl = component.MediaWidgetControl.extend({
|
||||
|
||||
/**
|
||||
* 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,b){"use strict";var c,d;c=a.MediaWidgetModel.extend({}),d=a.MediaWidgetControl.extend({events:_.extend({},a.MediaWidgetControl.prototype.events,{"click .media-widget-preview.populated":"editMedia"}),renderPreview:function(){var a,b,c,d,e,f=this;(f.model.get("attachment_id")||f.model.get("url"))&&(a=f.$el.find(".media-widget-preview"),b=wp.template("wp-media-widget-image-preview"),a.html(b(f.previewTemplateProps.toJSON())),a.addClass("populated"),e=f.$el.find(".link"),e.is(document.activeElement)||(c=f.$el.find(".media-widget-fields"),d=wp.template("wp-media-widget-image-fields"),c.html(d(f.previewTemplateProps.toJSON()))))},editMedia:function(){var a,c,d,e,f=this;e=f.mapModelToMediaFrameProps(f.model.toJSON()),"none"===e.link&&(e.linkUrl=""),a=wp.media({frame:"image",state:"image-details",metadata:e}),a.$el.addClass("media-widget"),c=function(){var b,c;b=a.state().attributes.image.toJSON(),c=b.link,b.link=b.linkUrl,f.selectedAttachment.set(b),f.displaySettings.set("link",c),f.model.set(_.extend(f.mapMediaToModelProps(b),{error:!1}))},a.state("image-details").on("update",c),a.state("replace-image").on("replace",c),d=wp.media.model.Attachment.prototype.sync,wp.media.model.Attachment.prototype.sync=function(){return b.Deferred().rejectWith(this).promise()},a.on("close",function(){a.detach(),wp.media.model.Attachment.prototype.sync=d}),a.open()},getEmbedResetProps:function(){return _.extend(a.MediaWidgetControl.prototype.getEmbedResetProps.call(this),{size:"full",width:0,height:0})},getModelPropsFromMediaFrame:function(b){var c=this;return _.omit(a.MediaWidgetControl.prototype.getModelPropsFromMediaFrame.call(c,b),"image_title")},mapModelToPreviewTemplateProps:function(){var b,c,d=this;return c=d.model.get("url"),b=a.MediaWidgetControl.prototype.mapModelToPreviewTemplateProps.call(d),b.currentFilename=c?c.replace(/\?.*$/,"").replace(/^.+\//,""):"",b.link_url=d.model.get("link_url"),b}}),a.controlConstructors.media_image=d,a.modelConstructors.media_image=c}(wp.mediaWidgets,jQuery);
|
||||
250
wp-admin/js/widgets/media-video-widget.js
Normal file
250
wp-admin/js/widgets/media-video-widget.js
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/* eslint consistent-this: [ "error", "control" ] */
|
||||
(function( component ) {
|
||||
'use strict';
|
||||
|
||||
var VideoWidgetModel, VideoWidgetControl, VideoDetailsMediaFrame;
|
||||
|
||||
/**
|
||||
* Custom video details frame that removes the replace-video state.
|
||||
*
|
||||
* @class VideoDetailsMediaFrame
|
||||
* @constructor
|
||||
*/
|
||||
VideoDetailsMediaFrame = wp.media.view.MediaFrame.VideoDetails.extend({
|
||||
|
||||
/**
|
||||
* 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 VideoWidgetModel
|
||||
* @constructor
|
||||
*/
|
||||
VideoWidgetModel = component.MediaWidgetModel.extend({});
|
||||
|
||||
/**
|
||||
* Video widget control.
|
||||
*
|
||||
* See WP_Widget_Video::enqueue_admin_scripts() for amending prototype from PHP exports.
|
||||
*
|
||||
* @class VideoWidgetControl
|
||||
* @constructor
|
||||
*/
|
||||
VideoWidgetControl = component.MediaWidgetControl.extend({
|
||||
|
||||
/**
|
||||
* 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(a){"use strict";var b,c,d;d=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"})])}}),b=a.MediaWidgetModel.extend({}),c=a.MediaWidgetControl.extend({showDisplaySettings:!1,oembedResponses:{},mapModelToMediaFrameProps:function(b){var c,d=this;return c=a.MediaWidgetControl.prototype.mapModelToMediaFrameProps.call(d,b),c.link="embed",c},fetchEmbed:function(){var a,b=this;a=b.model.get("url"),b.oembedResponses[a]||(b.fetchEmbedDfd&&"pending"===b.fetchEmbedDfd.state()&&b.fetchEmbedDfd.abort(),b.fetchEmbedDfd=wp.apiRequest({url:wp.media.view.settings.oEmbedProxyUrl,data:{url:b.model.get("url"),maxwidth:b.model.get("width"),maxheight:b.model.get("height"),discover:!1},type:"GET",dataType:"json",context:b}),b.fetchEmbedDfd.done(function(c){b.oembedResponses[a]=c,b.renderPreview()}),b.fetchEmbedDfd.fail(function(){b.oembedResponses[a]=null}))},isHostedVideo:function(){return!0},renderPreview:function(){var a,b,c,d,e,f,g,h,i,j=this,k="",l=!1;c=j.model.get("attachment_id"),d=j.model.get("url"),g=j.model.get("error"),(c||d)&&(f=j.selectedAttachment.get("mime"),f&&c?_.contains(_.values(wp.media.view.settings.embedMimes),f)||(g="unsupported_file_type"):c||(h=document.createElement("a"),h.href=d,i=h.pathname.toLowerCase().match(/\.(\w+)$/),i?_.contains(_.keys(wp.media.view.settings.embedMimes),i[1])||(g="unsupported_file_type"):l=!0),l&&(j.fetchEmbed(),j.oembedResponses[d]&&(e=j.oembedResponses[d].thumbnail_url,k=j.oembedResponses[d].html.replace(/\swidth="\d+"/,' width="100%"').replace(/\sheight="\d+"/,""))),a=j.$el.find(".media-widget-preview"),b=wp.template("wp-media-widget-video-preview"),a.html(b({model:{attachment_id:c,html:k,src:d,poster:e},is_oembed:l,error:g})),wp.mediaelement.initialize())},editMedia:function(){var a,b,c,e=this;b=e.mapModelToMediaFrameProps(e.model.toJSON()),a=new d({frame:"video",state:"video-details",metadata:b}),wp.media.frame=a,a.$el.addClass("media-widget"),c=function(a){e.selectedAttachment.set(a),e.model.set(_.extend(_.omit(e.model.defaults(),"title"),e.mapMediaToModelProps(a),{error:!1}))},a.state("video-details").on("update",c),a.state("replace-video").on("replace",c),a.on("close",function(){a.detach()}),a.open()}}),a.controlConstructors.media_video=c,a.modelConstructors.media_video=b}(wp.mediaWidgets);
|
||||
1306
wp-admin/js/widgets/media-widgets.js
Normal file
1306
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
535
wp-admin/js/widgets/text-widgets.js
Normal file
535
wp-admin/js/widgets/text-widgets.js
Normal file
|
|
@ -0,0 +1,535 @@
|
|||
/* global tinymce, switchEditors */
|
||||
/* eslint consistent-this: [ "error", "control" ] */
|
||||
wp.textWidgets = ( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var component = {
|
||||
dismissedPointers: [],
|
||||
idBases: [ 'text' ]
|
||||
};
|
||||
|
||||
/**
|
||||
* Text widget control.
|
||||
*
|
||||
* @class TextWidgetControl
|
||||
* @constructor
|
||||
* @abstract
|
||||
*/
|
||||
component.TextWidgetControl = Backbone.View.extend({
|
||||
|
||||
/**
|
||||
* View events.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
events: {},
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @type {Object.<string, wp.textWidgets.TextWidgetControl>}
|
||||
*/
|
||||
component.widgetControls = {};
|
||||
|
||||
/**
|
||||
* Handle widget being added or initialized for the first time at the widget-added event.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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().
|
||||
*
|
||||
* @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
220
wp-admin/js/word-count.js
Normal file
220
wp-admin/js/word-count.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/**
|
||||
* Word or character counting functionality. Count words or characters in a provided text string.
|
||||
*
|
||||
* @summary Count words or characters in a text.
|
||||
*
|
||||
* @namespace wp.utils
|
||||
* @since 2.6.0
|
||||
*/
|
||||
|
||||
( 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.
|
||||
*
|
||||
* @summary Count the number of elements in a 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;
|
||||
} )();
|
||||
1
wp-admin/js/word-count.min.js
vendored
Normal file
1
wp-admin/js/word-count.min.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
!function(){function a(a){var b,c;if(a)for(b in a)a.hasOwnProperty(b)&&(this.settings[b]=a[b]);c=this.settings.l10n.shortcodes,c&&c.length&&(this.settings.shortcodesRegExp=new RegExp("\\[\\/?(?:"+c.join("|")+")[^\\]]*?\\]","g"))}a.prototype.settings={HTMLRegExp:/<\/?[a-z][^>]*?>/gi,HTMLcommentRegExp:/<!--[\s\S]*?-->/g,spaceRegExp:/ | /gi,HTMLEntityRegExp:/&\S+?;/g,connectorRegExp:/--|\u2014/g,removeRegExp:new RegExp(["[","!-@[-`{-~","\x80-\xbf\xd7\xf7","\u2000-\u2bff","\u2e00-\u2e7f","]"].join(""),"g"),astralRegExp:/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,wordsRegExp:/\S\s+/g,characters_excluding_spacesRegExp:/\S/g,characters_including_spacesRegExp:/[^\f\n\r\t\v\u00AD\u2028\u2029]/g,l10n:window.wordCountL10n||{}},a.prototype.count=function(a,b){var c=0;return b=b||this.settings.l10n.type,"characters_excluding_spaces"!==b&&"characters_including_spaces"!==b&&(b="words"),a&&(a+="\n",a=a.replace(this.settings.HTMLRegExp,"\n"),a=a.replace(this.settings.HTMLcommentRegExp,""),this.settings.shortcodesRegExp&&(a=a.replace(this.settings.shortcodesRegExp,"\n")),a=a.replace(this.settings.spaceRegExp," "),"words"===b?(a=a.replace(this.settings.HTMLEntityRegExp,""),a=a.replace(this.settings.connectorRegExp," "),a=a.replace(this.settings.removeRegExp,"")):(a=a.replace(this.settings.HTMLEntityRegExp,"a"),a=a.replace(this.settings.astralRegExp,"a")),a=a.match(this.settings[b+"RegExp"]),a&&(c=a.length)),c},window.wp=window.wp||{},window.wp.utils=window.wp.utils||{},window.wp.utils.WordCounter=a}();
|
||||
39
wp-admin/js/wp-fullscreen-stub.js
Normal file
39
wp-admin/js/wp-fullscreen-stub.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Distraction-Free Writing (wp-fullscreen) backward compatibility stub.
|
||||
* Todo: remove at the end of 2016.
|
||||
*
|
||||
* Original was deprecated in 4.1, removed in 4.3.
|
||||
*/
|
||||
( function() {
|
||||
var noop = function(){};
|
||||
|
||||
window.wp = window.wp || {};
|
||||
window.wp.editor = window.wp.editor || {};
|
||||
window.wp.editor.fullscreen = {
|
||||
bind_resize: noop,
|
||||
dfwWidth: noop,
|
||||
off: noop,
|
||||
on: noop,
|
||||
refreshButtons: noop,
|
||||
resizeTextarea: noop,
|
||||
save: noop,
|
||||
switchmode: noop,
|
||||
toggleUI: noop,
|
||||
|
||||
settings: {},
|
||||
pubsub: {
|
||||
publish: noop,
|
||||
subscribe: noop,
|
||||
unsubscribe: noop,
|
||||
topics: {}
|
||||
},
|
||||
fade: {
|
||||
In: noop,
|
||||
Out: noop
|
||||
},
|
||||
ui: {
|
||||
fade: noop,
|
||||
init: noop
|
||||
}
|
||||
};
|
||||
}());
|
||||
1
wp-admin/js/wp-fullscreen-stub.min.js
vendored
Normal file
1
wp-admin/js/wp-fullscreen-stub.min.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
!function(){var a=function(){};window.wp=window.wp||{},window.wp.editor=window.wp.editor||{},window.wp.editor.fullscreen={bind_resize:a,dfwWidth:a,off:a,on:a,refreshButtons:a,resizeTextarea:a,save:a,switchmode:a,toggleUI:a,settings:{},pubsub:{publish:a,subscribe:a,unsubscribe:a,topics:{}},fade:{In:a,Out:a},ui:{fade:a,init:a}}}();
|
||||
273
wp-admin/js/xfn.js
Normal file
273
wp-admin/js/xfn.js
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
jQuery( document ).ready(function( $ ) {
|
||||
$( '#link_rel' ).prop( 'readonly', true );
|
||||
$( '#linkxfndiv input' ).bind( 'click keyup', function() {
|
||||
var isMe = $( '#me' ).is( ':checked' ), inputs = '';
|
||||
$( 'input.valinp' ).each( function() {
|
||||
if ( isMe ) {
|
||||
$( this ).prop( 'disabled', true ).parent().addClass( 'disabled' );
|
||||
} else {
|
||||
$( this ).removeAttr( 'disabled' ).parent().removeClass( 'disabled' );
|
||||
if ( $( this ).is( ':checked' ) && $( this ).val() !== '') {
|
||||
inputs += $( this ).val() + ' ';
|
||||
}
|
||||
}
|
||||
});
|
||||
$( '#link_rel' ).val( ( isMe ) ? 'me' : inputs.substr( 0,inputs.length - 1 ) );
|
||||
});
|
||||
});
|
||||
|
||||
// Privacy request action handling
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
var strings = window.privacyToolsL10n || {};
|
||||
|
||||
function setActionState( $action, state ) {
|
||||
$action.children().hide();
|
||||
$action.children( '.' + state ).show();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
setActionState( $action, 'export-personal-data-success' );
|
||||
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-idle' );
|
||||
|
||||
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, 'notice-success', summaryMessage, messages );
|
||||
}
|
||||
|
||||
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 );
|
||||
});
|
||||
});
|
||||
|
||||
( function( $ ) {
|
||||
|
||||
// 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 ) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} ( jQuery ) );
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue