Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
Merge 0d74731 into a928d18
Browse files Browse the repository at this point in the history
  • Loading branch information
westonruter committed Aug 7, 2016
2 parents a928d18 + 0d74731 commit 7e00358
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 14 deletions.
175 changes: 175 additions & 0 deletions js/customize-snapshots-frontend.js
@@ -0,0 +1,175 @@
/* global jQuery, confirm */
/* exported CustomizeSnapshotsFrontend */
/* eslint consistent-this: [ "error", "section" ], no-magic-numbers: [ "error", { "ignore": [0,1] } ] */
/* eslint-disable no-alert */

// @todo Allow the session to be explicitly exited. Warn with confirm if clicking a non-snapshotted link (to the admin).
// @todo Inject customize_snapshot_uuid into all Ajax requests back to the site.

var CustomizeSnapshotsFrontend = ( function( $ ) {
'use strict';

var component = {
data: {
uuid: '',
home_url: {
scheme: '',
host: '',
path: ''
},
l10n: {
restoreSessionPrompt: '',
leaveSessionPrompt: ''
}
}
};

/**
* Init.
*
* @param {object} args Args.
* @param {string} args.uuid UUID.
* @returns {void}
*/
component.init = function init( args ) {
_.extend( component.data, args );

component.hasSessionStorage = 'undefined' !== typeof sessionStorage;

component.keepSessionAlive();
component.rememberSessionSnapshot();
component.injectSnapshotIntoLinks();
};

/**
* Prompt to restore session.
*
* @returns {void}
*/
component.keepSessionAlive = function keepSessionAlive() {
var currentSnapshotUuid, urlParser;
if ( ! component.hasSessionStorage ) {
return;
}
currentSnapshotUuid = sessionStorage.getItem( 'customize_snapshot_uuid' );
if ( ! currentSnapshotUuid || component.data.uuid ) {
return;
}
if ( confirm( component.data.l10n.restoreSessionPrompt ) ) {
urlParser = document.createElement( 'a' );
urlParser.href = location.href;
if ( urlParser.search.length > 1 ) {
urlParser.search += '&';
}
urlParser.search += 'customize_snapshot_uuid=' + encodeURIComponent( sessionStorage.getItem( 'customize_snapshot_uuid' ) );
location.replace( urlParser.href );
} else {
sessionStorage.removeItem( 'customize_snapshot_uuid' );
}
};

/**
* Remember the session's snapshot.
*
* Persist the snapshot UUID in session storage so that we can prompt to restore the snapshot query param if inadvertently dropped.
*
* @returns {void}
*/
component.rememberSessionSnapshot = function rememberSessionSnapshot() {
if ( ! component.hasSessionStorage || ! component.data.uuid ) {
return;
}
sessionStorage.setItem( 'customize_snapshot_uuid', component.data.uuid );
};

/**
* Inject the snapshot UUID into links in the document.
*
* @returns {void}
*/
component.injectSnapshotIntoLinks = function injectSnapshotIntoLinks() {
if ( ! component.data.uuid ) {
return;
}
$( document.documentElement ).on( 'click focus mouseover', 'a, area', function( event ) {
component.injectLinkQueryParam( this );

if ( 'click' === event.type && ! component.isLinkSnapshottable( this ) ) {
if ( confirm( component.data.l10n.leaveSessionPrompt ) ) {
if ( component.hasSessionStorage ) {
sessionStorage.removeItem( 'customize_snapshot_uuid' );
}
} else {
event.preventDefault();
}
}
} );
};

/**
* Should the supplied link have a snapshot UUID added (or does it have one already)?
*
* @param {HTMLAnchorElement|HTMLAreaElement} element Link element.
* @param {string} element.search Query string.
* @param {string} element.pathname Path.
* @param {string} element.hostname Hostname.
* @returns {boolean} Is appropriate for snapshot link.
*/
component.isLinkSnapshottable = function isLinkSnapshottable( element ) {
if ( element.hostname !== component.data.home_url.host ) {
return false;
}
if ( 0 !== element.pathname.indexOf( component.data.home_url.path ) ) {
return false;
}

if ( /\/wp-(login|signup)\.php$/.test( element.pathname ) ) {
return false;
}

// @todo The snapshot UUID is getting added here still.
if ( $( element ).parent().is( '#wp-admin-bar-snapshot-view-link' ) ) {
return true;
}

if ( /(^|&)customize_snapshot_uuid=/.test( element.search.substr( 1 ) ) ) {
return true;
}

// Allow links to admin ajax as faux frontend URLs.
if ( /\/wp-admin\/admin-ajax\.php$/.test( element.pathname ) ) {
return true;
}

// Disallow links to admin.
if ( /\/wp-admin(\/|$)/.test( element.pathname ) ) {
return false;
}

return true;
};

/**
* Inject the customize_snapshot_uuid query param into links on the frontend.
*
* @param {HTMLAnchorElement|HTMLAreaElement} element Link element.
* @param {object} element.search Query string.
* @returns {void}
*/
component.injectLinkQueryParam = function injectLinkQueryParam( element ) {
if ( ! component.isLinkSnapshottable( element ) ) {
return;
}
if ( /(^|&)customize_snapshot_uuid=/.test( element.search.substr( 1 ) ) ) {
return;
}

if ( element.search.length > 1 ) {
element.search += '&';
}
element.search += 'customize_snapshot_uuid=' + encodeURIComponent( component.data.uuid );
};

return component;
} )( jQuery );

