diff --git a/core/modules/outside_in/js/off-canvas.iframe.js b/core/modules/outside_in/js/off-canvas.iframe.js new file mode 100644 index 0000000..30a6067 --- /dev/null +++ b/core/modules/outside_in/js/off-canvas.iframe.js @@ -0,0 +1,33 @@ +/** + * @file + * Drupal's off_canvas_iframe library. + */ + +(function ($, Drupal) { + 'use strict'; + + /** + * Ensure that links in the iframe use the correct renderer. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Append the correct _wrapper_format for links in the iframe. + */ + Drupal.behaviors.offCanvasIFrameLinks = { + attach: function (context) { + var $context = $(context); + // Update href for all links not targeting the "_parent". + $context.find('a[target!="_parent"]').each(function () { + $(this).attr('href', $(this).attr('href') + '?_wrapper_format=drupal_dialog_offcanvas'); + }); + $context.find('[data-dialog-renderer="offcanvas"]').each(function () { + $(this).removeAttr('data-dialog-renderer'); + $(this).removeAttr('data-dialog-type'); + + }); + + // @todo What should happen with off-canvas + } + }; +})(jQuery, Drupal); diff --git a/core/modules/outside_in/js/offcanvas.js b/core/modules/outside_in/js/offcanvas.js index 8cda69d..7b5749d 100644 --- a/core/modules/outside_in/js/offcanvas.js +++ b/core/modules/outside_in/js/offcanvas.js @@ -144,4 +144,73 @@ } }); + /** + * Add the Off-canvas wrapper format to the path. + * + * @param {string} path + * The path. + * @return {string} + * The appended path. + */ + function addFormatWrapper(path) { + if (path.includes('?')) { + path += '&'; + } + else { + path += '?'; + } + return path + '_wrapper_format=drupal_dialog_offcanvas'; + } + + /** + * Open off-canvas links in an iframe dialog. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + */ + Drupal.behaviors.offCanvasLinks = { + attach: function (context) { + if ($('.off-canvas-iframe').length) { + // Already in off-canvas iframe do not open any links in the nested + // iframe. + // @see \Drupal\outside_in\Render\MainContent\OffCanvasRender::renderResponse + return; + } + + $(context).find('[data-dialog-renderer="offcanvas"]').on('click', function (event) { + event.preventDefault(); + + var path = addFormatWrapper($(event.currentTarget).attr('href')); + if (!$('#drupal-offcanvas').length) { + $('
').appendTo('body'); + } + var $dialog = $('#drupal-offcanvas'); + $('#iframe-dialog').attr('src', path); + var dialogOptions = { + dialogClass: 'ui-dialog-outside-in ui-dialog-offcanvas', + modal: false, + autoResize: false, + resizable: 'w', + draggable: false, + drupalAutoButtons: false, + buttons: [] + }; + var dialog = Drupal.dialog($dialog.get(0), dialogOptions); + + $('iframe').on('load', function () { + if (!$('.ui-dialog-title').length) { + dialog.show(); + } + else { + var iframeTitle = document.getElementById('iframe-dialog').contentDocument.title; + $('.ui-dialog-title').text(iframeTitle); + } + }); + + }); + + } + }; + })(jQuery, Drupal, Drupal.debounce, Drupal.displace); diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js index 44dda51..723075c 100644 --- a/core/modules/outside_in/js/outside_in.js +++ b/core/modules/outside_in/js/outside_in.js @@ -210,43 +210,6 @@ attach: function (context) { $(toggleEditSelector).once('outsidein').on('click.outsidein', toggleEditMode); - var $context = $(context); - - $context.find('[data-dialog-renderer="offcanvas"]').on('click', function (event) { - event.preventDefault(); - - var path = $(event.currentTarget).attr('href') + '&_wrapper_format=drupal_dialog_offcanvas'; - if (!$('#drupal-offcanvas').length) { - $('').appendTo('body'); - } - var $dialog = $('#drupal-offcanvas'); - $('#iframe-dialog').attr('src', path); - var dialogOptions = { - dialogClass: 'ui-dialog-outside-in ui-dialog-offcanvas', - modal: false, - autoResize: false, - resizable: 'w', - draggable: false, - drupalAutoButtons: false, - buttons: [] - }; - var dialog = Drupal.dialog($dialog.get(0), dialogOptions); - - $('iframe').on('load', function () { - if (!$('.ui-dialog-title').length) { - dialog.show(); - } - else { - var iframeTitle = document.getElementById('iframe-dialog').contentDocument.title; - $('.ui-dialog-title').text(iframeTitle); - } - - - - }); - - }); - } }; diff --git a/core/modules/outside_in/outside_in.libraries.yml b/core/modules/outside_in/outside_in.libraries.yml index ec6228c..ecc75a2 100644 --- a/core/modules/outside_in/outside_in.libraries.yml +++ b/core/modules/outside_in/outside_in.libraries.yml @@ -34,3 +34,9 @@ drupal.off_canvas: - core/drupal.announce - core/drupal.dialog - core/drupal.dialog.ajax +drupal.off_canvas_iframe: + version: VERSION + js: + js/off-canvas.iframe.js: {} + dependencies: + - core/jquery diff --git a/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php b/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php index 3a6e420..63711b7 100644 --- a/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php +++ b/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php @@ -36,6 +36,7 @@ public function title(BlockInterface $block) { */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); + $form['#attributes']['target'] = '_parent'; // Create link to full block form. $query = []; diff --git a/core/modules/outside_in/src/Render/MainContent/OffCanvasRender.php b/core/modules/outside_in/src/Render/MainContent/OffCanvasRender.php index 41c2089..37cd741 100644 --- a/core/modules/outside_in/src/Render/MainContent/OffCanvasRender.php +++ b/core/modules/outside_in/src/Render/MainContent/OffCanvasRender.php @@ -28,6 +28,17 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte /** * {@inheritdoc} */ + public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) { + $main_content['#attached']['library'][] = 'outside_in/drupal.off_canvas_iframe'; + // Add a class so that JS can determine if we are currently in the iframe. + // @todo Will adding the class always work on the top level? + $main_content['#attributes']['class'][] = 'off-canvas-iframe'; + return parent::renderResponse($main_content, $request, $route_match); + } + + /** + * {@inheritdoc} + */ public function buildPageTopAndBottom(array &$html) { parent::buildPageTopAndBottom($html); unset($html['page_top']['toolbar']); diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml b/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml index 761693b..abbb7af 100644 --- a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml +++ b/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml @@ -17,6 +17,7 @@ offcanvas_test.thing1: offcanvas_test.thing2: path: '/offcanvas-thing2' defaults: + _title: 'Thing 2' _controller: '\Drupal\offcanvas_test\Controller\TestController::thing2' requirements: _access: 'TRUE' diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php b/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php index 9ee8e17..2fd9736 100644 --- a/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php +++ b/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php @@ -49,7 +49,6 @@ public function linksDisplay() { '#type' => 'link', '#url' => Url::fromRoute('offcanvas_test.thing1'), '#attributes' => [ - 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', 'data-dialog-renderer' => 'offcanvas', ], @@ -64,7 +63,6 @@ public function linksDisplay() { '#type' => 'link', '#url' => Url::fromRoute('offcanvas_test.thing2'), '#attributes' => [ - 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', 'data-dialog-renderer' => 'offcanvas', 'data-dialog-options' => Json::encode([ @@ -82,7 +80,6 @@ public function linksDisplay() { '#type' => 'link', '#url' => Url::fromRoute('offcanvas_test.dialog_links'), '#attributes' => [ - 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', 'data-dialog-renderer' => 'offcanvas', ], @@ -123,7 +120,6 @@ public function otherDialogLinks() { 'title' => 'Offcanvas link!', 'url' => Url::fromRoute('offcanvas_test.thing2'), 'attributes' => [ - 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', 'data-dialog-renderer' => 'offcanvas', ],