diff --git a/css/panopoly-modal.css b/css/panopoly-modal.css index 31c4003..0cb7705 100644 --- a/css/panopoly-modal.css +++ b/css/panopoly-modal.css @@ -207,8 +207,8 @@ } #modal-content fieldset.widget-preview { - margin-top: 3em; - margin-bottom: 4em; + margin-top: 2em; + margin-bottom: 5em; -webkitborder-top-right-radius: 0; -moz-border-topright-radius: 0; border-top-right-radius: 0; @@ -328,7 +328,8 @@ #modalContent .widget-preview-title .content-type-button span { width: auto; - padding: 0 0 0 10px; + padding: 0 0 0 5px; + top: 0; } #modal-content .widget-preview-title .content-type-button a { @@ -394,12 +395,16 @@ #modal-content .panels-section-columns, #modal-content .panels-categories-description { + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; overflow: visible; border: 1px solid #CECECA; border-right: none; height: 100%; margin: 0; margin-top: 1px; + padding-top: 1em; overflow-y: auto; } @@ -551,3 +556,64 @@ -moz-box-shadow: 0 0 0 0 #fff; box-shadow: 0 0 0 0 #fff; } + +#modal-content .content-wrapper { + position: relative; + padding: 5px 0px; +} + +#modal-content .content-wrapper .content-type-button { + position: absolute; + right: 10px; + top: 50%; + margin-top: -10px; +} + +#modal-content .content-wrapper .content-type-button a { + background: #999; + float: left; + color: white; + padding: 5px 10px; + opacity: 0; +} + +#modal-content .content-wrapper .content-type-button a img { + display: none; +} + +#modal-content .content-wrapper .content-type-button a span { + margin: 0; + padding: 0; + left: 0; + top: 0; +} + +#modal-content .content-wrapper .content-type-button a:hover, +#modal-content .content-wrapper .content-type-button a:focus { + background: #2fa6e5; +} + +#modal-content .content-wrapper .fieldset-legend a { + background: transparent; + border: none; + color: #666; + text-shadow: none; + margin: 0; + padding: 0px 10px 0px 10px; + text-align: left; + cursor: pointer; +} + +#modal-content .content-wrapper .fieldset-legend a:hover, +#modal-content .content-wrapper .fieldset-legend a:focus { + color: #000; +} + +#modal-content .content-wrapper:hover { + background-color: #f1f1f1; +} + +#modal-content .content-wrapper:hover .content-type-button a, +#modal-content .content-wrapper .content-type-button a:focus { + opacity: 1; +} diff --git a/panopoly-magic.js b/panopoly-magic.js index a743420..195bbe3 100644 --- a/panopoly-magic.js +++ b/panopoly-magic.js @@ -1,23 +1,29 @@ (function ($) { - - Drupal.behaviors.panopolyMagic = { - attach: function (context, settings) { - - /** - * Title Hax for Panopoly - * - * Replaces the markup of a node title pane with - * the h1.title page element - */ - if ($.trim($('.pane-node-title .pane-content').html()) == $.trim($('h1.title').html())) { - $('.pane-node-title .pane-content').html(''); - $('h1.title').hide().clone().prependTo('.pane-node-title .pane-content'); - $('.pane-node-title h1.title').show(); - } - - } - } - + Drupal.behaviors.panopolyMagic = { + attach: function (context, settings) { + + /** + * Title Hax for Panopoly + * + * Replaces the markup of a node title pane with + * the h1.title page element + */ + if ($.trim($('.pane-node-title .pane-content').html()) == $.trim($('h1.title').html())) { + $('.pane-node-title .pane-content').html(''); + $('h1.title').hide().clone().prependTo('.pane-node-title .pane-content'); + $('.pane-node-title h1.title').show(); + } + + // Focus on the 'Add' button for a single widget preview, after it's loaded. + if (settings.panopoly_magic && settings.panopoly_magic.pane_add_preview === 'single') { + // Need to defer until current set of behaviors is done, because Panels + // will move the focus to the first widget by default. + setTimeout(function () { + $('.widget-preview .content-type-button a', context).focus(); + }, 0); + } + } + }; })(jQuery); (function ($) { diff --git a/panopoly_magic.install b/panopoly_magic.install index 9a0168a..ac6a72a 100644 --- a/panopoly_magic.install +++ b/panopoly_magic.install @@ -43,3 +43,12 @@ function panopoly_magic_update_7101() { function panopoly_magic_update_7102() { views_flush_caches(); } + +/** + * Preserve the old 'Add content' preview default. + */ +function panopoly_magic_update_7103() { + if (variable_get('panopoly_magic_pane_add_preview', 'not set') === 'not set') { + variable_set('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_AUTOMATIC); + } +} diff --git a/panopoly_magic.module b/panopoly_magic.module index a583ac3..27675cd 100644 --- a/panopoly_magic.module +++ b/panopoly_magic.module @@ -1,10 +1,12 @@ array( + 'pane_add_preview' => $pane_add_preview, + )), 'setting'); } /** @@ -146,6 +167,7 @@ function panopoly_magic_configure_form($form, &$form_state) { '#options' => array( PANOPOLY_ADD_PREVIEW_AUTOMATIC => 'Automatic', PANOPOLY_ADD_PREVIEW_MANUAL => 'Manual', + PANOPOLY_ADD_PREVIEW_SINGLE => 'Single', PANOPOLY_ADD_PREVIEW_DISABLED => 'Disabled', ), '#default_value' => variable_get('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_DEFAULT), @@ -1361,31 +1383,76 @@ function panopoly_magic_views_pre_view(&$view) { } /** + * Helper function to display the pane for showing previews in the add_content modal + */ +function _panopoly_magic_render_preview_pane(&$plugin, $renderer) { + $pane = panels_new_pane($plugin['type_name'], $plugin['subtype_name'], TRUE); + $display = $renderer->display; + $context = $renderer->display->context; + $args = $renderer->display->args; + $incoming_content = $renderer->display->incoming_content; + $keywords = (!empty($renderer->display->keywords)) ? $renderer->display->keywords : array(); + if ($content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, $keywords, $args, $context, $incoming_content)) { + $strip_js = variable_get('panopoly_magic_strip_js_from_preview', 0); + $plugin['preview'] = theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)); + if (!empty($strip_js) && !empty($plugin['preview'])) { + $plugin['preview'] = preg_replace('#(.*?)#is', '', $plugin['preview']); + } + } +} + +/** * Preprocess the panels_add_content_modal() function to add the HTML for the preview */ function panopoly_magic_preprocess_panels_add_content_modal(&$vars) { // Generate the pane preview if (!empty($vars['categories'][$vars['category']]['content'])) { - foreach ($vars['categories'][$vars['category']]['content'] as &$plugin) { - $use_preview = (variable_get('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_DEFAULT) == PANOPOLY_ADD_PREVIEW_AUTOMATIC); - $strip_js = variable_get('panopoly_magic_strip_js_from_preview', 0); + $use_preview = variable_get('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_DEFAULT); + if ($use_preview == PANOPOLY_ADD_PREVIEW_DISABLED) { + return; + } + + // Generate the preview for the single widget if requested. + if ($use_preview == PANOPOLY_ADD_PREVIEW_SINGLE) { + $query = drupal_get_query_parameters(); + $type_name = !empty($query['type_name']) ? $query['type_name'] : ''; + $sub_type = !empty($query['subtype_name']) ? $query['subtype_name'] : ''; + $plugin = array( + 'type_name' => $type_name, + 'subtype_name' => $sub_type, + ); + _panopoly_magic_render_preview_pane($plugin, $vars['renderer']); + $vars['column_count'] = 1; + $vars['preview_single'] = isset($plugin['preview']) ? $plugin['preview'] : ''; + $vars['preview_single_title'] = ''; + foreach ($vars['categories'][$vars['category']]['content'] as $key => $plugin) { + if ($plugin['type_name'] == $type_name && $plugin['subtype_name'] == $sub_type) { + $vars['preview_single_title'] = $key; + break; + } + } + } + + // Process each widget option, either adding the preview itself or a link to generate it. + foreach ($vars['categories'][$vars['category']]['content'] as $key => &$plugin) { $query = drupal_get_query_parameters(); $preview_panes = (!empty($query['preview_panes'])) ? explode(',', $query['preview_panes']) : array(); // Determine if we should show a preview for this pane. - if (!empty($use_preview) || in_array($plugin['subtype_name'], $preview_panes)) { - $pane = panels_new_pane($plugin['type_name'], $plugin['subtype_name'], TRUE); - $display = $vars['renderer']->display; - $context = $vars['renderer']->display->context; - $args = $vars['renderer']->display->args; - $incoming_content = $vars['renderer']->display->incoming_content; - $keywords = (!empty($vars['renderer']->display->keywords)) ? $vars['renderer']->display->keywords : array(); - if ($content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, $keywords, $args, $context, $incoming_content)) { - $plugin['preview'] = theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)); - if (!empty($strip_js) && !empty($plugin['preview'])) { - $plugin['preview'] = preg_replace('#(.*?)#is', '', $plugin['preview']); - } - } + if ($use_preview == PANOPOLY_ADD_PREVIEW_SINGLE) { + // Convert the link to generate a preview of itself. + $options = array( + 'query' => array( + 'type_name' => $plugin['type_name'], + 'subtype_name' => $plugin['subtype_name'], + ), + 'attributes' => array('class' => array('use-ajax button')), + 'html' => TRUE, + ); + $plugin['title'] = l(filter_xss_admin($plugin['title']), current_path(), $options); + } + elseif ($use_preview == PANOPOLY_ADD_PREVIEW_AUTOMATIC || in_array($plugin['subtype_name'], $preview_panes)) { + _panopoly_magic_render_preview_pane($plugin, $vars['renderer']); } else { @@ -1393,7 +1460,10 @@ function panopoly_magic_preprocess_panels_add_content_modal(&$vars) { $preview = empty($query['preview_panes']) ? $plugin['subtype_name'] : $query['preview_panes'] . ',' . $plugin['subtype_name']; $options = array( 'query' => array('preview_panes' => $preview), - 'attributes' => array('class' => array('use-ajax button')) + 'attributes' => array( + 'class' => array('use-ajax button'), + 'title' => t('Preview @widget widget', array('@widget' => $key)), + ), ); $plugin['preview'] = ''; } @@ -1401,11 +1471,55 @@ function panopoly_magic_preprocess_panels_add_content_modal(&$vars) { } } -/** +/** + * Helper function to render the Panels add content link. + */ +function _panopoly_magic_render_add_content_link($vars, $content_type, $title) { + $content_type['title'] = t('Add'); + // @todo: Investigate why view_panes are missing description. + if (empty($content_type['description'])) { + $content_type['description'] = $title; + } + + return theme('panels_add_content_link', array( + 'renderer' => $vars['renderer'], + 'region' => $vars['region'], + 'content_type' => $content_type, + )); +} + + +/** + * Helper function to render the Panels add content link or preview (or both). + */ +function _panopoly_magic_render_link_or_preview($title, $link = '', $preview = FALSE) { + // @todo: These would be easier to read as templates. + $html = ''; + if ($preview) { + $html .= '
'; + $html .= ''; + $html .= '
' . $link . '
'; + $html .= '' . $title . ''; + $html .= '
'; + $html .= '
' . $preview . '
'; + $html .= '
'; + } + else { + $html .= '
'; + $html .= '' . $title . ''; + $html .= $link; + $html .= '
'; + } + + return $html; +} + +/** * Process the panels_add_content_modal() to adjust the markup to present the preview */ function panopoly_magic_process_panels_add_content_modal(&$vars) { - if (variable_get('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_DEFAULT) == PANOPOLY_ADD_PREVIEW_DISABLED) { + $use_preview = variable_get('panopoly_magic_pane_add_preview', PANOPOLY_ADD_PREVIEW_DEFAULT); + if ($use_preview == PANOPOLY_ADD_PREVIEW_DISABLED) { return; } @@ -1428,17 +1542,32 @@ function panopoly_magic_process_panels_add_content_modal(&$vars) { $vars['columns'][$which] = ''; } + // Render the single preview if it's requested. + if ($use_preview == PANOPOLY_ADD_PREVIEW_SINGLE) { + $title = $vars['preview_single_title']; + + $legend_title = !empty($title) ? $title : t('Select a widget to show its preview'); + $add_content_link = !empty($title) ? _panopoly_magic_render_add_content_link($vars, $content[$title], $title) : ''; + $preview = !empty($vars['preview_single']) ? $vars['preview_single'] : t('No Preview'); + + $vars['columns'][0] = _panopoly_magic_render_link_or_preview($legend_title, $add_content_link, $preview); + } + // Read the column data with our preview functionality $count = 0; foreach ($titles as $title) { $which = floor($count++ / $col_size) + 1; - // @todo: Investigate why view_panes are missing description. - if (empty($content[$title]['description'])) { - $content[$title]['description'] = $title; + $legend_title = $content[$title]['title']; + $add_content_link = _panopoly_magic_render_add_content_link($vars, $content[$title], $title); + + if ($use_preview == PANOPOLY_ADD_PREVIEW_SINGLE) { + $vars['columns'][$which] .= _panopoly_magic_render_link_or_preview($legend_title, $add_content_link); + } + else { + $preview = !empty($content[$title]['preview']) ? $content[$title]['preview'] : t('No Preview'); + $vars['columns'][$which] .= _panopoly_magic_render_link_or_preview($legend_title, $add_content_link, $preview); } - $content[$title]['title'] = 'Add'; - $vars['columns'][$which] .= '
' . theme('panels_add_content_link', array('renderer' => $vars['renderer'], 'region' => $vars['region'], 'content_type' => $content[$title])) . '
' . $title . '
' . (!empty($content[$title]['preview']) ? $content[$title]['preview'] : t('No Preview')) . '
'; } } }