From 0c660e90b2e88bb528dcf3975293792edb310459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?"J.=20Rene=CC=81e=20Beach"?= Date: Thu, 14 Feb 2013 01:36:23 -0500 Subject: [PATCH] Issue #1741498 by jessebeach, Wim Leers: Add a mobile preview bar to Drupal core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c39edbcca829430da449a60ab303dfc15044999b Author: J. Renée Beach Date: Wed Feb 13 23:37:58 2013 -0500 patch 17 Signed-off-by: J. Renée Beach Signed-off-by: J. Renée Beach --- .../config/responsive-preview.devices.yml | 21 ++ .../css/responsive-preview.base-rtl.css | 22 ++ .../css/responsive-preview.base.css | 90 +++++ .../css/responsive-preview.theme-rtl.css | 14 + .../css/responsive-preview.theme.css | 112 ++++++ core/modules/responsive_preview/images/close.png | 3 + .../images/icon-responsive-preview-active.png | 3 + .../images/icon-responsive-preview.png | 4 + .../responsive_preview/js/responsive-preview.js | 393 ++++++++++++++++++++ .../responsive_preview/responsive_preview.info | 5 + .../responsive_preview/responsive_preview.module | 112 ++++++ 11 files changed, 779 insertions(+) create mode 100644 core/modules/responsive_preview/config/responsive-preview.devices.yml create mode 100644 core/modules/responsive_preview/css/responsive-preview.base-rtl.css create mode 100644 core/modules/responsive_preview/css/responsive-preview.base.css create mode 100644 core/modules/responsive_preview/css/responsive-preview.theme-rtl.css create mode 100644 core/modules/responsive_preview/css/responsive-preview.theme.css create mode 100644 core/modules/responsive_preview/images/close.png create mode 100644 core/modules/responsive_preview/images/icon-responsive-preview-active.png create mode 100644 core/modules/responsive_preview/images/icon-responsive-preview.png create mode 100644 core/modules/responsive_preview/js/responsive-preview.js create mode 100644 core/modules/responsive_preview/responsive_preview.info create mode 100644 core/modules/responsive_preview/responsive_preview.module diff --git a/core/modules/responsive_preview/config/responsive-preview.devices.yml b/core/modules/responsive_preview/config/responsive-preview.devices.yml new file mode 100644 index 0000000..da246a4 --- /dev/null +++ b/core/modules/responsive_preview/config/responsive-preview.devices.yml @@ -0,0 +1,21 @@ +devices: + iphone: + label: iPhone + dimensions: + width: 320 + height: 480 + android: + label: Android + dimensions: + width: 540 + height: 960 + ipad: + label: iPad + dimensions: + width: 768 + height: 1024 + desktop: + label: desktop + dimensions: + width: 1366 + height: 768 diff --git a/core/modules/responsive_preview/css/responsive-preview.base-rtl.css b/core/modules/responsive_preview/css/responsive-preview.base-rtl.css new file mode 100644 index 0000000..d969346 --- /dev/null +++ b/core/modules/responsive_preview/css/responsive-preview.base-rtl.css @@ -0,0 +1,22 @@ +/** + * @file + * RTL base styling for responsive preview. + */ + +.js .toolbar .bar .responsive-preview-toolbar-tab.tab { + float: right; +} + +@media only screen and (min-width: 36em) { + .js .toolbar .bar .responsive-preview-toolbar-tab.tab { + float: left; + } +} + +#responsive-preview-container { + left: 0; + right: -200%; +} +#responsive-preview-container.active { + right: 0; +} diff --git a/core/modules/responsive_preview/css/responsive-preview.base.css b/core/modules/responsive_preview/css/responsive-preview.base.css new file mode 100644 index 0000000..2fc1a40 --- /dev/null +++ b/core/modules/responsive_preview/css/responsive-preview.base.css @@ -0,0 +1,90 @@ +/** + * @file + * Base styling for responsive preview. + */ + +/** + * Constrain the window height to the client height when the preview is active. + */ +.responsive-preview-active { + height: 100%; + overflow: hidden; +} + +/** + * Toolbar tab. + */ +.responsive-preview-toolbar-tab { + display: none; +} +/* At narrow screen widths, float the tab to the left so it falls in line with + * the rest of the toolbar tabs. */ +.js .toolbar .bar .responsive-preview-toolbar-tab.tab { + display: block; + float: left; /* LTR */ +} +/* At wide widths, float the tab to the right. */ +@media only screen and (min-width: 36em) { + .js .toolbar .bar .responsive-preview-toolbar-tab.tab { + float: right; /* LTR */ + } +} +.responsive-preview-toolbar-tab .responsive-preview-options { + display: none; +} +.responsive-preview-toolbar-tab.open .responsive-preview-options { + display: block; +} + +/** + * Preview container. + * + * The container is kept offscreen after it is built and has been disabled. + */ +#responsive-preview-container { + display: none; + height: 100%; + left: -200%; /* LTR */ + position: absolute; + width: 100%; + z-index: 1050; +} +#responsive-preview-container.active { + display: block; + left: 0; /* LTR */ +} +#responsive-preview-close { + position: absolute; + z-index: 75; +} +.responsive-preview-modal-background { + bottom: 0; + height: 100%; + left: 0; + position: fixed; + right: 0; + top: 3em; + width: 100%; + z-index: 1; +} + +/** + * Preview iframe. + */ +#responsive-preview-container iframe { + height: 100%; + position: relative; + width: 100%; + z-index: 100; +} + +/** + * Override Toolbar styling in the preview iframe. + */ +.responsive-preview-frame #toolbar-administration { + display: none !important; +} +body.toolbar-tray-open.responsive-preview-frame { + margin-left: 0 !important; + margin-right: 0 !important; +} diff --git a/core/modules/responsive_preview/css/responsive-preview.theme-rtl.css b/core/modules/responsive_preview/css/responsive-preview.theme-rtl.css new file mode 100644 index 0000000..f5e1339 --- /dev/null +++ b/core/modules/responsive_preview/css/responsive-preview.theme-rtl.css @@ -0,0 +1,14 @@ +/** + * @file + * RTL styling for responsive preview. + */ + +.toolbar .bar .responsive-preview-toolbar-tab .icon-responsive-preview:before { + left: 0; + right: 1em; +} + +.responsive-preview-toolbar-tab .trigger:after { + right: 0; + left: 1.2em; +} diff --git a/core/modules/responsive_preview/css/responsive-preview.theme.css b/core/modules/responsive_preview/css/responsive-preview.theme.css new file mode 100644 index 0000000..f2a648c --- /dev/null +++ b/core/modules/responsive_preview/css/responsive-preview.theme.css @@ -0,0 +1,112 @@ +/** + * @file + * Styling for responsive preview. + */ + +/** + * Toolbar tab. + */ +.responsive-preview-toolbar-tab .responsive-preview-options { + background-color: #0f0f0f; +} +/* Toolbar icon. */ +.toolbar .bar .icon.icon-responsive-preview { + margin-left: 0; + margin-right: 0; + padding-left: 0; + padding-right: 0; + text-indent: -9999px; + width: 5em; +} +.icon-responsive-preview:before { + background-image: url("../images/icon-responsive-preview.png"); +} +.toolbar .bar .responsive-preview-toolbar-tab .icon-responsive-preview:before { + left: 1em; /* LTR */ +} +.responsive-preview-toolbar-tab.open .icon-responsive-preview:before, +.responsive-preview-toolbar-tab .icon-responsive-preview.active:before { + background-image: url("../images/icon-responsive-preview-active.png"); +} +@media only screen and (min-width: 16.5em) { + .toolbar .responsive-preview-toolbar-tab.tab .icon-responsive-preview:before { + width: 20px; + } +} +/* Device preview options. */ +.responsive-preview-toolbar-tab .responsive-preview-options { + box-shadow: 0 0 2em 0 rgba(0, 0, 0, 0.75); + position: absolute; + white-space: nowrap; +} +.responsive-preview-toolbar-tab .responsive-preview-options li { + background-color: white; + border-top: 1px solid #cfcfcf; +} +.responsive-preview-toolbar-tab .trigger, +.responsive-preview-toolbar-tab .responsive-preview-options a { + padding-bottom: 1em; + padding-top: 1em; +} +.toolbar .responsive-preview-toolbar-tab.tab .responsive-preview-options a { + color: #777; +} +.toolbar .responsive-preview-toolbar-tab.tab .responsive-preview-options a:hover { + color: black; +} +/* Toolbar tab triangle toggle. */ +.responsive-preview-toolbar-tab .trigger:after { + border-bottom-color: transparent; + border-left-color: transparent; + border-right-color: transparent; + border-style: solid; + border-width: 0.4545em 0.4em 0; + color: #a0a0a0; + content: ' '; + display: block; + height: 0; + line-height: 0; + position: absolute; + right: 1.2em; /* LTR */ + top: 50%; + margin-top: -0.1666em; + width: 0; + overflow: hidden; +} +.responsive-preview-toolbar-tab.open .trigger:after { + border-bottom: 0.4545em solid; + border-top-color: transparent; + top: 1.25em; +} + +/** + * Preview container. + */ +#responsive-preview-container { + box-shadow: 0 0 10px 0 black; +} +#responsive-preview-close { + background-attachment: scroll; + background-color: #a0a0a0; + background-image: url("../images/close.png"); + background-image: url("../images/close.png"), -webkit-linear-gradient(transparent, #787878 150%); + background-image: url("../images/close.png"), linear-gradient(transparent, #787878 150%); + background-position: center center; + background-repeat: no-repeat; + border: none; + border-radius: 3px; + cursor: pointer; + font-size: 1em; + height: 2.333em; + margin-left: 10px; + margin-top: 9px; + text-indent: -9999px; + width: 2.333em; +} +#responsive-preview-close:hover { + background-image: url("../images/close.png"); +} +.responsive-preview-modal-background { + background-color: black; + background-color: rgba(0,0,0,0.92); +} diff --git a/core/modules/responsive_preview/images/close.png b/core/modules/responsive_preview/images/close.png new file mode 100644 index 0000000..538518e --- /dev/null +++ b/core/modules/responsive_preview/images/close.png @@ -0,0 +1,3 @@ +PNG + + IHDR7tEXtSoftwareAdobe ImageReadyqe<IDAT(SeKKBAx_iWjOhBREࣝ{E. BpEĽuy!h sVYkiֶ^pđ#^j[RPZaC̄>5Vdr2Q\mF*ToBKگ tJr?wϋ||PqkUݞ,/s_n ^z({!-sSS3oRlYgE/S 9d,H+_ϲ5}PrgY{ST⫑V k{,p2D*kfj5Nd2Z>%o=$4֘5FhhfPnoҗ1_M|6]!mf-!K}H2N|S \*6BQ1 #(&INʕr;Sd #Z IENDB` \ No newline at end of file diff --git a/core/modules/responsive_preview/images/icon-responsive-preview-active.png b/core/modules/responsive_preview/images/icon-responsive-preview-active.png new file mode 100644 index 0000000..f6e8a16 --- /dev/null +++ b/core/modules/responsive_preview/images/icon-responsive-preview-active.png @@ -0,0 +1,3 @@ +PNG + + IHDR $cIDAT8c L@HL0#! W?&m"mр0?|?! ?bG(!)dF,~(.teIENDB` \ No newline at end of file diff --git a/core/modules/responsive_preview/images/icon-responsive-preview.png b/core/modules/responsive_preview/images/icon-responsive-preview.png new file mode 100644 index 0000000..3e22cb8 --- /dev/null +++ b/core/modules/responsive_preview/images/icon-responsive-preview.png @@ -0,0 +1,4 @@ +PNG + + IHDR $pIDAT8cZx O? f 380L-\1 L %ϦQM߿@S;#ƐD +iڈEBCituJq4QIENDB` \ No newline at end of file diff --git a/core/modules/responsive_preview/js/responsive-preview.js b/core/modules/responsive_preview/js/responsive-preview.js new file mode 100644 index 0000000..a8fd1f3 --- /dev/null +++ b/core/modules/responsive_preview/js/responsive-preview.js @@ -0,0 +1,393 @@ +/** + * @file + * + * Provides a component that previews the a page in various device dimensions. + */ + +(function ($, Drupal) { + + "use strict"; + + Drupal.responsivePreview = Drupal.responsivePreview || {}; + + var $toolbarTab = $(); + var $container; // The container of the page preview component. + var $frame; // The iframe that contains the previewed page. + var iframeDocument; // The document of the iframe that contains the preview. + var size; // The width of the iframe container. + var leftOffset; // The left value of the iframe container. + var device = { + width: null, // The width of the device to preview. + height: null // The height of the device to preview. + }; + var edgeTolerance = 60; + + Drupal.behaviors.responsivePreview = { + attach: function (context, settings) { + var $body = $(window.top.document.body).once('responsive-preview'); + + if ($body.length) { + // Append the selector to the preview container. + $toolbarTab = $('.responsive-preview-toolbar-tab') + .on('click.responsivePreview', '#responsive-preview', toggleConfigurationOptions) + .on('mouseleave.responsivePreview', '.responsive-preview-options', {open: false}, toggleConfigurationOptions) + .on('click.responsivePreview', '.responsive-preview-options .responsive-preview-device', {open: false}, toggleConfigurationOptions) + .on('click.responsivePreview', '.responsive-preview-device', loadDevicePreview); + // Register a handler on window resize to reposition the tab dropdown. + $(window.top) + .on('resize.responsivePreview.tab', handleWindowToolbarResize) + .trigger('resize.responsivePreview.tab'); + } + // Remove administrative elements in the document inside the iframe. + if (window.top !== window.self) { + var $frameBody = $(window.self.document.body).once('responsive-preview'); + if ($frameBody.length > 0) { + $frameBody.get(0).className += ' responsive-preview-frame'; + } + } + } + }; + + /** + * Toggles the list of devices available to preview from the toolbar tab. + * + * @param {Object} event + * jQuery Event object. + */ + function toggleConfigurationOptions (event) { + event.preventDefault(); + var open = (event.data && typeof event.data.open === 'boolean') ? event.data.open : undefined; + $(event.delegateTarget) + // Set an open class on the tab wrapper. + .toggleClass('open', open) + .find('.responsive-preview-options') + // The list of options will most likely render outside the window. Correct + // this. + .drupalLayout('correctEdgeCollisions'); + } + + /** + * 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 built component. + * + * @param {Object} event + * jQuery Event object. + * + * @param {Boolean} activate + * A boolean that forces the preview to show (true) or to hide (false). + */ + function toggleLayoutPreview (event, activate) { + event.preventDefault(); + // Build the preview if it doesn't exist. + if (!$container) { + buildpreview(); + // Size is the width of the iframe. + updateDimensions({width: (size || window.top.document.documentElement.clientWidth)}); + } + $toolbarTab + .find('> button') + .toggleClass('active', activate); + $container + .toggleClass('active', activate); + $('body') + .toggleClass('responsive-preview-active', activate); + } + + /** + * Assembles a layout preview. + */ + function buildpreview () { + $(window.top.document.body).once('responsive-preview-container', function (index, element) { + $container = $(Drupal.theme('layoutContainer')); + + // Add a close button. + $container + .append(Drupal.theme('layoutClose')); + + // Attach the iframe that will hold the preview. + $frame = $(Drupal.theme('layoutFrame')) + .css({ width: size }) + .appendTo($container); + + // Append the container to the window. + $container.appendTo(window.top.document.body); + // 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; + + $container + .on('click.responsivePreview', '#responsive-preview-close', {activate: false}, toggleLayoutPreview) + .on('sizeUpdate.responsivePreview', refreshPreviewSizing); + + // Trigger a resize to kick off some initial placements. + $(window.top) + .on('resize.responsivePreview', updateDimensions) + .trigger('resize.responsivePreview'); + + // 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; + }); + } + + /** + * Updates the dimension variables of the preview components. + * + * @param {Object} dimensions + * An object with the following properties: + * - {Number} width: The width the preview should be set to. + * - {Number} height (optional): The height the preview should be set to. + * + * @todo dimensions.height is not yet being used. + */ + function updateDimensions () { + var width = device.width || NaN; + var height = device.height || NaN; + var max = document.documentElement.clientWidth; + var gutterPercent = (1 - (width / max)) / 2; + var left = gutterPercent * max; + // Set the left offset of the frame. + // The gutters must be at least the width of the edgeTolerance + left = (left < edgeTolerance) ? edgeTolerance : left; + // The frame width must fit within the difference of the gutters and the + // page width. + width = (max - (left * 2) < width) ? max - (left * 2) : width; + // Set the dimension variables in the closure. + leftOffset = left; + size = width; + // Trigger a dimension change. + $container.trigger('sizeUpdate.responsivePreview'); + } + + /** + * Handles refreshing the layout toolbar tab positioning. + * + * @param {Object} event + * jQuery Event object. + */ + function handleWindowToolbarResize (event) { + var options = $toolbarTab + .find('.responsive-preview-options') + // Move the list back onto the screen. + .drupalLayout('correctEdgeCollisions') + .find('.responsive-preview-device') + // Hide layout options that are wider than the current screen + .drupalLayout('prunePreviewChoices', edgeTolerance) + // The
  • s will be toggled. Assign them to options. + .parent('li'); + + $toolbarTab.toggle(options.not('.element-hidden').length > 0); + } + + /** + * Resizes the preview iframe to the configured dimensions of a device. + * + * @param {Object} event + * A jQuery event object. + */ + function loadDevicePreview (event) { + event.preventDefault(); + var $link = $(event.target); + device.width = $link.data('responsive-preview-width'); + device.height = $link.data('responsive-preview-height'); + // Toggle the preview on. + toggleLayoutPreview(event, true); + updateDimensions(); + } + + /** + * Redraws the layout preview component based on the stored dimensions. + * + * @param {Object} event + * A jQuery event object. + */ + function refreshPreviewSizing (event) { + $frame + .stop(true, true) + .animate({ + left: leftOffset, + width: size + }, 'fast'); + // Reposition the close button. + $('#responsive-preview-close') + .css({ + 'left': (leftOffset + size) + }); + } + + /** + * Get the total displacement of given region. + * + * @param {String} region + * Region name. Either "top" or "bottom". + * + * @return {Number} + * The total displacement of given region in pixels. + */ + function getDisplacement (region) { + var displacement = 0; + var lastDisplaced = $('[data-offset-' + region + ']'); + if (lastDisplaced.length) { + displacement = parseInt(lastDisplaced.attr('data-offset-' + region), 10); + } + return displacement; + } + + /** + * A jQuery plugin that contains element manipulation utilities. + * + * @return {Function} + * The method to invoke this plugin. + */ + $.fn.drupalLayout = (function () { + + /** + * Corrects element window edge collisions. + * + * Elements are moved back into the window if part of the element is + * rendered outside the visible window. + */ + function correct () { + // Clear any previous corrections. + clear.apply(this); + // Go through each element and correct edge collisions. + return this.each(function (index, element) { + var $this = $(this); + var width = $this.width(); + var height = $this.height(); + var clientW = document.documentElement.clientWidth; + var clientH = document.documentElement.clientHeight; + var collisions = { + 'top': null, + 'right': null, + 'bottom': null, + 'left': null + }; + // Determine if the element is too big for the document. Resize to fit. + if (width > clientW) { + $this.width(clientW); + // If the element is too wide, it will collide on both left and right. + collisions.left = true; + collisions.right = true; + } + if (height > clientH) { + $this.height(clientH); + // If the element is too high, it will collide on both top and bottom. + collisions.top = true; + collisions.bottom = true; + } + // Check each edge for a collision. + if (!collisions.top && $this.offset().top < 0) { + collisions.top = true; + } + if (!collisions.right && (($this.offset().left + width) > clientW)) { + collisions.right = true; + } + if (!collisions.bottom && (($this.offset().top + height) > clientH)) { + collisions.bottom = true; + } + if (!collisions.left && $this.offset().left < 0) { + collisions.left = true; + } + // Set the offset to zero for any collision on an edge. + for (var edge in collisions) { + if (collisions.hasOwnProperty(edge)) { + if (collisions[edge]) { + $this.css(edge, 0); + } + } + } + }); + } + + /** + * Clears any previous edge correction styling. + */ + function clear () { + var edges = ['top', 'right', 'bottom', 'left']; + return this.each(function (index, element) { + for (var i = 0; i < edges.length; i++) { + this.style[edges[i]] = ""; + } + }); + } + + /** + * Hides device preview options that are too wide for the current window. + * + * @param {Number} tolerance + * - The distance from the edge of the window that a device cannot exceed + * or it will be pruned from the list. + */ + function prune (tolerance) { + var docWidth = document.documentElement.clientWidth; + tolerance = (typeof tolerance === 'number' && tolerance > 0) ? tolerance : 0; + return this.each(function () { + var $this = $(this); + var width = parseInt($this.data('responsive-preview-width'), 10); + var fits = ((width + (tolerance * 2)) < docWidth); + $this.parent('li').toggleClass('element-hidden', !fits); + }); + } + + /** + * Methods that this plugin exposes. + */ + var methods = { + 'correctEdgeCollisions': correct, + 'prunePreviewChoices': prune + }; + + return function (method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } + else { + $.error(Drupal.t('Method @method does not exist in this plugin.', {'@method': method})); + } + }; + + }()); + + /** + * Registers theme templates with Drupal.theme(). + */ + $.extend(Drupal.theme, { + /** + * Theme function for the preview container element. + * + * @return + * The corresponding HTML. + */ + layoutContainer: function () { + return '
    '; + }, + + /** + * Theme function for the close button for the preview container. + * + * @return + * The corresponding HTML. + */ + layoutClose: function () { + return ''; + }, + + /** + * Theme function for a responsive preview iframe element. + * + * @return + * The corresponding HTML. + */ + layoutFrame: function (url) { + return ''; + } + }); + +}(jQuery, Drupal)); diff --git a/core/modules/responsive_preview/responsive_preview.info b/core/modules/responsive_preview/responsive_preview.info new file mode 100644 index 0000000..06e86eb --- /dev/null +++ b/core/modules/responsive_preview/responsive_preview.info @@ -0,0 +1,5 @@ +name = Responsive Preview +description = Provides a component that previews the a page in various device dimensions. +package = Core +version = VERSION +core = 8.x diff --git a/core/modules/responsive_preview/responsive_preview.module b/core/modules/responsive_preview/responsive_preview.module new file mode 100644 index 0000000..ac67170 --- /dev/null +++ b/core/modules/responsive_preview/responsive_preview.module @@ -0,0 +1,112 @@ +get('devices'); + + $links = array(); + + foreach($devices as $name => $info) { + $links[$name] = array( + 'title' => $info['label'], + 'href' => '', + 'fragment' => '!', + 'exteranl' => TRUE, + 'options' => array( + 'fragment' => '!', + 'exteranl' => TRUE, + ), + 'attributes' => array( + 'class' => array('responsive-preview-device'), + 'data-responsive-preview-width' => ($info['dimensions']['width']) ? $info['dimensions']['width'] : '', + 'data-responsive-preview-height' => ($info['dimensions']['height']) ? $info['dimensions']['height'] : '', + ), + ); + } + return $links; +} + +function responsive_preview_access() { + return !path_is_admin(current_path()); +} + +/** + * Implements hook_toolbar(). + */ +function responsive_preview_toolbar() { + + $items['responsive_preview'] = array( + '#type' => 'toolbar_item', + 'tab' => array( + 'trigger' => array( + '#theme' => 'html_tag', + '#tag' => 'button', + '#value' => t('Layout preview'), + '#attributes' => array( + 'id' => 'responsive-preview', + 'title' => "Preview page layout", + 'class' => array('icon', 'icon-responsive-preview', 'trigger'), + ), + ), + 'device_options' => array( + '#theme' => 'links', + '#links' => responsive_preview_get_devices_list(), + '#attributes' => array( + 'class' => array('responsive-preview-options'), + ), + ), + ), + '#wrapper_attributes' => array( + 'class' => array('responsive-preview-toolbar-tab'), + ), + '#attached' => array( + 'library' => array( + array('responsive_preview', 'responsive-preview'), + ), + ), + '#weight' => 200, + '#access' => responsive_preview_access(), + ); + + return $items; +} + +/** + * Implements hook_library(). + */ +function responsive_preview_library_info() { + $libraries = array(); + $path = drupal_get_path('module', 'responsive_preview'); + $options = array( + 'scope' => 'footer', + 'attributes' => array('defer' => TRUE), + ); + + $libraries['responsive-preview'] = array( + 'title' => 'Preview layouts', + 'website' => 'http://drupal.org/project/responsive_preview', + 'version' => VERSION, + 'css' => array( + $path . '/css/responsive-preview.base.css', + $path . '/css/responsive-preview.theme.css', + ), + 'js' => array( + $path . '/js/responsive-preview.js' => $options, + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + + return $libraries; +} -- 1.7.10.4