diff --git a/core/modules/layout/js/layout.js b/core/modules/layout/js/layout.js index e146dac..5dc40ee 100644 --- a/core/modules/layout/js/layout.js +++ b/core/modules/layout/js/layout.js @@ -2,17 +2,16 @@ Drupal.layout = Drupal.layout || {}; - var size; - var handles = []; - var leftOffset; - var $frame; - var iframeDocument; - var $slider; - var $container; - var $sizeInput; - var active = false; - var breakpoints = {}; - var $breakpointView; + var size; // The width of the preview container. + var handles = []; // The values of the jQuery UI Slider handles. + var leftOffset; // The left value of the iframe containing the previewed page. + var $frame; // The iframe that contains the previewed page. + var iframeDocument; // The document of the iframe that contains the preview. + var $slider; // The jQuery UI Slider widget that adjusts the iframed preview. + var $container; // The container of the page preview component. + var $sizeInput; // The input element that display the width of the preview. + var breakpoints = {}; // A list of breakpoints, keyed by configuration string. + var $breakpointView; // The container of the breakpoint views. Drupal.behaviors.layout = { attach: function (context, settings) { @@ -20,7 +19,7 @@ if ($body.length) { // Set up the trigger link. - $('#toolbar-tab-layout_preview').on('click.layout', Drupal.layout.toggleLayoutPreview); + $('#toolbar-tab-layout_preview').on('click.layout', toggleLayoutPreview); } // Remove administrative elements in the document inside the iframe. if (window.top !== window.self) { @@ -30,24 +29,30 @@ }; /** + * Toggles the layout preview component on or off. * + * When first toggled on, the layout preview component is built. All + * subsequent toggles hide or show the build component. + * + * @param Object Event + * - jQuery Event object. */ - Drupal.layout.toggleLayoutPreview = function (event) { + var toggleLayoutPreview = function (event) { // Build the previewer if it doesn't exist. if (!$container) { // Size is the width of the iframe. size = size || window.top.document.documentElement.clientWidth; // Initialize the handle positions. handles = (handles.length) ? handles : [0, document.documentElement.clientWidth]; - Drupal.layout.buildPreviewer(); + buildPreviewer(); } $container.toggleClass('active'); }; /** - * + * Assembles a layout previewer. */ - Drupal.layout.buildPreviewer = function (width) { + var buildPreviewer = function () { $(window.top.document.body).once('layout-preview-container', function (index, element) { $container = $(Drupal.theme('layoutContainer')) .appendTo(window.top.document.body); @@ -56,52 +61,58 @@ 'width': size }) .appendTo($container); - }); - // Slider. - $slider = $(Drupal.theme('layoutSlider')) - .slider({ - 'animate': 'fast', - 'range': true, - 'max': document.documentElement.clientWidth, - 'min': 0, - 'values': handles, - 'slide': Drupal.layout.handleSlide - }) - .prependTo($container); + // Slider. + $slider = $(Drupal.theme('layoutSlider')) + .slider({ + 'animate': 'fast', + 'range': true, + 'max': document.documentElement.clientWidth, + 'min': 0, + 'values': handles, + 'slide': handleSlide + }) + .prependTo($container); - // Load the breakpoints for the current theme. - if ('breakpoints' in Drupal.settings.layout.routes) { - $.ajax(Drupal.settings.layout.routes.breakpoints) - .success(breakpointsCallback); - } - // Width label. - $sizeInput = $(Drupal.theme('layoutSizeInput')) - .appendTo($container); - // Displace the top of the container. - $container - .css({ - top: Drupal.layout.getDisplacement('top'), - }) - .attr('data-offset-top', Drupal.layout.getDisplacement('top')); - // The contentDocument property is not supported in IE until IE8. - iframeDocument = $frame[0].contentDocument || $frame[0].contentWindow.document; + // Load the breakpoints for the current theme. + if ('breakpoints' in Drupal.settings.layout.routes) { + $.ajax(Drupal.settings.layout.routes.breakpoints) + .success(breakpointsCallback); + } + // Width label. + $sizeInput = $(Drupal.theme('layoutSizeInput')) + .appendTo($container); + // Displace the top of the container. + $container + .css({ + top: getDisplacement('top'), + }) + .attr('data-offset-top', getDisplacement('top')); + // The contentDocument property is not supported in IE until IE8. + iframeDocument = $frame[0].contentDocument || $frame[0].contentWindow.document; - $(window.top).on('resize.layout', Drupal.layout.handleWindowResize); - $sizeInput.on('keypress.layout', {pattern: /^[0-9\.]$/, callback: Drupal.layout.handleSizeInputChange}, keyManager); - $container.on('sizeUpdate.layout', refreshPreviewSizing); + $(window.top).on('resize.layout', handleWindowResize); + $sizeInput.on('keypress.layout', {pattern: /^[0-9\.]$/, callback: handleSizeInputChange}, keyManager); + $container.on('sizeUpdate.layout', refreshPreviewSizing); - // Trigger a resize to kick off some initial placements. - $(window.top).triggerHandler('resize.layout'); + // Trigger a resize to kick off some initial placements. + $(window.top).triggerHandler('resize.layout'); - // Load the current page URI into the preview iframe. - // @todo, are there any security implications to loading a page like this? - iframeDocument.location.href = Drupal.settings.basePath + Drupal.settings.currentPath; + // Load the current page URI into the preview iframe. + // @todo, are there any security implications to loading a page like this? + iframeDocument.location.href = Drupal.settings.basePath + Drupal.settings.currentPath; + }); }; /** + * Responds to a jQuery UI Slider slide event. + * + * @param Object Event + * - jQuery Event object. * + * @param Object ui + * - jQuery Slider widget state information resulting from a slide event. */ - Drupal.layout.handleSlide = function (event, ui) { + var handleSlide = function (event, ui) { // Layout will control the placement of the handles. event.preventDefault(); var delta = 0; @@ -131,9 +142,12 @@ }; /** + * Responds to keypress events from the frame size input. * + * @param Object Event + * - jQuery Event object. */ - Drupal.layout.handleSizeInputChange = function (event) { + var handleSizeInputChange = function (event) { var newSize; if (event.isDefaultPrevented()) { return false; @@ -162,7 +176,20 @@ }; /** + * Updates the dimension variables of the previewer components. * + * @param Array values + * - An array that contains the position values of the handles of the jQuery + * UI slider. + * + * @param max + * - The maximum width of the previewer. Often this is just the width of the + * client. + * + * @param speed + * - A number representing time in milliseconds or a jQuery speed keyword. + * Determines the speed at which animations between changes dimension values + * should take place. Defaults to zero. */ var updateDimensions = function (values, max, speed) { // Store the new values of the handles. @@ -176,9 +203,12 @@ }; /** + * Responds to window resize events. * + * @param Object Event + * - jQuery Event object. */ - Drupal.layout.handleWindowResize = function (event) { + var handleWindowResize = function (event) { var doc = this.document.documentElement; var docWidth = doc.clientWidth; var framePercent = size / docWidth; @@ -208,7 +238,18 @@ }; /** + * Renders breakpoint configuration to an HTML view. + * + * @param Object data + * - Breakpoint configuration data. The keys of the object correspond to the + * keys of theme-configured breakpoints. The value of each key is a string + * that represents a media query. * + * @param String textStatus + * - The status of the AJAX request. + * + * @param Object jqXHR + * - A jQuery XMLHttpRequest object. */ var breakpointsCallback = function (data, textStatus, jqXHR) { $breakpointView = $(Drupal.theme('layoutBreakpointView')); @@ -232,7 +273,15 @@ }; /** + * Redraws the layout preview component based on the stored dimensions. + * + * @param Object event + * - A jQuery event object. * + * @param Number/String speed + * - A number representing time in milliseconds or a jQuery speed keyword. + * Determines the speed at which animations between changes dimension values + * should take place. Defaults to zero. */ var refreshPreviewSizing = function (event, speed) { speed = speed || 0; @@ -249,13 +298,13 @@ /** * Get the total displacement of given region. * - * @param region + * @param String region * Region name. Either "top" or "bottom". * * @return * The total displacement of given region in pixels. */ - Drupal.layout.getDisplacement = function (region) { + var getDisplacement = function (region) { var displacement = 0; var lastDisplaced = $('[data-offset-' + region + ']'); if (lastDisplaced.length) { @@ -266,42 +315,42 @@ $.extend(Drupal.theme, { /** - * Theme function to create the overlay iframe element. + * Returns the preview container element. */ layoutContainer: function () { return '
'; }, /** - * Theme function to create an overlay iframe element. + * Returns an overlay iframe element. */ layoutFrame: function (url) { return ''; }, /** - * + * Returns the HTML for the jQuery UI Slider attachment. */ layoutSlider: function () { return '
'; }, /** - * + * Returns the input element for changing the preview width. */ layoutSizeInput: function () { return '
' + Drupal.t('Width') + 'px
'; }, /** - * + * Returns the wrapper for breakpoint item views. */ layoutBreakpointView: function () { return '
' }, /** - * + * Returns individual breakpoint configuration views. */ layoutBreakpointItemView: function (options) { var markup = ''; @@ -318,9 +367,24 @@ }); /** + * Handles key input. * + * Fires a callback function with either return the key that was pressed in + * the event.key property, or, if the key is a control key or does not match + * a supplied pattern, then null as the event.key value. + * + * @param Regex event.data.pattern + * - A regular expression that filters allowed key input. Only keys matching + * the expression will be returned. All other keys return null. + * + * @param Function event.data.callback + * - A callback function to be invoked after a key is processed. Any + * variadic parameters supplied to keyManager are passed through as well. + * + * @param Array event.data.controls + * - An Array of char codes that should be ignored as control keys. */ - function keyManager (event) { + var keyManager = function (event) { event.data = event.data || {}; var pattern = event.data.pattern || undefined; var callback = event.data.callback || undefined; @@ -351,9 +415,20 @@ } /** + * Maps keyCode to Strings, taking the shift key state into account. + * + * @param Boolean isShifted + * - A Boolean representing if the shift key was pressed (true) or not + * (false) + * + * @param Number keyCode + * - The numeric code of the key that was pressed. * + * @return String + * - A single character corresponding to the keyCode or null if no + * correspondence is found. */ - function mapKeyToChar(isShifted, keyCode) { + var mapKeyToChar = function (isShifted, keyCode) { if (keyCode === 27 || keyCode === 8 || keyCode === 9 @@ -413,7 +488,10 @@ } /** + * Parses a String representing a media query into usable values. * + * @param String mq + * - A String representing a media query e.g. 'all and (min-width: 800px)' */ var parseMediaQuery = function (mq) { return { diff --git a/core/modules/layout/layout.module b/core/modules/layout/layout.module index 4758bd3..df413e9 100644 --- a/core/modules/layout/layout.module +++ b/core/modules/layout/layout.module @@ -91,7 +91,9 @@ function layout_theme($existing, $type, $theme, $path) { } /** + * Page callback: Returns the breakpoints of the current active theme. * + * @see layout_menu(). */ function layout_retrieve_theme_breakpoints_jsonp() { global $theme_key;