Ticket #38573: 38573.wip.diff
File 38573.wip.diff, 11.4 KB (added by , 8 years ago) |
---|
-
src/wp-admin/js/customize-controls.js
diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js index 56c061f..779bc0b 100644
5095 5095 api.control.add( id, control ); 5096 5096 }); 5097 5097 5098 // @todo Pass allowed arrays? 5099 $.ajaxPrefilter( api.utils.prefilterAjaxPreviewingRequests ); 5100 5098 5101 // Focus the autofocused element 5099 5102 _.each( [ 'panel', 'section', 'control' ], function( type ) { 5100 5103 var id = api.settings.autofocus[ type ]; -
src/wp-includes/js/customize-base.js
diff --git src/wp-includes/js/customize-base.js src/wp-includes/js/customize-base.js index a1528de..131d5ff 100644
window.wp = window.wp || {}; 844 844 return queryParams; 845 845 }; 846 846 847 /** 848 * Should the supplied URL be previewable. 849 * 850 * @since 4.7.0 851 * @access public 852 * 853 * @param {string|HTMLAnchorElement|HTMLAreaElement} url URL. 854 * @param {string} element.search Query string. 855 * @param {string} element.pathname Path. 856 * @param {string} element.host Host. 857 * @param {object} [options] 858 * @param {object} [options.allowAdminAjax=false] Allow admin-ajax.php requests. 859 * @param {object} [options.allowedUrls] Allowed URLs. Defaults to wp.customize.settings.url.allowed. 860 * @returns {boolean} Is appropriate for changeset link. 861 */ 862 api.utils.isUrlPreviewable = function isUrlPreviewable( url, options ) { 863 var matchesAllowedUrl, parsedAllowedUrl, args, element; 864 865 if ( _.isString( url ) ) { 866 element = document.createElement( 'a' ); 867 element.href = url; 868 } else { 869 element = url; 870 } 871 872 args = _.extend( {}, { allowAdminAjax: false }, options || {} ); 873 874 if ( 'javascript:' === element.protocol ) { // jshint ignore:line 875 return true; 876 } 877 878 // Only web URLs can be previewed. 879 if ( 'https:' !== element.protocol && 'http:' !== element.protocol ) { 880 return false; 881 } 882 883 parsedAllowedUrl = document.createElement( 'a' ); 884 matchesAllowedUrl = ! _.isUndefined( _.find( args.allowedUrls || api.settings.url.allowed, function( allowedUrl ) { 885 parsedAllowedUrl.href = allowedUrl; 886 return parsedAllowedUrl.protocol === element.protocol && parsedAllowedUrl.host === element.host && 0 === element.pathname.indexOf( parsedAllowedUrl.pathname.replace( /\/$/, '' ) ); 887 } ) ); 888 if ( ! matchesAllowedUrl ) { 889 return false; 890 } 891 892 // Skip wp login and signup pages. 893 if ( /\/wp-(login|signup)\.php$/.test( element.pathname ) ) { 894 return false; 895 } 896 897 // Allow links to admin ajax as faux frontend URLs. 898 if ( /\/wp-admin\/admin-ajax\.php$/.test( element.pathname ) ) { 899 return args.allowAdminAjax; 900 } 901 902 // Disallow links to admin, includes, and content. 903 if ( /\/wp-(admin|includes|content)(\/|$)/.test( element.pathname ) ) { 904 return false; 905 } 906 907 return true; 908 }; 909 910 api.utils.addAjaxRequestPrefilter = function() { 911 // @todo allowed URLs. 912 // @todo allow Admin ajax, true on frontend but false in admin. 913 // @todo This depends on having instantiated settings anyway so really the 914 }; 915 916 /** 917 * Rewrite Ajax requests to inject customizer state. 918 * 919 * @since 4.7.0 920 * @access protected 921 * 922 * @param {object} options Options. 923 * @param {string} options.type Type. 924 * @param {string} options.url URL. 925 * @param {object} originalOptions Original options. 926 * @param {XMLHttpRequest} xhr XHR. 927 * @returns {void} 928 */ 929 api.utils.prefilterAjaxPreviewingRequests = function prefilterAjaxPreviewingRequests( options, originalOptions, xhr ) { 930 var urlParser, queryParams, requestMethod, dirtyValues = {}; 931 urlParser = document.createElement( 'a' ); 932 urlParser.href = options.url; 933 934 // Abort if the request is not for this site. 935 if ( ! api.utils.isUrlPreviewable( urlParser, { allowAdminAjax: _.isUndefined( window.pagenow ), allowedUrls: api.settings.url.allowed } ) ) { 936 return; 937 } 938 939 queryParams = api.utils.parseQueryString( urlParser.search.substring( 1 ) ); 940 941 // Abort if if changeset UUID is already present. 942 if ( queryParams.customize_changeset_uuid ) { 943 return; 944 } 945 946 if ( _.isFunction( api.dirtyValues ) ) { 947 dirtyValues = api.dirtyValues( { unsaved: true } ); 948 } else if ( api.extended( api.Values ) ) { 949 api.each( function( setting ) { 950 if ( setting._dirty ) { 951 dirtyValues[ setting.id ] = setting.get(); 952 } 953 } ); 954 } 955 956 if ( ! _.isEmpty( dirtyValues ) ) { 957 requestMethod = options.type.toUpperCase(); 958 959 // Override underlying request method to ensure unsaved changes to changeset can be included (force Backbone.emulateHTTP). 960 if ( 'POST' !== requestMethod ) { 961 xhr.setRequestHeader( 'X-HTTP-Method-Override', requestMethod ); 962 queryParams._method = requestMethod; 963 options.type = 'POST'; 964 } 965 966 // Amend the post data with the customized values. 967 if ( options.data ) { 968 options.data += '&'; 969 } else { 970 options.data = ''; 971 } 972 options.data += $.param( { 973 customized: JSON.stringify( dirtyValues ) 974 } ); 975 } 976 977 // Include customized state query params in URL. 978 queryParams.customize_changeset_uuid = api.settings.changeset.uuid; 979 if ( ! api.settings.theme.active ) { 980 queryParams.customize_theme = api.settings.theme.stylesheet; 981 } 982 urlParser.search = $.param( queryParams ); 983 options.url = urlParser.href; 984 }; 985 847 986 // Expose the API publicly on window.wp.customize 848 987 exports.customize = api; 849 988 })( wp, jQuery ); -
src/wp-includes/js/customize-preview.js
diff --git src/wp-includes/js/customize-preview.js src/wp-includes/js/customize-preview.js index 484ccf4..ffe1c22 100644
152 152 } 153 153 154 154 // If the link is not previewable, prevent the browser from navigating to it. 155 if ( ! api. isLinkPreviewable( link[0]) ) {155 if ( ! api.utils.isUrlPreviewable( link[0], { allowedUrls: api.settings.url.allowed } ) ) { 156 156 wp.a11y.speak( api.settings.l10n.linkUnpreviewable ); 157 157 event.preventDefault(); 158 158 return; … … 193 193 urlParser.href = form.prop( 'action' ); 194 194 195 195 // If the link is not previewable, prevent the browser from navigating to it. 196 if ( 'GET' !== form.prop( 'method' ).toUpperCase() || ! api. isLinkPreviewable( urlParser) ) {196 if ( 'GET' !== form.prop( 'method' ).toUpperCase() || ! api.utils.isUrlPreviewable( urlParser, { allowedUrls: api.settings.url.allowed } ) ) { 197 197 wp.a11y.speak( api.settings.l10n.formUnpreviewable ); 198 198 event.preventDefault(); 199 199 return; … … 268 268 }; 269 269 270 270 /** 271 * Should the supplied link is previewable.272 *273 * @since 4.7.0274 * @access public275 *276 * @param {HTMLAnchorElement|HTMLAreaElement} element Link element.277 * @param {string} element.search Query string.278 * @param {string} element.pathname Path.279 * @param {string} element.host Host.280 * @param {object} [options]281 * @param {object} [options.allowAdminAjax=false] Allow admin-ajax.php requests.282 * @returns {boolean} Is appropriate for changeset link.283 */284 api.isLinkPreviewable = function isLinkPreviewable( element, options ) {285 var matchesAllowedUrl, parsedAllowedUrl, args;286 287 args = _.extend( {}, { allowAdminAjax: false }, options || {} );288 289 if ( 'javascript:' === element.protocol ) { // jshint ignore:line290 return true;291 }292 293 // Only web URLs can be previewed.294 if ( 'https:' !== element.protocol && 'http:' !== element.protocol ) {295 return false;296 }297 298 parsedAllowedUrl = document.createElement( 'a' );299 matchesAllowedUrl = ! _.isUndefined( _.find( api.settings.url.allowed, function( allowedUrl ) {300 parsedAllowedUrl.href = allowedUrl;301 return parsedAllowedUrl.protocol === element.protocol && parsedAllowedUrl.host === element.host && 0 === element.pathname.indexOf( parsedAllowedUrl.pathname.replace( /\/$/, '' ) );302 } ) );303 if ( ! matchesAllowedUrl ) {304 return false;305 }306 307 // Skip wp login and signup pages.308 if ( /\/wp-(login|signup)\.php$/.test( element.pathname ) ) {309 return false;310 }311 312 // Allow links to admin ajax as faux frontend URLs.313 if ( /\/wp-admin\/admin-ajax\.php$/.test( element.pathname ) ) {314 return args.allowAdminAjax;315 }316 317 // Disallow links to admin, includes, and content.318 if ( /\/wp-(admin|includes|content)(\/|$)/.test( element.pathname ) ) {319 return false;320 }321 322 return true;323 };324 325 /**326 271 * Inject the customize_changeset_uuid query param into links on the frontend. 327 272 * 328 273 * @since 4.7.0 … … 352 297 element.protocol = 'https:'; 353 298 } 354 299 355 if ( ! api. isLinkPreviewable( element) ) {300 if ( ! api.utils.isUrlPreviewable( element, { allowedUrls: api.settings.url.allowed } ) ) { 356 301 $( element ).addClass( 'customize-unpreviewable' ); 357 302 return; 358 303 } … … 375 320 }; 376 321 377 322 /** 378 * Inject the changeset UUID into Ajax requests.379 *380 * @since 4.7.0381 * @access protected382 *383 * @return {void}384 */385 api.addRequestPreviewing = function addRequestPreviewing() {386 387 /**388 * Rewrite Ajax requests to inject customizer state.389 *390 * @param {object} options Options.391 * @param {string} options.type Type.392 * @param {string} options.url URL.393 * @param {object} originalOptions Original options.394 * @param {XMLHttpRequest} xhr XHR.395 * @returns {void}396 */397 var prefilterAjax = function( options, originalOptions, xhr ) {398 var urlParser, queryParams, requestMethod, dirtyValues = {};399 urlParser = document.createElement( 'a' );400 urlParser.href = options.url;401 402 // Abort if the request is not for this site.403 if ( ! api.isLinkPreviewable( urlParser, { allowAdminAjax: true } ) ) {404 return;405 }406 queryParams = api.utils.parseQueryString( urlParser.search.substring( 1 ) );407 408 // Note that _dirty flag will be cleared with changeset updates.409 api.each( function( setting ) {410 if ( setting._dirty ) {411 dirtyValues[ setting.id ] = setting.get();412 }413 } );414 415 if ( ! _.isEmpty( dirtyValues ) ) {416 requestMethod = options.type.toUpperCase();417 418 // Override underlying request method to ensure unsaved changes to changeset can be included (force Backbone.emulateHTTP).419 if ( 'POST' !== requestMethod ) {420 xhr.setRequestHeader( 'X-HTTP-Method-Override', requestMethod );421 queryParams._method = requestMethod;422 options.type = 'POST';423 }424 425 // Amend the post data with the customized values.426 if ( options.data ) {427 options.data += '&';428 } else {429 options.data = '';430 }431 options.data += $.param( {432 customized: JSON.stringify( dirtyValues )433 } );434 }435 436 // Include customized state query params in URL.437 queryParams.customize_changeset_uuid = api.settings.changeset.uuid;438 if ( ! api.settings.theme.active ) {439 queryParams.customize_theme = api.settings.theme.stylesheet;440 }441 urlParser.search = $.param( queryParams );442 options.url = urlParser.href;443 };444 445 $.ajaxPrefilter( prefilterAjax );446 };447 448 /**449 323 * Inject changeset UUID into forms, allowing preview to persist through submissions. 450 324 * 451 325 * @since 4.7.0 … … 501 375 form.action = urlParser.href; 502 376 } 503 377 504 if ( 'GET' !== form.method.toUpperCase() || ! api. isLinkPreviewable( urlParser) ) {378 if ( 'GET' !== form.method.toUpperCase() || ! api.utils.isUrlPreviewable( urlParser, { allowedUrls: api.settings.url.allowed } ) ) { 505 379 $( form ).addClass( 'customize-unpreviewable' ); 506 380 return; 507 381 } … … 608 482 }); 609 483 610 484 api.addLinkPreviewing(); 611 api.addRequestPreviewing();485 $.ajaxPrefilter( api.utils.prefilterAjaxPreviewingRequests ); 612 486 api.addFormPreviewing(); 613 487 614 488 /**