diff --git a/core/composer.json b/core/composer.json
index 9ac5ab0..421c222 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -112,6 +112,7 @@
"drupal/migrate_drupal_ui": "self.version",
"drupal/node": "self.version",
"drupal/options": "self.version",
+ "drupal/outside_in": "self.version",
"drupal/page_cache": "self.version",
"drupal/path": "self.version",
"drupal/quickedit": "self.version",
diff --git a/core/modules/outside_in/css/outside_in.module.css b/core/modules/outside_in/css/outside_in.module.css
new file mode 100644
index 0000000..a7fec82
--- /dev/null
+++ b/core/modules/outside_in/css/outside_in.module.css
@@ -0,0 +1,200 @@
+/**
+ * @file
+ * Styling for Outside-In module.
+ */
+
+/* Position the offcanvas tray container outside the right of the viewport. */
+#offcanvas {
+ box-sizing: border-box;
+ height: 100%;
+ overflow-y: auto;
+ z-index: 501;
+}
+
+/* Shift the main canvas to the right for right-to-left languages. */
+[dir="rtl"] #main-canvas-wrapper.js-tray-open #main-canvas {
+ right: 0;
+}
+
+/* Position the button that closes the offcanvas tray. */
+#offcanvas > button.offcanvasClose {
+ position: static;
+ float: right; /* LTR */
+ height: 52px;
+ width: 40px;
+ border: 0;
+ border-radius: 0;
+ background: url(../../../misc/icons/bebebe/ex.svg) center center no-repeat;
+ color: transparent;
+ cursor: pointer;
+ z-index: 501;
+}
+#offcanvas > button.offcanvasClose:focus {
+ outline: none;
+}
+[dir="rtl"] #offcanvas > button.offcanvasClose {
+ float: left;
+}
+
+/* Create a place to name the tray. */
+#offcanvas h1 {
+ padding: 15px 25% 15px 15px; /* LTR */
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 120%;
+}
+[dir="rtl"] #offcanvas h1 {
+ text-align: right;
+ padding-right: 0;
+ padding-left: 25%;
+}
+
+/* Wrap the form that's inside the offcanvas tray. */
+#offcanvas > .offcanvas-content {
+ height: 10000px;
+ padding: 0 15px;
+}
+[dir="rtl"] #offcanvas .offcanvas-content {
+ text-align: right;
+}
+#offcanvas > .form-item,
+#offcanvas > .form-item .form-item {
+ width: 100%;
+}
+
+/*
+ * Position the edit toolbar tab.
+ * @todo Move changes into toolbar module when outside-in is not experimental.
+ */
+.toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab {
+ float: left;
+}
+
+/* Media queries. */
+@media (max-width: 700px) {
+ #offcanvas {
+ position: absolute;
+ display: block;
+ right: 0;
+ top: 0;
+ width: 300px;
+ margin-right: -300px;
+ padding-top: 39px;
+ }
+ /* Wrap the rest of the site so we can control its width. */
+ #main-canvas-wrapper #main-canvas {
+ display: inline-block;
+ width: 100%;
+ }
+ #main-canvas-wrapper.js-tray-open #offcanvas {
+ margin-right: 0;
+ right: 0;
+ top: 0;
+ }
+ #main-canvas-wrapper.js-tray-open #main-canvas {
+ position: static;
+ width: 100%;
+ }
+}
+@media (min-width: 700px) {
+ /* Position the offcanvas tray container outside the right of the viewport. */
+ #offcanvas {
+ position: fixed;
+ display: inline-block;
+ width: 35%;
+ -webkit-transform: translateX(100%);
+ -moz-transform: translateX(100%);
+ -o-transform: translateX(100%);
+ -ms-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+ [dir="rtl"] #offcanvas {
+ text-align: right;
+ -webkit-transform: translateX(-100%);
+ -moz-transform: translateX(-100%);
+ -o-transform: translateX(-100%);
+ -ms-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+ /* Wrap the rest of the site so we can control its width. */
+ #main-canvas-wrapper #main-canvas {
+ display: inline-block;
+ width: 100%;
+ }
+ /* Move the offcanvas tray on canvas. */
+ #main-canvas-wrapper.js-tray-open #offcanvas {
+ -webkit-transform: translateX(0);
+ -moz-transform: translateX(0);
+ -o-transform: translateX(0);
+ -ms-transform: translateX(0);
+ transform: translateX(0);
+ }
+ /* Reduce the width of the main canvas to provide space for the offcanvas tray. */
+ #main-canvas-wrapper.js-tray-open #main-canvas {
+ width: 65%;
+ }
+}
+@media (min-width: 900px) {
+ /* Position the offcanvas tray container outside the right of the viewport. */
+ #offcanvas {
+ position: fixed;
+ display: inline-block;
+ width: 30%;
+ }
+ /* Wrap the rest of the site so we can control its width. */
+ #main-canvas-wrapper #main-canvas {
+ display: inline-block;
+ width: 100%;
+ }
+ /* Reduce the width of the main canvas to provide space for the offcanvas tray. */
+ #main-canvas-wrapper.js-tray-open #main-canvas {
+ width: 70%;
+ }
+}
+@media (min-width: 1000px) {
+ /* Position the offcanvas tray container outside the right of the viewport. */
+ #offcanvas {
+ position: fixed;
+ display: inline-block;
+ width: 25%;
+ }
+ /* Wrap the rest of the site so we can control its width. */
+ #main-canvas-wrapper #main-canvas {
+ display: inline-block;
+ width: 100%;
+ }
+ /* Reduce the width of the main canvas to provide space for the offcanvas tray. */
+ #main-canvas-wrapper.js-tray-open #main-canvas {
+ width: 75%;
+ }
+}
+
+/*
+ * Form layout changes, mostly specific to Bartik theme and menu.
+ * @todo Remove when more general form styling is done.
+ */
+#offcanvas td {
+ width: auto;
+}
+#offcanvas .menu-enabled {
+ width: auto;
+}
+#offcanvas table#menu-overview th {
+ display: none;
+}
+#offcanvas table#menu-overview tr td:first-child {
+ min-width: 110px;
+}
+#offcanvas details > .details-wrapper {
+ padding: 5px;
+ overflow: scroll;
+}
+#offcanvas .tabledrag-toggle-weight {
+ font-size: 80%;
+}
+#offcanvas input:focus,
+#offcanvas summary:focus {
+ outline: none;
+ box-shadow: 2px 2px #ddd;
+}
+
diff --git a/core/modules/outside_in/css/outside_in.motion.css b/core/modules/outside_in/css/outside_in.motion.css
new file mode 100644
index 0000000..f322241
--- /dev/null
+++ b/core/modules/outside_in/css/outside_in.motion.css
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * Motion effects for outside-in module.
+ *
+ * Motion effects are in a separate file so that they can be easily turned off
+ * to improve performance if desired.
+ *
+ * @todo Move motion effects file into toolbar module and add a configuration
+ * option to performance to disable this file.
+ */
+
+/* Transition the offcanvas tray container, with 2s delay to match main canvas speed. */
+#offcanvas {
+ -webkit-transition: all .7s ease 2s;
+ -moz-transition: all .7s ease 2s;
+ transition: all .7s ease 2s;
+}
+#main-canvas-wrapper #main-canvas,
+#main-canvas-wrapper.js-tray-open #main-canvas {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+}
+
+/* Transition the edit icon in the toolbar. */
+#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+}
+
+/* Transition the editables on the page, their contextual links and their hover states. */
+#main-canvas-wrapper .contextual,
+#main-canvas-wrapper .outside-in-editable,
+#main-canvas-wrapper.js-tray-open .outside-in-editable {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+}
+
+/* Transition the position of the toolbar. */
+.toolbar-fixed,
+.toolbar-tray-open {
+ -webkit-transition: all .5s ease;
+ -moz-transition: all .5s ease;
+ transition: all .5s ease;
+}
+
+@media (max-width: 700px) {
+ #offcanvas {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+ }
+ #main-canvas-wrapper.js-tray-open #offcanvas {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+ }
+}
+
+/* Transition the administration tray.
+#toolbar-administration,
+#toolbar-administration * {
+ -webkit-transition: all .7s ease;
+ -moz-transition: all .7s ease;
+ transition: all .7s ease;
+}*/
diff --git a/core/modules/outside_in/css/outside_in.theme.css b/core/modules/outside_in/css/outside_in.theme.css
new file mode 100644
index 0000000..c063115
--- /dev/null
+++ b/core/modules/outside_in/css/outside_in.theme.css
@@ -0,0 +1,104 @@
+/**
+ * @file
+ * Visual styling for Outside-In module.
+ */
+
+/* Style the edit tab in the toolbar. */
+/* @todo Move this into core when module is not experimental. */
+
+/* Style both the edit and editing states. */
+button.toolbar-icon.toolbar-icon-edit.toolbar-item {
+ background: #0e69be;
+ background-image: -webkit-linear-gradient(top, #0094f0, #0e69be);
+ background-image: linear-gradient(to bottom, #0094f0, #0e69be);
+}
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:hover,
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:focus {
+ background-image: -webkit-linear-gradient(top, #0094f0, #0e69be);
+ background-image: linear-gradient(to bottom, #0094f0, #0e69be);
+ color: #fff;
+}
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:before:hover,
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:before:focus {
+ background-image: url(../../../misc/icons/ffffff/pencil.svg);
+}
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:hover,
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:focus {
+ background-image: -webkit-linear-gradient(top, #0094f0, #0e69be);
+ background-image: linear-gradient(to bottom, #0094f0, #0e69be);
+ outline: none;
+}
+button.toolbar-icon.toolbar-icon-edit.toolbar-item:hover > .toolbar-icon-edit:before {
+ background-image: url(../../../misc/icons/ffffff/pencil.svg);
+}
+#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before {
+ background-image: url(../../../misc/icons/ffffff/pencil.svg);
+}
+
+/* Style the toolbar when in edit mode. */
+#toolbar-bar.js-outside-in-edit-mode {
+ background-color: #fff;
+}
+/* Change text color for white background. */
+#toolbar-bar.js-outside-in-edit-mode .toolbar-item {
+ color: #999;
+}
+#toolbar-bar.js-outside-in-edit-mode .toolbar-item .is-active {
+ color: #333;
+}
+/* Set color back to white for 'editing' button only. */
+#toolbar-bar.js-outside-in-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active {
+ color: #fff;
+}
+#toolbar-bar.js-outside-in-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:hover {
+ background-image: -webkit-linear-gradient(top, #0094f0, #0e69be);
+ background-image: linear-gradient(to bottom, #0094f0, #0e69be);
+}
+
+/*
+ * Style the editables while in edit mode.
+ */
+
+/* Highlight editable regions in edit mode. */
+#main-canvas.js-outside-in-edit-mode .outside-in-editable {
+ outline: 1px dashed rgba(0,0,0,0.5);
+ box-shadow: 0 0 0 1px rgba(255,255,255,0.7);
+}
+#main-canvas.js-outside-in-edit-mode .outside-in-editable:hover {
+ outline: 1px dashed rgba(0,0,0,0.5);
+ box-shadow: 0 0 0 1px rgba(255,255,255,0.7);
+ background-color: rgba(0,0,0,0.2);
+}
+/* Turn off the outlines on editables when the tray is open. */
+#main-canvas-wrapper.js-tray-open .outside-in-editable {
+ outline: transparent;
+ outline-color: transparent;
+ box-shadow: none;
+}
+#main-canvas-wrapper.js-tray-open .contextual {
+ opacity: 0;
+}
+#main-canvas-wrapper.js-tray-open .contextual:hover {
+ opacity: 1;
+}
+
+/*
+ * Style the offcanvas container.
+ */
+div#offcanvas {
+ background: #fff;
+ border-left: 1px solid #ddd; /* LTR */
+ box-shadow: -2px 2px 1px 1px rgba(0, 0, 0, 0.1); /* LTR */
+}
+[dir="rtl"] div#offcanvas {
+ border-right: 1px solid #ddd;
+ box-shadow: 2px 2px 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+/* Style the tray header. */
+#offcanvas h1 {
+ font-size: 120%;
+ border-bottom: 1px solid #ddd;
+}
+
+
diff --git a/core/modules/outside_in/js/offcanvas.js b/core/modules/outside_in/js/offcanvas.js
new file mode 100644
index 0000000..6904f3e
--- /dev/null
+++ b/core/modules/outside_in/js/offcanvas.js
@@ -0,0 +1,135 @@
+/**
+ * @file
+ * Drupal's off-canvas library.
+ */
+
+(function ($, Drupal) {
+
+ 'use strict';
+
+ /**
+ * Create a wrapper container for the off-canvas element.
+ *
+ * @param {number} pageWidth
+ * The width of #page-wrapper.
+ *
+ * @return {object}
+ * jQuery object that is the off-canvas wrapper element.
+ */
+ var createOffCanvasWrapper = function (pageWidth) {
+ return $('
', {
+ 'id': 'offcanvas',
+ 'role': 'region',
+ 'aria-labelledby': 'offcanvas-header'
+ });
+ };
+
+ /**
+ * Create the title element for the off-canvas element.
+ *
+ * @param {string} title
+ * The title string.
+ *
+ * @return {object}
+ * jQuery object that is the off-canvas title element.
+ */
+ var createTitle = function (title) {
+ return $('', {text: title, id: 'offcanvas-header'});
+ };
+
+ /**
+ * Create the actual off-canvas content.
+ *
+ * @param {string} data
+ * This is fully rendered HTML from Drupal.
+ *
+ * @return {object}
+ * jQuery object that is the off-canvas content element.
+ */
+ var createOffCanvasContent = function (data) {
+ return $('', {class: 'offcanvas-content', html: data});
+ };
+
+ /**
+ * Create the off-canvas close element.
+ *
+ * @param {object} offCanvasWrapper
+ * The jQuery off-canvas wrapper element
+ * @param {object} pageWrapper
+ * The jQuery off page wrapper element
+ *
+ * @return {jQuery}
+ * jQuery object that is the off-canvas close element.
+ */
+ var createOffCanvasClose = function (offCanvasWrapper, pageWrapper) {
+ return $('', {
+ 'class': 'offcanvasClose',
+ 'aria-label': Drupal.t('Close configuration tray.'),
+ 'html': '' + Drupal.t('Close') + ''
+ }).on('click', function () {
+ pageWrapper
+ .removeClass('js-tray-open')
+ .one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () {
+ Drupal.offCanvas.visible = false;
+ offCanvasWrapper.remove();
+ Drupal.announce(Drupal.t('Configuration tray closed.'));
+ }
+ );
+ });
+ };
+
+
+ /**
+ * Command to open an off-canvas element.
+ *
+ * @param {Drupal.Ajax} ajax
+ * The Drupal Ajax object.
+ * @param {object} response
+ * Object holding the server response.
+ *
+ * @param {number} [status]
+ * The HTTP status code.
+ */
+ Drupal.AjaxCommands.prototype.openOffCanvas = function (ajax, response, status) {
+ // Discover display/viewport size.
+ // @todo Work in breakpoints for tray size.
+ var $pageWrapper = $('#main-canvas-wrapper');
+ var pageWidth = $pageWrapper.width();
+
+ // Set the initial state of the off-canvas element.
+ // If the state has been set previously, use it.
+ Drupal.offCanvas = {
+ visible: (Drupal.offCanvas ? Drupal.offCanvas.visible : false)
+ };
+
+ // Construct off-canvas wrapper
+ var $offcanvasWrapper = createOffCanvasWrapper(pageWidth);
+
+ // Construct off-canvas internal elements.
+ var $offcanvasClose = createOffCanvasClose($offcanvasWrapper, $pageWrapper);
+ var $title = createTitle(response.dialogOptions.title);
+ var $offcanvasContent = createOffCanvasContent(response.data);
+
+ // Put everything together.
+ $offcanvasWrapper.append([$offcanvasClose, $title, $offcanvasContent]);
+
+ // Handle opening or updating tray with content.
+ var existingTray = false;
+ if (Drupal.offCanvas.visible) {
+ // Remove previous content then append new content.
+ $pageWrapper.find('#offcanvas').remove();
+ existingTray = true;
+ }
+ $pageWrapper.addClass('js-tray-open');
+ Drupal.offCanvas.visible = true;
+ $pageWrapper.append($offcanvasWrapper);
+ if (existingTray) {
+ Drupal.announce(Drupal.t('Configuration tray content has been updated.'));
+ }
+ else {
+ Drupal.announce(Drupal.t('Configuration tray opened.'));
+ }
+ Drupal.attachBehaviors(document.querySelector('#offcanvas'), drupalSettings);
+ };
+
+})(jQuery, Drupal);
diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js
new file mode 100644
index 0000000..2d6fed7
--- /dev/null
+++ b/core/modules/outside_in/js/outside_in.js
@@ -0,0 +1,139 @@
+/**
+ * @file
+ * Drupal's Outside-In library.
+ */
+
+(function ($, Drupal) {
+
+ 'use strict';
+
+ // Bind a listener to the 'edit' button
+ // Toggle the js-outside-edit-mode class on items that we want
+ // to disable while in edit mode.
+ $('.contextual-toolbar-tab.toolbar-tab button').on('click', function () {
+ setToggleActiveMode();
+ });
+
+ $('.outside-in-editable')
+ // Bind an event listener to the .outside-in-editable div
+ // This listen for click events and stops default actions of those elements.
+ .on('click', '.js-outside-in-edit-mode', function (e) {
+ if (localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false') {
+ e.preventDefault();
+ }
+ })
+ // Bind an event listener to the .outside-in-editable div
+ // When a click occurs try and find the outside-in edit link
+ // and click it.
+ .not('div.contextual a, div.contextual button')
+ .on('click', function (e) {
+ if ($(e.target.offsetParent).hasClass('contextual')) {
+ return;
+ }
+ if (!localStorage.getItem('Drupal.contextualToolbar.isViewing')) {
+ return;
+ }
+ var editLink = $(e.target).find('li.outside-inblock-configure a')[0];
+ if (!editLink) {
+ var parents = $(e.target).parents('.outside-in-editable');
+ editLink = parents.find('li.outside-inblock-configure a')[0];
+ }
+ editLink.click();
+ });
+
+ /**
+ * Add Ajax behaviours to links added by contextual links
+ *
+ * @todo Fix contextual links to work with use-ajax links in
+ * https://www.drupal.org/node/2764931.
+ *
+ * @param {jQuery.Event} event
+ * The `drupalContextualLinkAdded` event.
+ * @param {object} data
+ * An object containing the data relevant to the event.
+ *
+ * @listens event:drupalContextualLinkAdded
+ */
+ $(document).on('drupalContextualLinkAdded', function (event, data) {
+ // Bind Ajax behaviors to all items showing the class.
+ data.$el.find('.use-ajax').once('ajax').each(function () {
+ // Below is copied directly from ajax.js to keep behavior the same.
+ var element_settings = {};
+ // Clicked links look better with the throbber than the progress bar.
+ element_settings.progress = {type: 'throbber'};
+
+ // For anchor tags, these will go to the target of the anchor rather
+ // than the usual location.
+ var href = $(this).attr('href');
+ if (href) {
+ element_settings.url = href;
+ element_settings.event = 'click';
+ }
+ element_settings.dialogType = $(this).data('dialog-type');
+ element_settings.dialog = $(this).data('dialog-options');
+ element_settings.base = $(this).attr('id');
+ element_settings.element = this;
+ Drupal.ajax(element_settings);
+ });
+
+ // Bind a listener to all 'Quick Edit' links for blocks
+ // Click "Edit" button in toolbar to force Contextual Edit which starts
+ // Outside-In edit mode also.
+ data.$el.find('.outside-inblock-configure a').on('click', function () {
+ if (!isActiveMode()) {
+ $('div.contextual-toolbar-tab.toolbar-tab button').click();
+ }
+ });
+ });
+
+ /**
+ * Gets all items that should be toggled with class during edit mode.
+ *
+ * @return {*}
+ * Items that should be toggled.
+ */
+ var getItemsToToggle = function () {
+ return $('#main-canvas, #toolbar-bar, .outside-in-editable a, .outside-in-editable button')
+ .not('div.contextual a, div.contextual button');
+ };
+
+ var isActiveMode = function () {
+ return $('#toolbar-bar').hasClass('js-outside-in-edit-mode');
+ };
+
+ var setToggleActiveMode = function (forceActive) {
+ forceActive = forceActive || false;
+ if (forceActive || !isActiveMode()) {
+ $('#toolbar-bar .contextual-toolbar-tab button').text(Drupal.t('Editing'));
+ // Close the Manage tray if open when entering edit mode.
+ if ($('#toolbar-item-administration-tray').hasClass('is-active')) {
+ $('#toolbar-item-administration').click();
+ }
+ getItemsToToggle().addClass('js-outside-in-edit-mode');
+ $('.edit-mode-inactive').addClass('visually-hidden');
+ }
+ else {
+ $('#toolbar-bar .contextual-toolbar-tab button').text(Drupal.t('Edit'));
+ getItemsToToggle().removeClass('js-outside-in-edit-mode');
+ $('.edit-mode-inactive').removeClass('visually-hidden');
+ }
+ };
+
+ /**
+ * Attaches contextual's edit toolbar tab behavior.
+ *
+ * @type {Drupal~behavior}
+ *
+ * @prop {Drupal~behaviorAttach} attach
+ * Attaches contextual toolbar behavior on a contextualToolbar-init event.
+ */
+ Drupal.behaviors.outsideinedit = {
+ attach: function () {
+ var editMode = localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false';
+ if (editMode) {
+ setToggleActiveMode(true);
+ }
+ }
+ };
+
+})(jQuery, Drupal);
diff --git a/core/modules/outside_in/outside_in.info.yml b/core/modules/outside_in/outside_in.info.yml
new file mode 100644
index 0000000..83f45e5
--- /dev/null
+++ b/core/modules/outside_in/outside_in.info.yml
@@ -0,0 +1,10 @@
+name: 'Outside-In'
+type: module
+description: 'Provides the ability to access useful configuration from the Drupal front-end.'
+package: Core (Experimental)
+version: VERSION
+core: 8.x
+dependencies:
+ - block
+ - toolbar
+ - contextual
diff --git a/core/modules/outside_in/outside_in.libraries.yml b/core/modules/outside_in/outside_in.libraries.yml
new file mode 100644
index 0000000..8787d77
--- /dev/null
+++ b/core/modules/outside_in/outside_in.libraries.yml
@@ -0,0 +1,23 @@
+drupal.outside_in:
+ version: VERSION
+ js:
+ js/outside_in.js: {}
+ css:
+ component:
+ css/outside_in.module.css: {}
+ css/outside_in.theme.css: {}
+ css/outside_in.motion.css: {}
+ dependencies:
+ - core/jquery
+ - core/drupal
+drupal.off_canvas:
+ version: VERSION
+ js:
+ js/offcanvas.js: {}
+ dependencies:
+ - core/jquery
+ - core/drupal
+ - core/drupal.ajax
+ - core/drupal.announce
+ - core/drupal.dialog
+ - core/drupal.dialog.ajax
diff --git a/core/modules/outside_in/outside_in.links.contextual.yml b/core/modules/outside_in/outside_in.links.contextual.yml
new file mode 100644
index 0000000..05455f3
--- /dev/null
+++ b/core/modules/outside_in/outside_in.links.contextual.yml
@@ -0,0 +1,4 @@
+outside_in.block_configure:
+ title: 'Quick Edit'
+ route_name: 'entity.block.offcanvas_form'
+ group: 'block'
diff --git a/core/modules/outside_in/outside_in.module b/core/modules/outside_in/outside_in.module
new file mode 100644
index 0000000..83c68b6
--- /dev/null
+++ b/core/modules/outside_in/outside_in.module
@@ -0,0 +1,138 @@
+' . t('About') . '';
+ // @todo Update help text.
+ $output .= '
' . t('The Outside-In module is something that we should have help for. For more information, see the online documentation for the Outside-In module.', [':outside-in-documentation' => 'https://www.drupal.org/documentation/modules/outside_in']) . '