From 23528d419ab2968f250392e8552095783b138fec Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Mon, 31 Aug 2020 20:28:41 +0000 Subject: [PATCH] Script Loader: Add backward compatibility for JavaScript i18n globals and properties deprecated in WordPress 5.5. The recommended approach for any plugins using these globals or properties is to switch to the newer `wp.i18n` functions. In the meantime, this ensures that accessing any of these globals does not break the rest of the code on the page, and an appropriate warning message is logged to the JavaScript console. Follow-up to: https://core.trac.wordpress.org/query?summary=~wp.i18n&milestone=5.5 Props omarreiss, peterwilsoncc, kbjohnson90, johnbillion, TimothyBlynJacobs, joostdevalk, ocean90, desrosj, SergeyBiryukov. Fixes #51123. git-svn-id: https://develop.svn.wordpress.org/trunk@48923 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/admin/common.js | 335 ++++++++++++++++++++- src/js/_enqueues/admin/widgets.js | 17 ++ src/js/_enqueues/wp/theme-plugin-editor.js | 24 ++ src/js/_enqueues/wp/updates.js | 75 +++++ src/wp-includes/script-loader.php | 4 +- 5 files changed, 452 insertions(+), 3 deletions(-) diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js index 58f68d110f..772ec1f1f7 100644 --- a/src/js/_enqueues/admin/common.js +++ b/src/js/_enqueues/admin/common.js @@ -16,7 +16,340 @@ var $document = $( document ), $window = $( window ), $body = $( document.body ), - __ = wp.i18n.__; + __ = wp.i18n.__, + sprintf = wp.i18n.sprintf; + +/** + * Throws an error for a deprecated property. + * + * @since 5.5.1 + * + * @param {string} propName The property that was used. + * @param {string} version The version of WordPress that deprecated the property. + * @param {string} replacement The property that should have been used. + */ +function deprecatedProperty( propName, version, replacement ) { + var message; + + if ( 'undefined' !== typeof replacement ) { + message = sprintf( + /* translators: 1: Deprecated property name, 2: Version number, 3: Alternative property name. */ + __( '%1$s is deprecated since version %2$s! Use %3$s instead.' ), + propName, + version, + replacement + ); + } else { + message = sprintf( + /* translators: 1: Deprecated property name, 2: Version number. */ + __( '%1$s is deprecated since version %2$s with no alternative available.' ), + propName, + version + ); + } + + window.console.warn( message ); +} + +/** + * Deprecate all properties on an object. + * + * @since 5.5.1 + * + * @param {string} name The name of the object, i.e. commonL10n. + * @param {object} l10nObject The object to deprecate the properties on. + * + * @return {object} The object with all its properties deprecated. + */ +function deprecateL10nObject( name, l10nObject ) { + var deprecatedObject = {}; + + Object.keys( l10nObject ).forEach( function( key ) { + var prop = l10nObject[ key ]; + var propName = name + '.' + key; + + if ( 'object' === typeof prop ) { + Object.defineProperty( deprecatedObject, key, { get: function() { + deprecatedProperty( propName, '5.5.0', prop.alternative ); + return prop.func(); + } } ); + } else { + Object.defineProperty( deprecatedObject, key, { get: function() { + deprecatedProperty( propName, '5.5.0', 'wp.i18n' ); + return prop; + } } ); + } + } ); + + return deprecatedObject; +} + +window.wp.deprecateL10nObject = deprecateL10nObject; + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.6.0 + * @deprecated 5.5.0 + */ +window.commonL10n = window.commonL10n || { + warnDelete: '', + dismiss: '', + collapseMenu: '', + expandMenu: '' +}; + +window.commonL10n = deprecateL10nObject( 'commonL10n', window.commonL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 3.3.0 + * @deprecated 5.5.0 + */ +window.wpPointerL10n = window.wpPointerL10n || { + dismiss: '' +}; + +window.wpPointerL10n = deprecateL10nObject( 'wpPointerL10n', window.wpPointerL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 4.3.0 + * @deprecated 5.5.0 + */ +window.userProfileL10n = window.userProfileL10n || { + warn: '', + warnWeak: '', + show: '', + hide: '', + cancel: '', + ariaShow: '', + ariaHide: '' +}; + +window.userProfileL10n = deprecateL10nObject( 'userProfileL10n', window.userProfileL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 4.9.6 + * @deprecated 5.5.0 + */ +window.privacyToolsL10n = window.privacyToolsL10n || { + noDataFound: '', + foundAndRemoved: '', + noneRemoved: '', + someNotRemoved: '', + removalError: '', + emailSent: '', + noExportFile: '', + exportError: '' +}; + +window.privacyToolsL10n = deprecateL10nObject( 'privacyToolsL10n', window.privacyToolsL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 3.6.0 + * @deprecated 5.5.0 + */ +window.authcheckL10n = { + beforeunload: '' +}; + +window.authcheckL10n = window.authcheckL10n || deprecateL10nObject( 'authcheckL10n', window.authcheckL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.8.0 + * @deprecated 5.5.0 + */ +window.tagsl10n = { + noPerm: '', + broken: '' +}; + +window.tagsl10n = window.tagsl10n || deprecateL10nObject( 'tagsl10n', window.tagsl10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.5.0 + * @deprecated 5.5.0 + */ +window.adminCommentsL10n = window.adminCommentsL10n || { + hotkeys_highlight_first: { + alternative: 'window.adminCommentsSettings.hotkeys_highlight_first', + func: function() { return window.adminCommentsSettings.hotkeys_highlight_first; } + }, + hotkeys_highlight_last: { + alternative: 'window.adminCommentsSettings.hotkeys_highlight_last', + func: function() { return window.adminCommentsSettings.hotkeys_highlight_last; } + }, + replyApprove: '', + reply: '', + warnQuickEdit: '', + warnCommentChanges: '', + docTitleComments: '', + docTitleCommentsCount: '' +}; + +window.adminCommentsL10n = deprecateL10nObject( 'adminCommentsL10n', window.adminCommentsL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.5.0 + * @deprecated 5.5.0 + */ +window.tagsSuggestL10n = window.tagsSuggestL10n || { + tagDelimiter: '', + removeTerm: '', + termSelected: '', + termAdded: '', + termRemoved: '' +}; + +window.tagsSuggestL10n = deprecateL10nObject( 'tagsSuggestL10n', window.tagsSuggestL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 3.5.0 + * @deprecated 5.5.0 + */ +window.wpColorPickerL10n = window.wpColorPickerL10n || { + clear: '', + clearAriaLabel: '', + defaultString: '', + defaultAriaLabel: '', + pick: '', + defaultLabel: '' +}; + +window.wpColorPickerL10n = deprecateL10nObject( 'wpColorPickerL10n', window.wpColorPickerL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.7.0 + * @deprecated 5.5.0 + */ +window.attachMediaBoxL10n = window.attachMediaBoxL10n || { + error: '' +}; + +window.attachMediaBoxL10n = deprecateL10nObject( 'attachMediaBoxL10n', window.attachMediaBoxL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.5.0 + * @deprecated 5.5.0 + */ +window.postL10n = window.postL10n || { + ok: '', + cancel: '', + publishOn: '', + publishOnFuture: '', + publishOnPast: '', + dateFormat: '', + showcomm: '', + endcomm: '', + publish: '', + schedule: '', + update: '', + savePending: '', + saveDraft: '', + 'private': '', + 'public': '', + publicSticky: '', + password: '', + privatelyPublished: '', + published: '', + saveAlert: '', + savingText: '', + permalinkSaved: '' +}; + +window.postL10n = deprecateL10nObject( 'postL10n', window.postL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.7.0 + * @deprecated 5.5.0 + */ +window.inlineEditL10n = window.inlineEditL10n || { + error: '', + ntdeltitle: '', + notitle: '', + comma: '', + saved: '' +}; + +window.inlineEditL10n = deprecateL10nObject( 'inlineEditL10n', window.inlineEditL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.7.0 + * @deprecated 5.5.0 + */ +window.plugininstallL10n = window.plugininstallL10n || { + plugin_information: '', + plugin_modal_label: '', + ays: '' +}; + +window.plugininstallL10n = deprecateL10nObject( 'plugininstallL10n', window.plugininstallL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 3.0.0 + * @deprecated 5.5.0 + */ +window.navMenuL10n = window.navMenuL10n || { + noResultsFound: '', + warnDeleteMenu: '', + saveAlert: '', + untitled: '' +}; + +window.navMenuL10n = deprecateL10nObject( 'navMenuL10n', window.navMenuL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.5.0 + * @deprecated 5.5.0 + */ +window.commentL10n = window.commentL10n || { + submittedOn: '', + dateFormat: '' +}; + +window.commentL10n = deprecateL10nObject( 'commentL10n', window.commentL10n ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 2.9.0 + * @deprecated 5.5.0 + */ +window.setPostThumbnailL10n = window.setPostThumbnailL10n || { + setThumbnail: '', + saving: '', + error: '', + done: '' +}; + +window.setPostThumbnailL10n = deprecateL10nObject( 'setPostThumbnailL10n', window.setPostThumbnailL10n ); /** * Removed in 3.3.0, needed for back-compatibility. diff --git a/src/js/_enqueues/admin/widgets.js b/src/js/_enqueues/admin/widgets.js index e0dac1f4db..fb3759bfc9 100644 --- a/src/js/_enqueues/admin/widgets.js +++ b/src/js/_enqueues/admin/widgets.js @@ -744,3 +744,20 @@ window.wpWidgets = { $document.ready( function(){ wpWidgets.init(); } ); })(jQuery); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 4.9.0 + * @deprecated 5.5.0 + * + * @type {object} +*/ +wpWidgets.l10n = wpWidgets.l10n || { + save: '', + saved: '', + saveAlert: '', + widgetAdded: '' +}; + +wpWidgets.l10n = window.wp.deprecateL10nObject( 'wpWidgets.l10n', wpWidgets.l10n ); diff --git a/src/js/_enqueues/wp/theme-plugin-editor.js b/src/js/_enqueues/wp/theme-plugin-editor.js index 9516b0f003..59e8ce3d0c 100644 --- a/src/js/_enqueues/wp/theme-plugin-editor.js +++ b/src/js/_enqueues/wp/theme-plugin-editor.js @@ -1000,3 +1000,27 @@ wp.themePluginEditor = (function( $ ) { return component; })( jQuery ); + +/** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 4.9.0 + * @deprecated 5.5.0 + * + * @type {object} + */ +wp.themePluginEditor.l10n = wp.themePluginEditor.l10n || { + saveAlert: '', + saveError: '', + lintError: { + alternative: 'wp.i18n', + func: function() { + return { + singular: '', + plural: '' + }; + } + } +}; + +wp.themePluginEditor.l10n = window.wp.deprecateL10nObject( 'wp.themePluginEditor.l10n', wp.themePluginEditor.l10n ); diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index 48a256bd5e..36a9437db9 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -42,6 +42,81 @@ */ wp.updates = {}; + /** + * Removed in 5.5.0, needed for back-compatibility. + * + * @since 4.2.0 + * @deprecated 5.5.0 + * + * @type {object} + */ + wp.updates.l10n = { + searchResults: '', + searchResultsLabel: '', + noPlugins: '', + noItemsSelected: '', + updating: '', + pluginUpdated: '', + themeUpdated: '', + update: '', + updateNow: '', + pluginUpdateNowLabel: '', + updateFailedShort: '', + updateFailed: '', + pluginUpdatingLabel: '', + pluginUpdatedLabel: '', + pluginUpdateFailedLabel: '', + updatingMsg: '', + updatedMsg: '', + updateCancel: '', + beforeunload: '', + installNow: '', + pluginInstallNowLabel: '', + installing: '', + pluginInstalled: '', + themeInstalled: '', + installFailedShort: '', + installFailed: '', + pluginInstallingLabel: '', + themeInstallingLabel: '', + pluginInstalledLabel: '', + themeInstalledLabel: '', + pluginInstallFailedLabel: '', + themeInstallFailedLabel: '', + installingMsg: '', + installedMsg: '', + importerInstalledMsg: '', + aysDelete: '', + aysDeleteUninstall: '', + aysBulkDelete: '', + aysBulkDeleteThemes: '', + deleting: '', + deleteFailed: '', + pluginDeleted: '', + themeDeleted: '', + livePreview: '', + activatePlugin: '', + activateTheme: '', + activatePluginLabel: '', + activateThemeLabel: '', + activateImporter: '', + activateImporterLabel: '', + unknownError: '', + connectionError: '', + nonceError: '', + pluginsFound: '', + noPluginsFound: '', + autoUpdatesEnable: '', + autoUpdatesEnabling: '', + autoUpdatesEnabled: '', + autoUpdatesDisable: '', + autoUpdatesDisabling: '', + autoUpdatesDisabled: '', + autoUpdatesError: '' + }; + + wp.updates.l10n = window.wp.deprecateL10nObject( 'wp.updates.l10n', wp.updates.l10n ); + /** * User nonce for ajax calls. * diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 6f59ec8e06..e0b80803d2 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1013,7 +1013,7 @@ function wp_default_scripts( $scripts ) { $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' ); $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) ); $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror', 'underscore' ) ); - $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) ); + $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'common', 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) ); $scripts->set_translations( 'wp-theme-plugin-editor' ); $scripts->add( 'wp-playlist', "/wp-includes/js/mediaelement/wp-playlist$suffix.js", array( 'wp-util', 'backbone', 'mediaelement' ), false, 1 ); @@ -1261,7 +1261,7 @@ function wp_default_scripts( $scripts ) { $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'privacy-tools' ); - $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize' ), false, 1 ); + $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize' ), false, 1 ); $scripts->set_translations( 'updates' ); did_action( 'init' ) && $scripts->localize( 'updates',