diff -u b/core/modules/outside_in/js/offcanvas.js b/core/modules/outside_in/js/offcanvas.js --- b/core/modules/outside_in/js/offcanvas.js +++ b/core/modules/outside_in/js/offcanvas.js @@ -15,12 +15,9 @@ */ var createOffCanvasWrapper = function (pageWidth) { return $('
', { - id: 'offcanvas', + 'id': 'offcanvas', 'role': 'region', - 'aria-labelledby': 'offcanvas-header', - css: { - right: '-25%' - } + 'aria-labelledby': 'offcanvas-header' }); }; @@ -50,30 +47,26 @@ * Create the off canvas close element. * @param {object} offCanvasWrapper * The jQuery off canvas wrapper element - * @param {object} page - * The #page element. - * @param {number} pageWidth - * The width of #page-wrapper - * @param {number} animationDuration - * The duration of the animation. + * @param {object} pageWrapper + * The jQuery off page wrapper element * @return {object} * jQuery object that is the off canvas close element. */ - var createOffCanvasClose = function (offCanvasWrapper, page, pageWidth, animationDuration) { - return $('', {class: 'offcanvasClose', 'aria-label': Drupal.t('Close configuration tray.'), text: 'x'}).click(function () { - offCanvasWrapper.animate({right: -(pageWidth * .2)}, {duration: animationDuration, queue: false}); - page - .animate({width: '100%'}, {duration: animationDuration, queue: false, complete: function () { - // Remove some leftovers on $page. - page - .removeClass('offCanvasDisplayed') - .removeAttr('style'); - - // Remove off canvas element, and set display state variable. + var createOffCanvasClose = function (offCanvasWrapper, pageWrapper) { + return $('', { + 'class': 'offcanvasClose', + 'aria-label': Drupal.t('Close configuration tray.'), + 'text': 'x' + }).click(function () { + pageWrapper + .removeClass('js-tray-open'); + offCanvasWrapper.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', + function (e) { Drupal.offCanvas.visible = false; offCanvasWrapper.remove(); Drupal.announce(Drupal.t('Configuration tray closed.')); - }}); + } + ); }); }; @@ -93,12 +86,9 @@ */ Drupal.AjaxCommands.prototype.openOffCanvas = function (ajax, response, status) { // Set animation duration and get #page-wrapper width. - var animationDuration = 600; var $pageWrapper = $('#canvas-tray-wrapper'); var pageWidth = $pageWrapper.width(); - var $page = $('#canvas-tray'); - // Set the initial state of the off canvas element. // If the state has been set previously, use it. Drupal.offCanvas = { @@ -109,7 +99,7 @@ var $offcanvasWrapper = createOffCanvasWrapper(pageWidth); // Construct off canvas internal elements. - var $offcanvasClose = createOffCanvasClose($offcanvasWrapper, $page, pageWidth, animationDuration); + var $offcanvasClose = createOffCanvasClose($offcanvasWrapper, $pageWrapper); var $title = createTitle(response.dialogOptions.title); var $offcanvasContent = createOffCanvasContent(response.data); @@ -121,34 +111,9 @@ // Append off canvas wrapper to the 'page' $pageWrapper.append($offcanvasWrapper); - // Animate $page and $offcanvasWrapper to simulate a slide in effect - $page - .animate({ - width: '75%' - }, { - duration: animationDuration, - queue: false, - start: function () { - $page.addClass('offCanvasDisplayInProgress'); - }, - complete: function () { - $page - .removeClass('offCanvasDisplayInProgress') - .addClass('offCanvasDisplayed'); - } - }); - $offcanvasWrapper - .animate({right: '0%'}, { - duration: animationDuration, - queue: false, - start: function () { - // Set the offCanvas visible state. - Drupal.offCanvas.visible = true; - }, - complete: function() { - Drupal.announce(Drupal.t('Configuration tray opened.')); - } - }); + Drupal.offCanvas.visible = true; + $pageWrapper + .addClass('js-tray-open'); } return false; diff -u b/core/modules/outside_in/outside_in.libraries.yml b/core/modules/outside_in/outside_in.libraries.yml --- b/core/modules/outside_in/outside_in.libraries.yml +++ b/core/modules/outside_in/outside_in.libraries.yml @@ -4,7 +4,9 @@ js/offcanvas.js: {} css: component: - css/offcanvas.css: {} + css/outside_in.base.css: {} + css/outside_in.module.css: {} + css/outside_in.theme.css: {} dependencies: - core/jquery - core/drupal diff -u b/core/modules/outside_in/outside_in.module b/core/modules/outside_in/outside_in.module --- b/core/modules/outside_in/outside_in.module +++ b/core/modules/outside_in/outside_in.module @@ -5,9 +5,11 @@ * Allows configuring blocks and other configuration from the front-end of the site. */ + use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Routing\RouteMatchInterface; - +use Drupal\Component\Utility\Html; +use Drupal\Component\Utility\Xss; /** * Implements hook_help(). */ diff -u b/core/modules/outside_in/outside_in.services.yml b/core/modules/outside_in/outside_in.services.yml --- b/core/modules/outside_in/outside_in.services.yml +++ b/core/modules/outside_in/outside_in.services.yml @@ -4,7 +4,6 @@ arguments: ['@title_resolver', '@renderer'] tags: - { name: render.main_content_renderer, format: drupal_offcanvas } - outside_in.block.manager: class: Drupal\outside_in\OutsideInBlockManager arguments: ['@class_resolver'] diff -u b/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php b/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php --- b/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php +++ b/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php @@ -11,7 +11,7 @@ * @Block( * id = "offcanvas_links_block", * form = { - * "offcanvas" = "\Drupal\offcanvas_test\Form\OffcanvasForm" + * "sidebar" = "\Drupal\offcanvas_test\Form\SidebarForm" * }, * admin_label = @Translation("Offcanvas test block") * ) diff -u b/core/modules/outside_in/tests/src/Kernel/MultipleBlockFormTest.php b/core/modules/outside_in/tests/src/Kernel/MultipleBlockFormTest.php --- b/core/modules/outside_in/tests/src/Kernel/MultipleBlockFormTest.php +++ b/core/modules/outside_in/tests/src/Kernel/MultipleBlockFormTest.php @@ -3,7 +3,7 @@ namespace Drupal\Tests\outside_in\Kernel; use Drupal\KernelTests\KernelTestBase; -use Drupal\offcanvas_test\Form\OffcanvasForm; +use Drupal\offcanvas_test\Form\SidebarForm; /** * Tests that blocks can have multiple forms. @@ -24,14 +24,14 @@ $block = \Drupal::service('plugin.manager.block')->createInstance('offcanvas_links_block'); $form_object1 = \Drupal::service('outside_in.block.manager')->getFormObject($block, 'default'); - $form_object2 = \Drupal::service('outside_in.block.manager')->getFormObject($block, 'offcanvas'); + $form_object2 = \Drupal::service('outside_in.block.manager')->getFormObject($block, 'sidebar'); // Assert that the block itself is used for the default form. $this->assertSame($block, $form_object1); - $expected_offcanvas = new OffcanvasForm(); - $expected_offcanvas->setOperation('offcanvas'); - $this->assertEquals($expected_offcanvas, $form_object2); + $expected_sidebar = new SidebarForm(); + $expected_sidebar->setOperation('sidebar'); + $this->assertEquals($expected_sidebar, $form_object2); } } only in patch2: unchanged: --- /dev/null +++ b/core/modules/outside_in/css/outside_in.base.css @@ -0,0 +1,184 @@ +/** + * @file + * Resets for Outside-In module. + */ + +/** + * Resets + * inside the wrapper override font styling the page provides, this may look a bit extreme + * but any module may place any new form element in this tray therefore CSS from any + * front-end-theme needs to be overridden + */ +#offcanvas abbr, +#offcanvas acronym, +#offcanvas address, +#offcanvas article, +#offcanvas aside, +#offcanvas audio, +#offcanvas b, +#offcanvas caption, +#offcanvas center, +#offcanvas cite, +#offcanvas code, +#offcanvas dd, +#offcanvas del, +#offcanvas details, +#offcanvas dfn, +#offcanvas dialog, +#offcanvas div, +#offcanvas dl, +#offcanvas dt, +#offcanvas em, +#offcanvas embed, +#offcanvas fieldset, +#offcanvas figcaption, +#offcanvas figure, +#offcanvas font, +#offcanvas footer, +#offcanvas form, +#offcanvas h1, +#offcanvas h2, +#offcanvas h3, +#offcanvas h4, +#offcanvas h5, +#offcanvas h6, +#offcanvas header, +#offcanvas hgroup, +#offcanvas i, +#offcanvas img, +#offcanvas ins, +#offcanvas kbd, +#offcanvas label, +#offcanvas legend, +#offcanvas li, +#offcanvas mark, +#offcanvas menu, +#offcanvas meter, +#offcanvas nav, +#offcanvas object, +#offcanvas ol, +#offcanvas output, +#offcanvas p, +#offcanvas pre, +#offcanvas progress, +#offcanvas q, +#offcanvas rp, +#offcanvas rt, +#offcanvas ruby, +#offcanvas s, +#offcanvas samp, +#offcanvas section, +#offcanvas small, +#offcanvas span, +#offcanvas strike, +#offcanvas strong, +#offcanvas sub, +#offcanvas summary, +#offcanvas sup, +#offcanvas table, +#offcanvas tbody, +#offcanvas td, +#offcanvas tfoot, +#offcanvas th, +#offcanvas thead, +#offcanvas time, +#offcanvas tr, +#offcanvas tt, +#offcanvas u, +#offcanvas ul, +#offcanvas var, +#offcanvas video { + font-family: 'Lucida Grande','Lucida Sans Unicode','Liberation Sans',sans-serif; + color: #eee; + font-size: 13px; + font-weight: normal; + font-style: normal; + line-height: 1.5em; + text-transform: none; + text-align: left; /* LTR */ + text-indent: 0; + padding:0; +} +/* reset font family rules from formalize to match Druapl (seven theme) */ +#offcanvas ::-webkit-validation-bubble-message, +#offcanvas optgroup, +#offcanvas .ie6_input, +#offcanvas * html textarea, +#offcanvas * html select, +#offcanvas textarea, +#offcanvas select, +#offcanvas button, +#offcanvas a.button, +#offcanvas input[type="date"], +#offcanvas input[type="datetime"], +#offcanvas input[type="datetime-local"], +#offcanvas input[type="email"], +#offcanvas input[type="month"], +#offcanvas input[type="number"], +#offcanvas input[type="password"], +#offcanvas input[type="search"], +#offcanvas input[type="tel"], +#offcanvas input[type="text"], +#offcanvas input[type="time"], +#offcanvas input[type="url"], +#offcanvas input[type="week"], +#offcanvas input[type="reset"], +#offcanvas input[type="submit"], +#offcanvas input[type="button"] { + font-family: 'Lucida Grande','Lucida Sans Unicode','Liberation Sans',sans-serif; +} +/* reset the link color to one that stands out on dark background */ +#offcanvas a { + color: #33aaff; + text-decoration: none; +} +/* reset to sensible vertical rhythm */ +#offcanvas .form-item, +#offcanvas details, +#offcanvas button, +.form-type-checkbox, +.form-type-radio { + margin-top: 0; + margin-bottom: 1.25em; + padding-right: .5em; /* LTR */ + display: inline-block; +} +/* re-set defaults for fieldsets */ +#offcanvas .fieldset-wrapper { + margin: 0; + padding: 0; + border: 0; +} +/* override formalize label styling */ +#offcanvas label { + font-size: 85%; + font-weight: bold; + line-height: 1.5em; +} +/* override formalize button styling */ +#offcanvas button, +#offcanvas .button, +#offcanvas input[type="button"], +#offcanvas input[type="reset"] { + font-weight: normal; + text-shadow: none; + width: auto; + max-width: 50%; + color: #fff; + border-radius: 30px; + border: none; + background-color: #777; + background-image: none; + background-image: none; +} + /* remove browser and formalize focus effects for dark background */ +#offcanvas input:focus, +#offcanvas button:focus, +#offcanvas a.button:focus, +#offcanvas select:focus, +#offcanvas textarea:focus { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + outline: none; +} only in patch2: unchanged: --- /dev/null +++ b/core/modules/outside_in/css/outside_in.module.css @@ -0,0 +1,213 @@ +/** + * @file + * Styling for Outside-In module. + */ + +/* style the offcanvas container */ +#offcanvas { + box-sizing: border-box; + position: fixed; + height: 100%; + overflow-y: auto; + box-shadow: -2px 3px 1px 1px rgba(0, 0, 0, 0.3333); /* LTR */ + display: inline-block; + width: 25%; + -webkit-transform: translate(100%, 0); + -moz-transform: translate(100%, 0); + -o-transform: translate(100%, 0); + -ms-transform: translate(100%, 0); + transform: translate(100%, 0); + transition: all 0.75s; + -webkit-transition: all 0.75s; + -moz-transition: all 0.75s; + z-index: 1000; +} +[dir="rtl"] #offcanvas { + right: auto; + left: 0; +} +#canvas-tray-wrapper #canvas-tray { + width: 100%; + display: inline-block; + transition: all 0.75s; + -webkit-transition: all 0.75s; + -moz-transition: all 0.75s; +} +#canvas-tray-wrapper.js-tray-open #canvas-tray { + width: 75%; +} +#canvas-tray-wrapper.js-tray-open #offcanvas { + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +/* button that closes the offcanvas tray */ +#offcanvas > button.offcanvasClose, +#offcanvas > button.offcanvasClose:hover { /* todo: add hover state */ + position: absolute; + width: 30px; + right: 0; /* LTR */ + top: 1em; + border: 0; + border-radius: 0; + background: url(/core/misc/icons/ffffff/ex.svg) 0 0 no-repeat; + color: transparent; + cursor: pointer; +} +[dir="rtl"] #offcanvas > span.offcanvasClose { + right: auto; + left: 0; +} +#offcanvas > .content { + height: 100%; + padding: 15px; +} +#canvas-tray.offCanvasDisplayInProgress { + position: fixed; + display: inline-block; +} +#canvas-tray.offCanvasDisplayed { + display: inline-block; +} + +/** + * Buttons. + */ + +/* style for primary button */ +#offcanvas .button--primary { + width: auto; + max-width: 50%; + border-radius: 30px; + border: none; + background-image: -webkit-linear-gradient(top,#007bc6,#0071b8); + background-image: linear-gradient(to bottom,#007bc6,#0071b8); +} +#offcanvas .button--primary:hover, +#offcanvas .button--primary:active { + background-color: inherit; +} +/* Style for delete button */ +#offcanvas .button--danger { + width: auto; + max-width: 50%; + border-radius: none; + border: none; + background: transparent; +} +/* special edit link to flow inline with form items that link to more configuration */ +#offcanvas .edit-link { /* todo add markup and class to template */ + display: inline-block; + font-size: 85%; + font-weight: bold; +} + +/** + * Inputs. + */ +#offcanvas textarea, +#offcanvas select, +#offcanvas input[type="date"], +#offcanvas input[type="datetime"], +#offcanvas input[type="datetime-local"], +#offcanvas input[type="email"], +#offcanvas input[type="month"], +#offcanvas input[type="number"], +#offcanvas input[type="password"], +#offcanvas input[type="search"], +#offcanvas input[type="tel"], +#offcanvas input[type="text"], +#offcanvas input[type="time"], +#offcanvas input[type="url"], +#offcanvas input[type="week"], +#offcanvas input[type="range"] { + display: block; + width: 100%; +} +/* reduce the size of descriptions and other elements for scanability */ +#offcanvas .description, +#offcanvas .machine-name-label, +#offcanvas .machine-name-value { + font-size: 85%; + font-weight: normal; + padding-top: .25em; +} + +/* add a background to checkboxes, radois for contrast */ +/* +#offcanvas .radio-wrapper { + display: inline-block; + padding: 1px; + border-radius: 20px; +} +#offcanvas .checkbox-wrapper { + display: inline-block; + padding: 1px; + border-radius: 3px; +} +*/ + +/** + * Fieldsets. + */ +#offcanvas fieldset { + border: 0px solid transparent; + margin-left:-1em; /* push background to the left edge of the parent */ + margin-right:-1em; /* push background to the right edge of the parent */ + padding-top: 2.5em; + padding-left: 1em; + padding-bottom: 1em; + position: relative; +} +#offcanvas fieldset .form-item { + display: block; +} +/* style fieldset legend similar to Drupal (seven theme) */ +#offcanvas span.fieldset-legend { + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 85%; + position: absolute; + top: 10px; +} + +/** + * Admin label. + */ +#offcanvas .form-item-settings-admin-label { + font-size: 1.25em; + width: 100%; + padding: 1em; + padding-top: 0; + margin-top: 0; + margin-left: -1em; + margin-right: -1em; + margin-bottom: 1em; + border-bottom-width: 1px; + border-bottom-style: solid; +} +#offcanvas .form-item-settings-admin-label label { + font-size: 10px; + display: block; + margin-bottom: 0; +} + +#offcanvas span.field-suffix small { /* don't know why it's there. todo: figure out why it's rendering empty and taking space */ + display: none; +} + +/** + * Form actions. + */ +#offcanvas .form-actions { + padding: 1em; + margin-left: -1em; + margin-right: -1em; + border-bottom-width: 1px; + border-bottom-style: solid; +} + + + only in patch2: unchanged: --- /dev/null +++ b/core/modules/outside_in/css/outside_in.theme.css @@ -0,0 +1,128 @@ +/** + * @file + * Visual styling for Outside-In module. + * + * Since visual styling here differs from styling elsewhere in core, + * font and color styles are put here so they can be more easily changed. + * + */ + +/* style the offcanvas container */ +#offcanvas { + color: #eee; + border-left: 1px solid #000; + background: #444; + font-family: 'Lucida Grande','Lucida Sans Unicode','Liberation Sans',sans-serif; +} +#offcanvas .content { + color: #eee; +} +#offcanvas h1 { + margin: 0 0 15px 0; + padding: 15px; + color: #eee; + border-bottom: 1px solid #777; +} + +/** + * Buttons. + */ +#offcanvas button:hover, +#offcanvas button:active, +#offcanvas .button:hover, +#offcanvas .button:active { + background-color: inherit; + background-image: inherit; + background-image: inherit; +} +/* style for primary button */ +#offcanvas .button--primary { + background-image: -webkit-linear-gradient(top,#007bc6,#0071b8); + background-image: linear-gradient(to bottom,#007bc6,#0071b8); + font-weight: bold; + text-shadow: none; + color: #fff; +} +#offcanvas .button--primary:hover, +#offcanvas .button--primary:active { + background-color: inherit; + background-image: -webkit-linear-gradient(top,#007bc6,#0071b8); /* todo: make the hover gradient different from normal */ + background-image: linear-gradient(to bottom,#007bc6,#0071b8); /* todo: make the hover gradient different from normal */ +} +/* Style for delete button */ +#offcanvas .button--danger { + font-weight: bold; + text-shadow: none; + color: #ff3333; +} + +/** + * Inputs. + */ +#offcanvas textarea, +#offcanvas select, +#offcanvas input[type="date"], +#offcanvas input[type="datetime"], +#offcanvas input[type="datetime-local"], +#offcanvas input[type="email"], +#offcanvas input[type="month"], +#offcanvas input[type="number"], +#offcanvas input[type="password"], +#offcanvas input[type="search"], +#offcanvas input[type="tel"], +#offcanvas input[type="text"], +#offcanvas input[type="time"], +#offcanvas input[type="url"], +#offcanvas input[type="week"], +#offcanvas input[type="range"] { + background-color: #ddd; /* darken inputs to reduce contrast on dark background */ + border: 1px solid #333; +} +/* add focus effect to fields for dark background */ +#offcanvas textarea:focus, +#offcanvas select:focus, +#offcanvas input:focus { + background-color: #fff; +} +/* reduce the size of descriptions and other elements for scanability */ +#offcanvas .description, +#offcanvas .machine-name-label, +#offcanvas .machine-name-value { + font-family: 'Lucida Grande','Lucida Sans Unicode','Liberation Sans',sans-serif; + color: #bbb; +} +/* add a background to radio buttons for contrast */ +/* +#offcanvas .radio-wrapper { + background-color: #000; +} +#offcanvas .checkbox-wrapper { + background-color: #000; +} +*/ + +/** + * Fieldsets. + */ +#offcanvas fieldset { + background-color: #333; +} + +/** + * Admin label. + */ +#offcanvas .form-item-settings-admin-label { + border-bottom-color: #777; +} +#offcanvas .form-item-settings-admin-label label { + color: #bbb; +} + +/** + * Form actions. + */ +#offcanvas .form-actions { + border-bottom-color: #777; +} + +