39 changes: 35 additions & 4 deletions php/class-customize-snapshot-manager.php
Expand Up @@ -92,8 +92,10 @@ function init() {

add_action( 'template_redirect', array( $this, 'show_theme_switch_error' ) );

add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_controls_scripts' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ) );

add_action( 'customize_controls_init', array( $this, 'add_snapshot_uuid_to_return_url' ) );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_templates' ) );
add_action( 'customize_save', array( $this, 'check_customize_publish_authorization' ), 10, 0 );
add_filter( 'customize_refresh_nonces', array( $this, 'filter_customize_refresh_nonces' ) );
Expand Down Expand Up @@ -196,6 +198,11 @@ public function is_theme_active() {
*/
public function should_import_and_preview_snapshot( Customize_Snapshot $snapshot ) {

// Ignore if in the admin.
if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
return false;
}

if ( is_wp_error( $this->get_theme_switch_error( $snapshot ) ) ) {
return false;
}
Expand Down Expand Up @@ -518,15 +525,15 @@ static public function encode_json( $value ) {
* @action customize_controls_enqueue_scripts
* @global \WP_Customize_Manager $wp_customize
*/
public function enqueue_scripts() {
public function enqueue_controls_scripts() {

// Prevent loading the Snapshot interface if the theme is not active.
if ( ! $this->is_theme_active() ) {
return;
}

wp_enqueue_style( $this->plugin->slug );
wp_enqueue_script( $this->plugin->slug );
wp_enqueue_style( 'customize-snapshots' );
wp_enqueue_script( 'customize-snapshots' );

// Script data array.
$exports = apply_filters( 'customize_snapshots_export_data', array(
Expand Down Expand Up @@ -559,6 +566,30 @@ public function enqueue_scripts() {
);
}

/**
* Enqueue Customizer frontend scripts.
*/
public function enqueue_frontend_scripts() {
if ( $this->snapshot || current_user_can( 'customize' ) ) {
$handle = 'customize-snapshots-frontend';
wp_enqueue_script( $handle );

$exports = array(
'uuid' => $this->snapshot ? $this->snapshot->uuid() : null,
'home_url' => wp_parse_url( home_url( '/' ) ),
'l10n' => array(
'restoreSessionPrompt' => __( 'It seems you may have inadvertently navigated away from previewing a customized state. Would you like to restore the snapshot context?', 'customize-snapshots' ),
'leaveSessionPrompt' => __( 'You\'re about to leave previewing our snapshotted customized state. Would you like to continue?', 'customize-snapshots' ),
),
);
wp_add_inline_script(
$handle,
sprintf( 'CustomizeSnapshotsFrontend.init( %s )', wp_json_encode( $exports ) ),
'after'
);
}
}

/**
* Include the snapshot nonce in the Customizer nonces.
*
Expand Down
13 changes: 11 additions & 2 deletions php/class-plugin.php
Expand Up @@ -65,9 +65,16 @@ public function init() {
*/
public function register_scripts( \WP_Scripts $wp_scripts ) {
$min = ( SCRIPT_DEBUG ? '' : '.min' );

$handle = 'customize-snapshots';
$src = $this->dir_url . 'js/customize-snapshots' . $min . '.js';
$deps = array( 'jquery', 'jquery-ui-dialog', 'wp-util', 'customize-controls' );
$wp_scripts->add( $this->slug, $src, $deps );
$wp_scripts->add( $handle, $src, $deps );

$handle = 'customize-snapshots-frontend';
$src = $this->dir_url . 'js/customize-snapshots-frontend' . $min . '.js';
$deps = array( 'jquery', 'underscore' );
$wp_scripts->add( $handle, $src, $deps );
}

/**
Expand All @@ -79,8 +86,10 @@ public function register_scripts( \WP_Scripts $wp_scripts ) {
*/
public function register_styles( \WP_Styles $wp_styles ) {
$min = ( SCRIPT_DEBUG ? '' : '.min' );

$handle = 'customize-snapshots';
$src = $this->dir_url . 'css/customize-snapshots' . $min . '.css';
$deps = array( 'wp-jquery-ui-dialog' );
$wp_styles->add( $this->slug, $src, $deps );
$wp_styles->add( $handle, $src, $deps );
}
}
46 changes: 38 additions & 8 deletions tests/php/test-class-customize-snapshot-manager.php
Expand Up @@ -93,14 +93,22 @@ function setUp() {
}
}

/**
* Clean up global scope.
*/
function clean_up_global_scope() {
unset( $GLOBALS['wp_scripts'] );
unset( $GLOBALS['wp_styles'] );
parent::clean_up_global_scope();
}

/**
* Tear down.
*/
function tearDown() {
$this->wp_customize = null;
$this->manager = null;
unset( $GLOBALS['wp_customize'] );
unset( $GLOBALS['wp_scripts'] );
unset( $GLOBALS['screen'] );
$_REQUEST = array();
parent::tearDown();
Expand Down Expand Up @@ -158,7 +166,7 @@ function test_construct_with_customize() {
$this->assertInstanceOf( 'CustomizeSnapshots\Post_Type', $manager->post_type );
$this->assertInstanceOf( 'CustomizeSnapshots\Customize_Snapshot', $manager->snapshot() );
$this->assertEquals( 0, has_action( 'init', array( $manager, 'create_post_type' ) ) );
$this->assertEquals( 10, has_action( 'customize_controls_enqueue_scripts', array( $manager, 'enqueue_scripts' ) ) );
$this->assertEquals( 10, has_action( 'customize_controls_enqueue_scripts', array( $manager, 'enqueue_controls_scripts' ) ) );
$this->assertEquals( 10, has_action( 'wp_ajax_customize_update_snapshot', array( $manager, 'handle_update_snapshot_request' ) ) );
}

Expand Down Expand Up @@ -342,18 +350,40 @@ function test_encode_json() {
}

/**
* Test enqueue scripts.
* Test enqueue controls scripts.
*
* @see Customize_Snapshot_Manager::enqueue_scripts()
* @see Customize_Snapshot_Manager::enqueue_controls_scripts()
*/
function test_enqueue_scripts() {
function test_enqueue_controls_scripts() {
$this->plugin->register_scripts( wp_scripts() );
$this->plugin->register_styles( wp_styles() );
$manager = new Customize_Snapshot_Manager( $this->plugin );
$manager->init();
$manager->enqueue_scripts();
$this->assertTrue( wp_script_is( $this->plugin->slug, 'enqueued' ) );
$this->assertTrue( wp_style_is( $this->plugin->slug, 'enqueued' ) );
$manager->enqueue_controls_scripts();
$this->assertTrue( wp_script_is( 'customize-snapshots', 'enqueued' ) );
$this->assertTrue( wp_style_is( 'customize-snapshots', 'enqueued' ) );
}

/**
* Test enqueue frontend scripts.
*
* @see Customize_Snapshot_Manager::enqueue_frontend_scripts()
*/
function test_enqueue_frontend_scripts() {
$this->plugin->register_scripts( wp_scripts() );
$this->plugin->register_styles( wp_styles() );
$manager = new Customize_Snapshot_Manager( $this->plugin );
$manager->init();
$this->assertFalse( wp_script_is( 'customize-snapshots-frontend', 'enqueued' ) );
$manager->enqueue_frontend_scripts();
$this->assertFalse( wp_script_is( 'customize-snapshots-frontend', 'enqueued' ) );

$_REQUEST['customize_snapshot_uuid'] = self::UUID;
$manager = new Customize_Snapshot_Manager( $this->plugin );
$manager->init();
$this->assertFalse( wp_script_is( 'customize-snapshots-frontend', 'enqueued' ) );
$manager->enqueue_frontend_scripts();
$this->assertTrue( wp_script_is( 'customize-snapshots-frontend', 'enqueued' ) );
}

/**
Expand Down

0 comments on commit 7e00358

Please sign in to comment.