From f24ca6ef754e97016f43f35d6747db5dbc884fc1 Mon Sep 17 00:00:00 2001 From: Alin Istrate Date: Fri, 22 May 2020 08:41:19 +0300 Subject: [PATCH] Adding site_id to the initial install migration --- CHANGELOG.md | 5 + composer.json | 2 +- src/migrations/Install.php | 1 + src/src/Olivemenus.php | 142 +++ .../olivemenus/OlivemenuItemsAsset.php | 68 ++ .../olivemenus/OlivemenusAsset.php | 61 ++ .../olivemenus/dist/css/MenuItems.css | 293 ++++++ .../olivemenus/dist/img/Index-icon.svg | 56 ++ .../assetbundles/olivemenus/dist/js/Index.js | 52 + .../olivemenus/dist/js/MenuItem.js | 324 +++++++ .../olivemenus/dist/js/jquery-ui.js | 7 + .../dist/js/jquery.filterList.min.js | 47 + .../dist/js/jquery.mjs.nestedSortable.js | 912 ++++++++++++++++++ src/src/controllers/MenuController.php | 208 ++++ src/src/controllers/MenuItemsController.php | 149 +++ src/src/icon-mask.svg | 12 + src/src/icon.svg | 13 + src/src/migrations/Install.php | 198 ++++ ...9_olivemenus_addFieldToMenusItemsTable.php | 33 + ..._olivemenus_addSiteIdFieldToMenusTable.php | 31 + ...livemenus_fixBrokenMultisiteMigrations.php | 29 + 21 files changed, 2642 insertions(+), 1 deletion(-) create mode 100644 src/src/Olivemenus.php create mode 100644 src/src/assetbundles/olivemenus/OlivemenuItemsAsset.php create mode 100644 src/src/assetbundles/olivemenus/OlivemenusAsset.php create mode 100644 src/src/assetbundles/olivemenus/dist/css/MenuItems.css create mode 100644 src/src/assetbundles/olivemenus/dist/img/Index-icon.svg create mode 100644 src/src/assetbundles/olivemenus/dist/js/Index.js create mode 100644 src/src/assetbundles/olivemenus/dist/js/MenuItem.js create mode 100644 src/src/assetbundles/olivemenus/dist/js/jquery-ui.js create mode 100644 src/src/assetbundles/olivemenus/dist/js/jquery.filterList.min.js create mode 100644 src/src/assetbundles/olivemenus/dist/js/jquery.mjs.nestedSortable.js create mode 100644 src/src/controllers/MenuController.php create mode 100644 src/src/controllers/MenuItemsController.php create mode 100644 src/src/icon-mask.svg create mode 100644 src/src/icon.svg create mode 100644 src/src/migrations/Install.php create mode 100644 src/src/migrations/m200212_124859_olivemenus_addFieldToMenusItemsTable.php create mode 100644 src/src/migrations/m200228_124859_olivemenus_addSiteIdFieldToMenusTable.php create mode 100644 src/src/migrations/m200515_124130_olivemenus_fixBrokenMultisiteMigrations.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 391ffaf..364c422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,3 +70,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## 1.2.0 - 2020-05-18 ### Added - extra config options for HTML output: without-container and without-ul + +## 1.2.1 - 2020-05-20 +### Fixed +- Added "site_id" to the install migration + diff --git a/composer.json b/composer.json index aaeaa4f..6d54c91 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "olivestudio/craft-olivemenus", "description": "A powerful menus plugin for Craft 3 built for the need of simplicity and flexibility", "type": "craft-plugin", - "version": "1.2.0", + "version": "1.2.1", "keywords": [ "craft", "cms", diff --git a/src/migrations/Install.php b/src/migrations/Install.php index ac480bd..3300655 100644 --- a/src/migrations/Install.php +++ b/src/migrations/Install.php @@ -87,6 +87,7 @@ protected function createTables() 'id' => $this->primaryKey(), 'name' => $this->string(255)->notNull()->defaultValue(''), 'handle' => $this->string(255)->notNull()->defaultValue(''), + 'site_id' => $this->integer(11), 'dateCreated' => $this->dateTime()->notNull(), 'dateUpdated' => $this->dateTime()->notNull(), 'uid' => $this->uid(), diff --git a/src/src/Olivemenus.php b/src/src/Olivemenus.php new file mode 100644 index 0000000..748d321 --- /dev/null +++ b/src/src/Olivemenus.php @@ -0,0 +1,142 @@ +setComponents([ + 'olivemenus' => services\OlivemenusService::class, + 'olivemenuItems' => services\OlivemenuItemsService::class, + ]); + self::$plugin = $this; + + // Register our CP routes + Event::on( + UrlManager::class, + UrlManager::EVENT_REGISTER_CP_URL_RULES, + function (RegisterUrlRulesEvent $event) { + $event->rules['olivemenus'] = 'olivemenus/menu'; + $event->rules['olivemenus/'] = 'olivemenus/menu'; + $event->rules['olivemenus/menu-new/'] = 'olivemenus/menu/menu-new'; + $event->rules['olivemenus/delete-menu'] = 'olivemenus/menu/delete-menu'; + $event->rules['olivemenus/delete-menu/'] = 'olivemenus/menu/delete-menu'; + $event->rules['olivemenus/menu-edit/'] = 'olivemenus/menu/menu-edit'; + $event->rules['olivemenus/menu-edit/'] = 'olivemenus/menu'; + $event->rules['olivemenus/menu-items/'] = 'olivemenus/menu-items/edit'; + } + ); + + // Register our variables + Event::on( + CraftVariable::class, + CraftVariable::EVENT_INIT, + function (Event $event) { + /** @var CraftVariable $variable */ + $variable = $event->sender; + $variable->set('olivemenus', variables\OlivemenusVariable::class); + } + ); + +/** + * Logging in Craft involves using one of the following methods: + * + * Craft::trace(): record a message to trace how a piece of code runs. This is mainly for development use. + * Craft::info(): record a message that conveys some useful information. + * Craft::warning(): record a warning message that indicates something unexpected has happened. + * Craft::error(): record a fatal error that should be investigated as soon as possible. + * + * Unless `devMode` is on, only Craft::warning() & Craft::error() will log to `craft/storage/logs/web.log` + * + * It's recommended that you pass in the magic constant `__METHOD__` as the second parameter, which sets + * the category to the method (prefixed with the fully qualified class name) where the constant appears. + * + * To enable the Yii debug toolbar, go to your user account in the AdminCP and check the + * [] Show the debug toolbar on the front end & [] Show the debug toolbar on the Control Panel + * + * http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html + */ + Craft::info( + Craft::t( + 'olivemenus', + '{name} plugin loaded', + ['name' => $this->name] + ), + __METHOD__ + ); + } +} diff --git a/src/src/assetbundles/olivemenus/OlivemenuItemsAsset.php b/src/src/assetbundles/olivemenus/OlivemenuItemsAsset.php new file mode 100644 index 0000000..75ba32c --- /dev/null +++ b/src/src/assetbundles/olivemenus/OlivemenuItemsAsset.php @@ -0,0 +1,68 @@ +sourcePath = "@olivestudio/olivemenus/assetbundles/olivemenus/dist"; + + // define the dependencies + $this->depends = [ + CpAsset::class, + ]; + + // define the relative path to CSS/JS files that should be registered with the page + // when this asset bundle is registered + $this->js = [ + 'js/jquery-ui.js', + 'js/jquery.filterList.min.js', + 'js/jquery.mjs.nestedSortable.js', + 'js/MenuItem.js', + ]; + + $this->css = [ + 'css/MenuItems.css', + ]; + + parent::init(); + } +} diff --git a/src/src/assetbundles/olivemenus/OlivemenusAsset.php b/src/src/assetbundles/olivemenus/OlivemenusAsset.php new file mode 100644 index 0000000..2907a53 --- /dev/null +++ b/src/src/assetbundles/olivemenus/OlivemenusAsset.php @@ -0,0 +1,61 @@ +sourcePath = "@olivestudio/olivemenus/assetbundles/olivemenus/dist"; + + // define the dependencies + $this->depends = [ + CpAsset::class, + ]; + + // define the relative path to CSS/JS files that should be registered with the page + // when this asset bundle is registered + $this->js = [ + 'js/Index.js', + ]; + + parent::init(); + } +} diff --git a/src/src/assetbundles/olivemenus/dist/css/MenuItems.css b/src/src/assetbundles/olivemenus/dist/css/MenuItems.css new file mode 100644 index 0000000..8e43d49 --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/css/MenuItems.css @@ -0,0 +1,293 @@ +/** + * Olivemenus plugin for Craft CMS + * + * MenuItems Field CSS + * + * @author Olivestudio + * @copyright Copyright (c) 2018 Olivestudio + * @link http://www.olivestudio.net/ + * @package Olivemenus + * @since 1.0.0 + */ + + #menu-items-sidebar { + width:24%; + float:left; +} +#menu-items-sidebar > .os-accordion { + border-bottom:1px solid #e3e5e8; +} +#menu-items-sidebar .ui-tabs-panel form > .field, +#menu-items-sidebar .ui-tabs-panel form > .fields, +#menu-items-sidebar .fields-custom { + margin-bottom:20px; +} +#menu-items-sidebar .field.checkboxfield { + margin:0 0 8px 0; +} +#menu-items-sidebar .field.checkboxfield label { + display:block; +} +#menu-items-sidebar .accordion .ui-accordion-header { + border:1px solid #e3e5e8; + height:20px; + line-height:20px; + padding:10px 10px 10px 14px; + cursor:pointer; + background:#fafafa; + color: #29323d; + position:relative; + color:#555; + margin:0; + border-bottom:0; +} +#menu-items-sidebar .accordion .ui-accordion-header:last-child { +} +#menu-items-sidebar .accordion .ui-accordion-header:after { + content: "▼"; + font-family: "Craft"; + height:40px; + width:40px; + text-align:center; + position:absolute; + top:0; + right:0; + line-height:40px; + font-size:20px; + color:#29323d; +} +#menu-items-sidebar .accordion .ui-accordion-header:hover, +#menu-items-sidebar .accordion .ui-accordion-header.ui-state-active { + background:#737f8c; + border-color:#737f8c; + color:#fff; + outline:none; +} +#menu-items-sidebar .accordion .ui-accordion-header:hover:after, +#menu-items-sidebar .accordion .ui-accordion-header.ui-state-active:after { + color:#fff; +} +#menu-items-sidebar .accordion .ui-accordion-header.ui-state-active:after { + transform:rotate(180deg); +} +#menu-items-sidebar .accordion .ui-accordion-content { + border:1px solid #e3e5e8; + border-top:none; + border-bottom:0; + padding:15px 14px 14px 14px; +} +#menu-items-sidebar .accordion .ui-accordion-content:last-child { + border-top:1px solid #e3e5e8; +} +#menu-items-sidebar .accordion .accordion { + margin-bottom:20px; +} +#menu-items-sidebar .accordion .accordion .ui-accordion-header { + border:none; + padding:5px 0 5px 0; + font-size:13px; + border-bottom:1px solid #e3e5e8; + background:none; + color:#29323d; +} +#menu-items-sidebar .accordion .accordion .ui-accordion-header:hover, +#menu-items-sidebar .accordion .accordion .ui-accordion-header.ui-state-active { + border-bottom:1px solid #29323d; +} +#menu-items-sidebar .accordion .accordion .ui-accordion-header:after { + width:30px; + height:30px; + line-height:30px; + font-size:14px; + color:#29323d; +} +#menu-items-sidebar .accordion .accordion .ui-accordion-content { + padding:14px 0; + border:none; +} +#menu-items-sidebar .accordion .accordion .ui-accordion-content .ui-tabs { + margin-bottom:0; +} +#menu-items-sidebar .ui-tabs .ui-tabs-nav { + border-bottom:1px solid #e3e5e8; + padding-bottom:10px; + margin-bottom:10px; + overflow:hidden; +} +#menu-items-sidebar .ui-tabs .ui-tabs-nav li { + float:left; + margin-right:10px; +} +#menu-items-sidebar .ui-tabs .ui-tabs-nav li a { + color:#555; +} +#menu-items-sidebar .ui-tabs .ui-tabs-nav li:hover a, +#menu-items-sidebar .ui-tabs .ui-tabs-nav li.ui-state-active a { + color:#da5a47; + text-decoration:none; +} +#menu-items-sidebar .search-list { + margin-bottom:20px; +} +#menu-items-sidebar .search-list.active { + padding-top:20px; +} +#menu-items-sidebar .search-list li { + display:none; +} +#menu-items-sidebar .templating { + margin-top:20px; +} +#menu-items-sidebar .templating .heading { + padding:10px 10px 10px 14px; + background:#737f8c; + color:#fff; +} +#menu-items-sidebar .templating .content { + padding:10px; + background:#fafafa; + border:1px solid #e3e5e8; + border-top:none; +} +#menu-items-sidebar .templating .content pre { + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + padding:10px; + background:#f2f2f2; + border:1px solid #eaeaea; +} +#menu-items-sidebar .btn:hover, +#menu-items-sidebar .btn:focus, +#menu-items-sidebar .btn:active, +#menu-items .btn:hover, +#menu-items .btn:focus, +#menu-items .btn:active { + background:#737f8c; + color:#fff !important; +} +#menu-items { + box-sizing:border-box; + width:76%; + float:left; + padding-left:40px; +} +#menu-items .sortable { + padding-left:0; + list-style:none; +} +#menu-items .sortable li { + width:380px; + margin-bottom:14px; +} +#menu-items .sortable li.ui-sortable-helper { + margin-top:14px; +} +#menu-items .sortable ol { + list-style:none; + padding-left:20px; + border-left:1px dotted #cacaca; +} +#menu-items .sortable li > .ui-sortable-handle { + margin-bottom:14px; +} +#menu-items .sortable li .item-heading { + border:1px solid #e3e5e8; + height:20px; + line-height:20px; + padding:10px 10px 10px 14px; + background:#fafafa; + color: #29323d; + position:relative; + color:#555; + font-size:13px; + font-weight:700; + margin:0; + cursor:move; +} +#menu-items .sortable li > .ui-sortable-handle:hover > .item-heading, +#menu-items .sortable li.active > .ui-sortable-handle > .item-heading { + background:#737f8c; + border-color:#737f8c; + color:#fff; +} +#menu-items .sortable li .item-heading .menu-title { + position:relative; + padding-left:30px; + display:inline-block; + max-width:70%; + height:20px; + overflow:hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +#menu-items .sortable li .item-heading .settings-toggle { + width:30px; + height:40px; + position:absolute; + top:0; + left:0; + display:block; + cursor:pointer; + z-index:10; +} +#menu-items .sortable li .item-heading .settings-toggle:before { + content: "▼"; + font-family: "Craft"; + height:40px; + width:40px; + text-align:center; + position:absolute; + top:0; + left:0; + line-height:40px; + font-size:20px; + color:#29323d; +} +#menu-items .sortable li.active > .ui-sortable-handle > .item-heading .settings-toggle:before { + transform:rotate(180deg); +} +#menu-items .sortable li > .ui-sortable-handle:hover > .item-heading .settings-toggle:before, +#menu-items .sortable li.active > .ui-sortable-handle > .item-heading .settings-toggle:before { + color:#fff; +} +#menu-items .sortable li .item-heading .delete-menu { + position:absolute; + top:10px; + right:10px; + z-index:20px; + text-align:right; + font-size:11px; + font-weight:400; + color:#29323d; +} +#menu-items .sortable li .item-content { + max-height:0; + transition:200ms linear all; + overflow:hidden; +} +#menu-items .sortable li.active > .ui-sortable-handle > .item-content { + max-height:500px; +} +#menu-items .sortable li .item-content .inner { + padding:10px; + border:1px solid #e3e5e8; + border-top:none; +} +#menu-items .sortable li .item-content .inner .field:last-child { + margin-bottom:0; +} +#menu-items .sortable li .item-content .inner a { + color:#b9bfc6; + text-decoration:underline; +} +#menu-items .sortable .placeholder { + background:#fafafa; + border:1px solid #eaeaea; +} + +.d-flex { + display: flex; +} \ No newline at end of file diff --git a/src/src/assetbundles/olivemenus/dist/img/Index-icon.svg b/src/src/assetbundles/olivemenus/dist/img/Index-icon.svg new file mode 100644 index 0000000..a5d6ae7 --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/img/Index-icon.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/src/assetbundles/olivemenus/dist/js/Index.js b/src/src/assetbundles/olivemenus/dist/js/Index.js new file mode 100644 index 0000000..486250b --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/js/Index.js @@ -0,0 +1,52 @@ +/** + * Olivemenus plugin for Craft CMS + * + * Index Field JS + * + * @author Olivestudio + * @copyright Copyright (c) 2018 Olivestudio + * @link http://www.olivestudio.net/ + * @package Olivemenus + * @since 1.0.0 + */ + +$(document).ready(function() { +var menuList = $('#menu-list'), + menuListItemsCount = menuList.find('tbody tr').length; + + $('#menu-list .delete').each(function(){ + + var menu = $(this), + menuParent = menu.parent().parent(), + menuID = menuParent.attr('data-id'), + menuName = menuParent.attr('data-name'); + + $(this).on('click',function() { + if (confirm(Craft.t('olivemenus', 'Are you sure you want to delete the "{menuName}" menu?', {menuName: menuName }))) { + var data = { + menuID: menuID + } + // Add the CSRF Token + data[csrfTokenName] = csrfTokenValue; + + $.post(siteUrl +'/olivemenus/delete-menu', data, null, 'json') + .done(function( data ) { + if (data.success) { + Craft.cp.displayNotice(Craft.t('olivemenus', 'Menu successfully deleted.')); + menuParent.remove(); + + var menuListItems = menuList.find('tbody tr'), + menuListItemsCount = menuListItems.length; + + if ( menuListItemsCount == 0 ) + { + menuList.remove(); + $('#menu-none').removeClass('hidden'); + } + } + else Craft.cp.displayError(Craft.t('olivemenus','Menu was not deleted. Please try again.')); + }); + } + }); + }); +}); \ No newline at end of file diff --git a/src/src/assetbundles/olivemenus/dist/js/MenuItem.js b/src/src/assetbundles/olivemenus/dist/js/MenuItem.js new file mode 100644 index 0000000..97b2a2c --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/js/MenuItem.js @@ -0,0 +1,324 @@ +$(document).ready(function() { + $('.os-accordion').accordion({ + heightStyle: "content", + collapsible: true, + active: false + }); + + $('.os-tabs').tabs(); + + $('.search').filterList(); + + var menuList = $('ol#menu-list'), + menuListConfig = { + handle: 'div', + items: 'li', + toleranceElement: '> div', + isTree: true, + forcePlaceholderSize: true, + placeholder: 'placeholder' + }; + + menuList.nestedSortable(menuListConfig); + + var deletedMenuItems = $('#menu-items-deleted'); + + menuList.on('click', '.delete-menu', function() { + if (confirm(Craft.t('olivemenus','Are you sure you want to delete this menu item?'))) { + var element = $(this), + targetToDeleteID = element.attr('data-id'), + targetToDelete = $('#menu-item-' + targetToDeleteID); + targetChildren = targetToDelete.find('ol'); + deletedMenuItemsValue = deletedMenuItems.val(); + + if ( deletedMenuItemsValue == '' ) deletedMenuItemsValue = []; + else deletedMenuItemsValue = deletedMenuItemsValue.split(',') + + deletedMenuItemsValue.push(targetToDeleteID); + deletedMenuItems.val(deletedMenuItemsValue.toString()); + + if (targetChildren.length) { + var childrenHTML = targetChildren.html(); + targetChildren.remove(); + targetToDelete.before($(childrenHTML)); + } + + targetToDelete.remove(); + + if ( menuList.find('li').length == 0 ) $('#menu-list-placeholder').show(); + } + }); + + menuList.on('click', '.settings-toggle', function(){ + if ( !$(this).hasClass('ui-sortable-helper') ) $(this).closest('li').toggleClass('active'); + }); + + var inputCounter; + if ( $('#menu-list li').length == 0 ) inputCounter = 1; + else { + var biggestID = 0; + $('#menu-list li').each(function(){ + var elementID = $(this).attr('id'), + elementIDNumber = parseInt(elementID.replace('menu-item-', '')); + + if ( elementIDNumber > biggestID ) biggestID = elementIDNumber; + }); + + inputCounter = biggestID + 1; + } + + $('#menu-items-sidebar form').each(function(){ + var form = $(this); + + form.submit(function(e) { + e.preventDefault(); + + $('#menu-list-placeholder').hide(); + + var inputs = form.find('input[type="checkbox"]'), + values = []; + + inputs.each(function(){ + var input = $(this); + + if (input.is(':checked')) { + var itemID = input.val(), + itemURL = input.attr('data-url'), + itemName = input.next().text(), + itemHTML = ''; + + itemHTML += ''; + + inputCounter++; + menuList.append(itemHTML); + } + }); + + //reset checkes + inputs.prop('checked', false); + + if (form.hasClass('custom-url')) { + var customMenuTitle = $('#custom-menu-title'), + customMenuTitleVal = customMenuTitle.val(), + customMenuURL = $('#custom-menu-url'), + customMenuURLVal = customMenuURL.val(), + itemHTML = ''; + + customMenuTitle.removeClass('error'); + customMenuURL.removeClass('error'); + + if (customMenuTitleVal == '') { + if (customMenuTitleVal == '') customMenuTitle.addClass('error'); + } else { + itemHTML += ''; + + inputCounter++; + menuList.append(itemHTML); + } + } + }); + }); + + //main form submit + var mainForm = $('#menu-items form'); + mainForm.submit(function(e) { + e.preventDefault(); + + var menuListProcessed = [], + menuListToArray = menuList.nestedSortable('toArray', {startDepthCount: 0}); + + if ($.isArray(menuListToArray)) { + for (var index in menuListToArray) { + var menuItem = menuListToArray[index]; + if (typeof menuItem.id !== 'undefined') { + var menuItemEntryIDValue = '', + menuItemCustomURLValue= ''; + + var menuItemParentID = (typeof menuItem.parent_id !== null ) ? menuItem.parent_id : 0, + menuItemElement = $('#menu-item-' + menuItem.id + ' > div'), + menuItemID = menuItemElement.find('input[name="item-id"]'), + menuItemNameElement = menuItemElement.find('input[name="item-name"]'), + menuItemNameValue = menuItemNameElement.val(), + + menuItemEntryIDElement = menuItemElement.find('input[name="item-entry-id"]'), + menuItemCustomURLElement = menuItemElement.find('input[name="custom-url"]'), + + menuItemClassElement = menuItemElement.find('input[name="class"]'), + menuItemClassValue = menuItemClassElement.val(), + menuItemClassParentElement = menuItemElement.find('input[name="class-parent"]'), + menuItemClassParentValue = menuItemClassParentElement.val(), + menuItemDataElement = menuItemElement.find('textarea[name="data-json"]'), + menuItemDataValue = menuItemDataElement.val(); + + if (menuItemID.length == 0) { + menuItemID = null; + } else { + menuItemID = menuItemID.val(); + } + + if (menuItemCustomURLElement.length) { + menuItemCustomURLValue = menuItemCustomURLElement.val(); + } else { + menuItemEntryIDValue = menuItemEntryIDElement.val(); + } + + var menuItemData = { + 'item-id' : { + db:menuItemID, + html:menuItem.id + }, + 'parent-id' : menuItemParentID, + 'name' : menuItemNameValue, + 'entry-id' : menuItemEntryIDValue, + 'custom-url' : menuItemCustomURLValue, + 'class' : menuItemClassValue, + 'class-parent' : menuItemClassParentValue, + 'data-json' : menuItemDataValue, + 'target' : $('#target-' + menuItem.id + ' :selected').val() + }; + + menuListProcessed.push(menuItemData); + } + } + + $('#menu-items-serialized').val(JSON.stringify(menuListProcessed)); + this.submit(); + } + }); + + //delete menu from menu items list + $('#delete-menu-with-items').on('click', function(e){ + e.preventDefault(); + }); +}); +function confirm_delete() { + return confirm(Craft.t('olivemenus', "Are you sure you want to delete the menu and all it's items?")); +} \ No newline at end of file diff --git a/src/src/assetbundles/olivemenus/dist/js/jquery-ui.js b/src/src/assetbundles/olivemenus/dist/js/jquery-ui.js new file mode 100644 index 0000000..2907e45 --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/js/jquery-ui.js @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.12.1 - 2017-01-11 +* http://jqueryui.com +* Includes: widget.js, data.js, keycode.js, scroll-parent.js, unique-id.js, widgets/sortable.js, widgets/accordion.js, widgets/mouse.js, widgets/tabs.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,l=r+t.height,h=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+h>r&&l>s+h,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&l>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],l=[],h=this._connectWith();if(h&&e)for(s=h.length-1;s>=0;s--)for(o=t(h[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&l.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(l.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=l.length-1;s>=0;s--)l[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,l,h,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,h=r.length;h>s;s++)l=t(r[s]),l.data(this.widgetName+"-item",a),c.push({item:l,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t(" ",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,l,h,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(l=this.items[s].item.offset()[a],h=!1,e[u]-l>this.items[s][r]/2&&(h=!0),n>Math.abs(e[u]-l)&&(n=Math.abs(e[u]-l),o=this.items[s],this.direction=h?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName); +return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():l?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():l?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t(""),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],l=r&&n.collapsible,h=l?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:l?t():a,newPanel:h};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=l?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,l=t.css("box-sizing"),h=t.length&&(!e.length||t.index()?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),l=t(s).closest("li"),h=l.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=l.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),h&&l.data("ui-tabs-aria-controls",h),l.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("
").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,l=r?t():this._getPanelForTab(o),h=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:h,newTab:r?t():o,newPanel:l};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),h.length||l.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),l.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},l=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),l(n,e)},1)}).fail(function(t,e){setTimeout(function(){l(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs}); \ No newline at end of file diff --git a/src/src/assetbundles/olivemenus/dist/js/jquery.filterList.min.js b/src/src/assetbundles/olivemenus/dist/js/jquery.filterList.min.js new file mode 100644 index 0000000..5f55dc1 --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/js/jquery.filterList.min.js @@ -0,0 +1,47 @@ +// jquery.filterList.js +// +// Uses an input box to filter an unordered list in real-time. +// +// Useage +// +// REQUIRED HTML: +// +//
+// +//
    +//
  • Item A
  • +//
  • Item B
  • +//
  • Item C
  • +//
+//
+// +// REQUIRED JAVASCRIPT: +// +// $('#filter').filterList(); + +(function($) { + $.fn.filterList = function(ul) { + // Case-insensitive "contains" + $.expr[':'].Contains = function(a, i, m) { + return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0; + }; + + // Hide list items that do not contain filter term/show ones that do + $(this).keyup(function() { + var ulTarget = ul !== undefined ? $(ul) : $(this).next("ul"); + var filterListTerm = $(this).val(); + if (filterListTerm) { + ulTarget.addClass('active'); + ulTarget.find("li:not(:Contains(" + filterListTerm + "))").css('display', 'none'); + ulTarget.find("li:Contains(" + filterListTerm + ")").css('display', 'block'); + } else { + ulTarget.removeClass('active'); + ulTarget.children('li').css('display', 'none');; + } + return false; + }); + + return this; + + }; +})(jQuery); diff --git a/src/src/assetbundles/olivemenus/dist/js/jquery.mjs.nestedSortable.js b/src/src/assetbundles/olivemenus/dist/js/jquery.mjs.nestedSortable.js new file mode 100644 index 0000000..d7388aa --- /dev/null +++ b/src/src/assetbundles/olivemenus/dist/js/jquery.mjs.nestedSortable.js @@ -0,0 +1,912 @@ +/* + * jQuery UI Nested Sortable + * v 2.0b1 / 2016-02-04 + * https://github.com/ilikenwf/nestedSortable + * + * Depends on: + * jquery.ui.sortable.js 1.10+ + * + * Copyright (c) 2010-2016 Manuele J Sarfatti and contributors + * Licensed under the MIT License + * http://www.opensource.org/licenses/mit-license.php + */ +(function( factory ) { + "use strict"; + + var define = window.define; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "jquery-ui/sortable" + ], factory ); + } else { + + // Browser globals + factory( window.jQuery ); + } +}(function($) { + "use strict"; + + function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); + } + + $.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, { + + options: { + disableParentChange: false, + doNotClear: false, + expandOnHover: 700, + isAllowed: function() { return true; }, + isTree: false, + listType: "ol", + maxLevels: 0, + protectRoot: false, + rootID: null, + rtl: false, + startCollapsed: false, + tabSize: 20, + + branchClass: "mjs-nestedSortable-branch", + collapsedClass: "mjs-nestedSortable-collapsed", + disableNestingClass: "mjs-nestedSortable-no-nesting", + errorClass: "mjs-nestedSortable-error", + expandedClass: "mjs-nestedSortable-expanded", + hoveringClass: "mjs-nestedSortable-hovering", + leafClass: "mjs-nestedSortable-leaf", + disabledClass: "mjs-nestedSortable-disabled" + }, + + _create: function() { + var self = this, + err; + + this.element.data("ui-sortable", this.element.data("mjs-nestedSortable")); + + // mjs - prevent browser from freezing if the HTML is not correct + if (!this.element.is(this.options.listType)) { + err = "nestedSortable: " + + "Please check that the listType option is set to your actual list type"; + + throw new Error(err); + } + + // if we have a tree with expanding/collapsing functionality, + // force 'intersect' tolerance method + if (this.options.isTree && this.options.expandOnHover) { + this.options.tolerance = "intersect"; + } + + $.ui.sortable.prototype._create.apply(this, arguments); + + // prepare the tree by applying the right classes + // (the CSS is responsible for actual hide/show functionality) + if (this.options.isTree) { + $(this.items).each(function() { + var $li = this.item, + hasCollapsedClass = $li.hasClass(self.options.collapsedClass), + hasExpandedClass = $li.hasClass(self.options.expandedClass); + + if ($li.children(self.options.listType).length) { + $li.addClass(self.options.branchClass); + // expand/collapse class only if they have children + + if ( !hasCollapsedClass && !hasExpandedClass ) { + if (self.options.startCollapsed) { + $li.addClass(self.options.collapsedClass); + } else { + $li.addClass(self.options.expandedClass); + } + } + } else { + $li.addClass(self.options.leafClass); + } + }); + } + }, + + _destroy: function() { + this.element + .removeData("mjs-nestedSortable") + .removeData("ui-sortable"); + return $.ui.sortable.prototype._destroy.apply(this, arguments); + }, + + _mouseDrag: function(event) { + var i, + item, + itemElement, + intersection, + self = this, + o = this.options, + scrolled = false, + $document = $(document), + previousTopOffset, + parentItem, + level, + childLevels, + itemAfter, + itemBefore, + newList, + method, + a, + previousItem, + nextItem, + helperIsNotSibling; + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Do scrolling + if (this.options.scroll) { + if (this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { + + if ( + ( + this.overflowOffset.top + + this.scrollParent[0].offsetHeight + ) - + event.pageY < + o.scrollSensitivity + ) { + scrolled = this.scrollParent.scrollTop() + o.scrollSpeed; + this.scrollParent.scrollTop(scrolled); + } else if ( + event.pageY - + this.overflowOffset.top < + o.scrollSensitivity + ) { + scrolled = this.scrollParent.scrollTop() - o.scrollSpeed; + this.scrollParent.scrollTop(scrolled); + } + + if ( + ( + this.overflowOffset.left + + this.scrollParent[0].offsetWidth + ) - + event.pageX < + o.scrollSensitivity + ) { + scrolled = this.scrollParent.scrollLeft() + o.scrollSpeed; + this.scrollParent.scrollLeft(scrolled); + } else if ( + event.pageX - + this.overflowOffset.left < + o.scrollSensitivity + ) { + scrolled = this.scrollParent.scrollLeft() - o.scrollSpeed; + this.scrollParent.scrollLeft(scrolled); + } + + } else { + + if ( + event.pageY - + $document.scrollTop() < + o.scrollSensitivity + ) { + scrolled = $document.scrollTop() - o.scrollSpeed; + $document.scrollTop(scrolled); + } else if ( + $(window).height() - + ( + event.pageY - + $document.scrollTop() + ) < + o.scrollSensitivity + ) { + scrolled = $document.scrollTop() + o.scrollSpeed; + $document.scrollTop(scrolled); + } + + if ( + event.pageX - + $document.scrollLeft() < + o.scrollSensitivity + ) { + scrolled = $document.scrollLeft() - o.scrollSpeed; + $document.scrollLeft(scrolled); + } else if ( + $(window).width() - + ( + event.pageX - + $document.scrollLeft() + ) < + o.scrollSensitivity + ) { + scrolled = $document.scrollLeft() + o.scrollSpeed; + $document.scrollLeft(scrolled); + } + + } + + if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + } + + //Regenerate the absolute position used for position checks + this.positionAbs = this._convertPositionTo("absolute"); + + // mjs - find the top offset before rearrangement, + previousTopOffset = this.placeholder.offset().top; + + //Set the helper position + if (!this.options.axis || this.options.axis !== "y") { + this.helper[0].style.left = this.position.left + "px"; + } + if (!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = (this.position.top) + "px"; + } + + // mjs - check and reset hovering state at each cycle + this.hovering = this.hovering ? this.hovering : null; + this.mouseentered = this.mouseentered ? this.mouseentered : false; + + // mjs - let's start caching some variables + (function() { + var _parentItem = this.placeholder.parent().parent(); + if (_parentItem && _parentItem.closest(".ui-sortable").length) { + parentItem = _parentItem; + } + }.call(this)); + + level = this._getLevel(this.placeholder); + childLevels = this._getChildLevels(this.helper); + newList = document.createElement(o.listType); + + //Rearrange + for (i = this.items.length - 1; i >= 0; i--) { + + //Cache variables and intersection, continue if no intersection + item = this.items[i]; + itemElement = item.item[0]; + intersection = this._intersectsWithPointer(item); + if (!intersection) { + continue; + } + + // Only put the placeholder inside the current Container, skip all + // items form other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this moving items in "sub-sortables" can cause the placeholder to jitter + // beetween the outer and inner container. + if (item.instance !== this.currentContainer) { + continue; + } + + // No action if intersected item is disabled + // and the element above or below in the direction we're going is also disabled + if (itemElement.className.indexOf(o.disabledClass) !== -1) { + // Note: intersection hardcoded direction values from + // jquery.ui.sortable.js:_intersectsWithPointer + if (intersection === 2) { + // Going down + itemAfter = this.items[i + 1]; + if (itemAfter && itemAfter.item.hasClass(o.disabledClass)) { + continue; + } + + } else if (intersection === 1) { + // Going up + itemBefore = this.items[i - 1]; + if (itemBefore && itemBefore.item.hasClass(o.disabledClass)) { + continue; + } + } + } + + method = intersection === 1 ? "next" : "prev"; + + // cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if (itemElement !== this.currentItem[0] && + this.placeholder[method]()[0] !== itemElement && + !$.contains(this.placeholder[0], itemElement) && + ( + this.options.type === "semi-dynamic" ? + !$.contains(this.element[0], itemElement) : + true + ) + ) { + + // mjs - we are intersecting an element: + // trigger the mouseenter event and store this state + if (!this.mouseentered) { + $(itemElement).mouseenter(); + this.mouseentered = true; + } + + // mjs - if the element has children and they are hidden, + // show them after a delay (CSS responsible) + if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) { + if (!this.hovering) { + $(itemElement).addClass(o.hoveringClass); + this.hovering = window.setTimeout(function() { + $(itemElement) + .removeClass(o.collapsedClass) + .addClass(o.expandedClass); + + self.refreshPositions(); + self._trigger("expand", event, self._uiHash()); + }, o.expandOnHover); + } + } + + this.direction = intersection === 1 ? "down" : "up"; + + // mjs - rearrange the elements and reset timeouts and hovering state + if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { + $(itemElement).mouseleave(); + this.mouseentered = false; + $(itemElement).removeClass(o.hoveringClass); + if (this.hovering) { + window.clearTimeout(this.hovering); + } + this.hovering = null; + + // mjs - do not switch container if + // it's a root item and 'protectRoot' is true + // or if it's not a root item but we are trying to make it root + if (o.protectRoot && + !( + this.currentItem[0].parentNode === this.element[0] && + // it's a root item + itemElement.parentNode !== this.element[0] + // it's intersecting a non-root item + ) + ) { + if (this.currentItem[0].parentNode !== this.element[0] && + itemElement.parentNode === this.element[0] + ) { + + if ( !$(itemElement).children(o.listType).length) { + itemElement.appendChild(newList); + if (o.isTree) { + $(itemElement) + .removeClass(o.leafClass) + .addClass(o.branchClass + " " + o.expandedClass); + } + } + + if (this.direction === "down") { + a = $(itemElement).prev().children(o.listType); + } else { + a = $(itemElement).children(o.listType); + } + + if (a[0] !== undefined) { + this._rearrange(event, null, a); + } + + } else { + this._rearrange(event, item); + } + } else if (!o.protectRoot) { + this._rearrange(event, item); + } + } else { + break; + } + + // Clear emtpy ul's/ol's + this._clearEmpty(itemElement); + + this._trigger("change", event, this._uiHash()); + break; + } + } + + // mjs - to find the previous sibling in the list, + // keep backtracking until we hit a valid list item. + (function() { + var _previousItem = this.placeholder.prev(); + if (_previousItem.length) { + previousItem = _previousItem; + } else { + previousItem = null; + } + }.call(this)); + + if (previousItem != null) { + while ( + previousItem[0].nodeName.toLowerCase() !== "li" || + previousItem[0].className.indexOf(o.disabledClass) !== -1 || + previousItem[0] === this.currentItem[0] || + previousItem[0] === this.helper[0] + ) { + if (previousItem[0].previousSibling) { + previousItem = $(previousItem[0].previousSibling); + } else { + previousItem = null; + break; + } + } + } + + // mjs - to find the next sibling in the list, + // keep stepping forward until we hit a valid list item. + (function() { + var _nextItem = this.placeholder.next(); + if (_nextItem.length) { + nextItem = _nextItem; + } else { + nextItem = null; + } + }.call(this)); + + if (nextItem != null) { + while ( + nextItem[0].nodeName.toLowerCase() !== "li" || + nextItem[0].className.indexOf(o.disabledClass) !== -1 || + nextItem[0] === this.currentItem[0] || + nextItem[0] === this.helper[0] + ) { + if (nextItem[0].nextSibling) { + nextItem = $(nextItem[0].nextSibling); + } else { + nextItem = null; + break; + } + } + } + + this.beyondMaxLevels = 0; + + // mjs - if the item is moved to the left, send it one level up + // but only if it's at the bottom of the list + if (parentItem != null && + nextItem == null && + !(o.protectRoot && parentItem[0].parentNode == this.element[0]) && + ( + o.rtl && + ( + this.positionAbs.left + + this.helper.outerWidth() > parentItem.offset().left + + parentItem.outerWidth() + ) || + !o.rtl && (this.positionAbs.left < parentItem.offset().left) + ) + ) { + + parentItem.after(this.placeholder[0]); + helperIsNotSibling = !parentItem + .children(o.listItem) + .children("li:visible:not(.ui-sortable-helper)") + .length; + if (o.isTree && helperIsNotSibling) { + parentItem + .removeClass(this.options.branchClass + " " + this.options.expandedClass) + .addClass(this.options.leafClass); + } + if(typeof parentItem !== 'undefined') + this._clearEmpty(parentItem[0]); + this._trigger("change", event, this._uiHash()); + // mjs - if the item is below a sibling and is moved to the right, + // make it a child of that sibling + } else if (previousItem != null && + !previousItem.hasClass(o.disableNestingClass) && + ( + previousItem.children(o.listType).length && + previousItem.children(o.listType).is(":visible") || + !previousItem.children(o.listType).length + ) && + !(o.protectRoot && this.currentItem[0].parentNode === this.element[0]) && + ( + o.rtl && + ( + this.positionAbs.left + + this.helper.outerWidth() < + previousItem.offset().left + + previousItem.outerWidth() - + o.tabSize + ) || + !o.rtl && + (this.positionAbs.left > previousItem.offset().left + o.tabSize) + ) + ) { + + this._isAllowed(previousItem, level, level + childLevels + 1); + + if (!previousItem.children(o.listType).length) { + previousItem[0].appendChild(newList); + if (o.isTree) { + previousItem + .removeClass(o.leafClass) + .addClass(o.branchClass + " " + o.expandedClass); + } + } + + // mjs - if this item is being moved from the top, add it to the top of the list. + if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) { + previousItem.children(o.listType).prepend(this.placeholder); + } else { + // mjs - otherwise, add it to the bottom of the list. + previousItem.children(o.listType)[0].appendChild(this.placeholder[0]); + } + if(typeof parentItem !== 'undefined') + this._clearEmpty(parentItem[0]); + this._trigger("change", event, this._uiHash()); + } else { + this._isAllowed(parentItem, level, level + childLevels); + } + + //Post events to containers + this._contactContainers(event); + + //Interconnect with droppables + if ($.ui.ddmanager) { + $.ui.ddmanager.drag(this, event); + } + + //Call callbacks + this._trigger("sort", event, this._uiHash()); + + this.lastPositionAbs = this.positionAbs; + return false; + + }, + + _mouseStop: function(event) { + // mjs - if the item is in a position not allowed, send it back + if (this.beyondMaxLevels) { + + this.placeholder.removeClass(this.options.errorClass); + + if (this.domPosition.prev) { + $(this.domPosition.prev).after(this.placeholder); + } else { + $(this.domPosition.parent).prepend(this.placeholder); + } + + this._trigger("revert", event, this._uiHash()); + + } + + // mjs - clear the hovering timeout, just to be sure + $("." + this.options.hoveringClass) + .mouseleave() + .removeClass(this.options.hoveringClass); + + this.mouseentered = false; + if (this.hovering) { + window.clearTimeout(this.hovering); + } + this.hovering = null; + + this._relocate_event = event; + this._pid_current = $(this.domPosition.parent).parent().attr("id"); + this._sort_current = this.domPosition.prev ? $(this.domPosition.prev).next().index() : 0; + $.ui.sortable.prototype._mouseStop.apply(this, arguments); //asybnchronous execution, @see _clear for the relocate event. + }, + + // mjs - this function is slightly modified + // to make it easier to hover over a collapsed element and have it expand + _intersectsWithSides: function(item) { + + var half = this.options.isTree ? .8 : .5, + isOverBottomHalf = isOverAxis( + this.positionAbs.top + this.offset.click.top, + item.top + (item.height * half), + item.height + ), + isOverTopHalf = isOverAxis( + this.positionAbs.top + this.offset.click.top, + item.top - (item.height * half), + item.height + ), + isOverRightHalf = isOverAxis( + this.positionAbs.left + this.offset.click.left, + item.left + (item.width / 2), + item.width + ), + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (this.floating && horizontalDirection) { + return ( + (horizontalDirection === "right" && isOverRightHalf) || + (horizontalDirection === "left" && !isOverRightHalf) + ); + } else { + return verticalDirection && ( + (verticalDirection === "down" && isOverBottomHalf) || + (verticalDirection === "up" && isOverTopHalf) + ); + } + + }, + + _contactContainers: function() { + + if (this.options.protectRoot && this.currentItem[0].parentNode === this.element[0] ) { + return; + } + + $.ui.sortable.prototype._contactContainers.apply(this, arguments); + + }, + + _clear: function() { + var i, + item; + + $.ui.sortable.prototype._clear.apply(this, arguments); + + //relocate event + if (!(this._pid_current === this._uiHash().item.parent().parent().attr("id") && + this._sort_current === this._uiHash().item.index())) { + this._trigger("relocate", this._relocate_event, this._uiHash()); + } + + // mjs - clean last empty ul/ol + for (i = this.items.length - 1; i >= 0; i--) { + item = this.items[i].item[0]; + this._clearEmpty(item); + } + + }, + + serialize: function(options) { + + var o = $.extend({}, this.options, options), + items = this._getItemsAsjQuery(o && o.connected), + str = []; + + $(items).each(function() { + var res = ($(o.item || this).attr(o.attribute || "id") || "") + .match(o.expression || (/(.+)[-=_](.+)/)), + pid = ($(o.item || this).parent(o.listType) + .parent(o.items) + .attr(o.attribute || "id") || "") + .match(o.expression || (/(.+)[-=_](.+)/)); + + if (res) { + str.push( + ( + (o.key || res[1]) + + "[" + + (o.key && o.expression ? res[1] : res[2]) + "]" + ) + + "=" + + (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID)); + } + }); + + if (!str.length && o.key) { + str.push(o.key + "="); + } + + return str.join("&"); + + }, + + toHierarchy: function(options) { + + var o = $.extend({}, this.options, options), + ret = []; + + $(this.element).children(o.items).each(function() { + var level = _recursiveItems(this); + ret.push(level); + }); + + return ret; + + function _recursiveItems(item) { + var id = ($(item).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[-=_](.+)/)), + currentItem; + + var data = $(item).data(); + if (data.nestedSortableItem) { + delete data.nestedSortableItem; // Remove the nestedSortableItem object from the data + } + + if (id) { + currentItem = { + "id": id[2] + }; + + currentItem = $.extend({}, currentItem, data); // Combine the two objects + + if ($(item).children(o.listType).children(o.items).length > 0) { + currentItem.children = []; + $(item).children(o.listType).children(o.items).each(function() { + var level = _recursiveItems(this); + currentItem.children.push(level); + }); + } + return currentItem; + } + } + }, + + toArray: function(options) { + + var o = $.extend({}, this.options, options), + sDepth = o.startDepthCount || 0, + ret = [], + left = 1; + + if (!o.excludeRoot) { + ret.push({ + "item_id": o.rootID, + "parent_id": null, + "depth": sDepth, + "left": left, + "right": ($(o.items, this.element).length + 1) * 2 + }); + left++; + } + + $(this.element).children(o.items).each(function() { + left = _recursiveArray(this, sDepth, left); + }); + + ret = ret.sort(function(a, b) { return (a.left - b.left); }); + + return ret; + + function _recursiveArray(item, depth, _left) { + + var right = _left + 1, + id, + pid, + parentItem; + + if ($(item).children(o.listType).children(o.items).length > 0) { + depth++; + $(item).children(o.listType).children(o.items).each(function() { + right = _recursiveArray($(this), depth, right); + }); + depth--; + } + + id = ($(item).attr(o.attribute || "id")).match(o.expression || (/(.+)[-=_](.+)/)); + + if (depth === sDepth) { + pid = o.rootID; + } else { + parentItem = ($(item).parent(o.listType) + .parent(o.items) + .attr(o.attribute || "id")) + .match(o.expression || (/(.+)[-=_](.+)/)); + pid = parentItem[2]; + } + + if (id) { + var name = $(item).data("name"); + ret.push({ + "id": id[2], + "parent_id": pid, + "depth": depth, + "left": _left, + "right": right, + "name":name + }); + } + + _left = right + 1; + return _left; + } + + }, + + _clearEmpty: function (item) { + function replaceClass(elem, search, replace, swap) { + if (swap) { + search = [replace, replace = search][0]; + } + + $(elem).removeClass(search).addClass(replace); + } + + var o = this.options, + childrenList = $(item).children(o.listType), + hasChildren = childrenList.is(':not(:empty)'); + + var doNotClear = + o.doNotClear || + hasChildren || + o.protectRoot && $(item)[0] === this.element[0]; + + if (o.isTree) { + replaceClass(item, o.branchClass, o.leafClass, doNotClear); + + if (doNotClear && hasChildren) { + replaceClass(item, o.collapsedClass, o.expandedClass); + } + } + + if (!doNotClear) { + childrenList.remove(); + } + }, + + _getLevel: function(item) { + + var level = 1, + list; + + if (this.options.listType) { + list = item.closest(this.options.listType); + while (list && list.length > 0 && !list.is(".ui-sortable")) { + level++; + list = list.parent().closest(this.options.listType); + } + } + + return level; + }, + + _getChildLevels: function(parent, depth) { + var self = this, + o = this.options, + result = 0; + depth = depth || 0; + + $(parent).children(o.listType).children(o.items).each(function(index, child) { + result = Math.max(self._getChildLevels(child, depth + 1), result); + }); + + return depth ? result + 1 : result; + }, + + _isAllowed: function(parentItem, level, levels) { + var o = this.options, + // this takes into account the maxLevels set to the recipient list + maxLevels = this + .placeholder + .closest(".ui-sortable") + .nestedSortable("option", "maxLevels"), + + // Check if the parent has changed to prevent it, when o.disableParentChange is true + oldParent = this.currentItem.parent().parent(), + disabledByParentchange = o.disableParentChange && ( + //From somewhere to somewhere else, except the root + typeof parentItem !== 'undefined' && !oldParent.is(parentItem) || + typeof parentItem === 'undefined' && oldParent.is("li") //From somewhere to the root + ); + // mjs - is the root protected? + // mjs - are we nesting too deep? + if ( + disabledByParentchange || + !o.isAllowed(this.placeholder, parentItem, this.currentItem) + ) { + this.placeholder.addClass(o.errorClass); + if (maxLevels < levels && maxLevels !== 0) { + this.beyondMaxLevels = levels - maxLevels; + } else { + this.beyondMaxLevels = 1; + } + } else { + if (maxLevels < levels && maxLevels !== 0) { + this.placeholder.addClass(o.errorClass); + this.beyondMaxLevels = levels - maxLevels; + } else { + this.placeholder.removeClass(o.errorClass); + this.beyondMaxLevels = 0; + } + } + } + + })); + + $.mjs.nestedSortable.prototype.options = $.extend( + {}, + $.ui.sortable.prototype.options, + $.mjs.nestedSortable.prototype.options + ); +})); diff --git a/src/src/controllers/MenuController.php b/src/src/controllers/MenuController.php new file mode 100644 index 0000000..ba383ee --- /dev/null +++ b/src/src/controllers/MenuController.php @@ -0,0 +1,208 @@ +getSites()->currentSite->handle; + + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + } + $this->view->registerAssetBundle(OlivemenusAsset::class); + $data['menus'] = Olivemenus::$plugin->olivemenus->getAllMenus($objSite->id); + $data['objSite'] = $objSite; + + return $this->renderTemplate('olivemenus/_index', $data); + } + + /** + * Handle a request going to our plugin's actionMenuNew URL, + * e.g.: actions/olivemenus/menu/menu-new + * + * @return mixed + */ + public function actionMenuNew($siteHandle) + { + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + } + $data['objSite'] = $objSite; + + $this->view->registerAssetBundle(OlivemenusAsset::class); + + return $this->renderTemplate('olivemenus/_menu-new', $data); + } + /** + * Handle a request going to our plugin's actionSaveMenu URL, + * e.g.: actions/olivemenus/menu/save-menu + * + * @return mixed + */ + public function actionSaveMenu() + { + $this->requirePostRequest(); + if (isset(Craft::$app->request->getBodyParams()['data']['id'])) { + $model = Olivemenus::$plugin->olivemenus->getMenuById(Craft::$app->request->getBodyParams()['data']['id']); + } else { + $model = new OlivemenusModel(); + } + + $model->setAttributes(Craft::$app->request->getBodyParams()['data']); + + if (!$model->validate()) { + Craft::$app->getSession()->setError(Craft::t('olivemenus', 'Validation errors have occured.')); + + $objSite = Craft::$app->getSites()->getSiteById($model->site_id); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + } + + return $this->renderTemplate('olivemenus/_menu-new', [ + 'menu' => $model, + 'errors' => $model->getErrors(), + 'objSite' => $objSite + ]); + } else { + Olivemenus::$plugin->olivemenus->saveMenu($model); + Craft::$app->getSession()->setNotice(Craft::t('olivemenus', 'Menu saved successfully.')); + + $objSite = Craft::$app->getSites()->getSiteById($model->site_id); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + } else { + $siteHandle = $objSite->handle; + } + return $this->redirect("olivemenus/$siteHandle"); + } + + } + + public function actionDeleteMenu() { + if (Craft::$app->request->getIsAjax()) { + $this->requirePostRequest(); + $this->requireAcceptsJson(); + + if (Olivemenus::$plugin->olivemenus->deleteMenuById(Craft::$app->request->post('menuID'))) { + // Return data + $returnData['success'] = true; + return $this->asJson($returnData); + }; + } else { + $menuId = Craft::$app->request->getSegment(3); + + if ($menuId) { + $menu = Olivemenus::$plugin->olivemenus->getMenuById($menuId); + if (Olivemenus::$plugin->olivemenus->deleteMenuById($menuId)) { + Craft::$app->getSession()->setNotice(Craft::t('olivemenus', 'Menu deleted successfully.')); + } else { + Craft::$app->getSession()->setError(Craft::t('olivemenus', 'An error occurred while deleting menu.')); + } + $objSite = Craft::$app->getSites()->getSiteById($menu->site_id); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + } else { + $siteHandle = $objSite->handle; + } + return $this->redirect("olivemenus/$siteHandle"); + } + + return $this->redirect("olivemenus"); + } + } + + public function actionMenuEdit($menuId = null) { + if ($menuId) { + $menu = Olivemenus::$plugin->olivemenus->getMenuById($menuId); + $arrData['menu'] = $menu; + + if (isset(Craft::$app->request->getBodyParams()['data']['id'])) { + $model = Olivemenus::$plugin->olivemenus->getMenuById(Craft::$app->request->getBodyParams()['data']['id']); + $model->setAttributes(Craft::$app->request->getBodyParams()['data']); + + if (!$model->validate()) { + Craft::$app->getSession()->setError(Craft::t('olivemenus', 'Validation errors have occured.')); + $arrData['menu'] = $model; + $arrData['errors'] = $model->getErrors(); + $arrData['originalMenu'] = $menu; + } else { + Olivemenus::$plugin->olivemenus->saveMenu($model); + Craft::$app->getSession()->setNotice(Craft::t('olivemenus', 'Menu saved successfully.')); + + $arrData['menu'] = $model; + } + } + + $objSite = Craft::$app->getSites()->getSiteById($menu->site_id); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + } + $arrData['objSite'] = $objSite; + + return $this->renderTemplate('olivemenus/_menu-edit', $arrData); + } + } +} diff --git a/src/src/controllers/MenuItemsController.php b/src/src/controllers/MenuItemsController.php new file mode 100644 index 0000000..562b5f4 --- /dev/null +++ b/src/src/controllers/MenuItemsController.php @@ -0,0 +1,149 @@ +view->registerAssetBundle(OlivemenuItemsAsset::class); + $menu = Olivemenus::$plugin->olivemenus->getMenuById($menuId); + $data['menu'] = $menu; + $data['sections'] = Olivemenus::$plugin->olivemenuItems->getSectionsWithEntries($menu->site_id); + $data['menuItemsMarkup'] = Olivemenus::$plugin->olivemenuItems->getMenuItemsAdminMarkup($menuId); + $data['categories'] = Craft::$app + ->categories + ->getAllGroups(); + + $objSite = Craft::$app->getSites()->getSiteById($menu->site_id); + if (!$objSite) { + $siteHandle = Craft::$app->getSites()->getPrimarySite()->handle; + $objSite = Craft::$app->getSites()->getSiteByHandle($siteHandle); + } + $data['objSite'] = $objSite; + return $this->renderTemplate('olivemenus/_menu-items', $data); + } + + /** + * Handle a request going to our plugin's actionSave URL, + * e.g.: actions/olivemenus/menu-items/save-menu-items + * + * @return mixed + */ + public function actionSaveMenuItems() + { + $this->requirePostRequest(); + $intMenuId = Craft::$app->request->getBodyParams()['menu-id']; + $strMenuItems = Craft::$app->request->getBodyParams()['menu-items-serialized']; + + $arrMenuItems = json_decode($strMenuItems, true); + + if (!empty($arrMenuItems)) { + foreach($arrMenuItems as $order=> $menuItem) { + $parent_id = 0; + + if (isset($menuItem['parent-id'])){ + $parent_id = $menuItem['parent-id']; + + foreach ($arrMenuItems as $element) { + if (isset($element['item-id']['html']) && $element['item-id']['html'] == $parent_id) { + $parent_id = $element['menu-item-db-id']; + $arrMenuItems[$order]['parent-id'] = $parent_id; + break; + } + } + } + + if ($menuItem['item-id']['db'] != null) { + $menuItemModel = Olivemenus::$plugin->olivemenuItems->getMenuItem($menuItem['item-id']['db']); + } else { + $menuItemModel = new OlivemenusItemsModel(); + } + $arrData['id']= $menuItem['item-id']['db']; + $arrData['menu_id']= $intMenuId; + $arrData['parent_id']= $parent_id; + $arrData['item_order']= $order; + $arrData['name']= $menuItem['name']; + $arrData['entry_id']= (isset($menuItem['entry-id']) ? $menuItem['entry-id'] : ''); + $arrData['custom_url']= (isset($menuItem['custom-url']) ? $menuItem['custom-url'] : ''); + $arrData['class']= (isset($menuItem['class']) ? $menuItem['class'] : ''); + $arrData['class_parent']= (isset($menuItem['class-parent']) ? $menuItem['class-parent'] : ''); + $arrData['data_json']= (isset($menuItem['data-json']) ? $menuItem['data-json'] : ''); + $arrData['target']= (isset($menuItem['target']) ? $menuItem['target'] : ''); + + $menuItemModel->setAttributes($arrData); + + if ($menuItemModel->validate()) { + $menuItemDbId = Olivemenus::$plugin->olivemenuItems->saveMenuItem($menuItemModel); + if (is_numeric($menuItemDbId)) $arrMenuItems[$order]['menu-item-db-id'] = $menuItemDbId; + } + } + } + + $menuItemsDeleted = Craft::$app->request->getBodyParams()['menu-items-deleted']; + if (!empty($menuItemsDeleted)) { + $arrItems = explode(',', $menuItemsDeleted); + if (!empty($arrItems)) { + foreach ($arrItems as $intVal) { + Olivemenus::$plugin->olivemenuItems->deleteMenuItem($intVal); + } + } + } + Craft::$app->getSession()->setNotice(Craft::t('olivemenus', 'Menu items saved successfully.')); + } +} \ No newline at end of file diff --git a/src/src/icon-mask.svg b/src/src/icon-mask.svg new file mode 100644 index 0000000..2bc92a1 --- /dev/null +++ b/src/src/icon-mask.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/src/src/icon.svg b/src/src/icon.svg new file mode 100644 index 0000000..6635023 --- /dev/null +++ b/src/src/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/src/migrations/Install.php b/src/src/migrations/Install.php new file mode 100644 index 0000000..ac480bd --- /dev/null +++ b/src/src/migrations/Install.php @@ -0,0 +1,198 @@ +driver = Craft::$app->getConfig()->getDb()->driver; + if ($this->createTables()) { + $this->createIndexes(); + $this->addForeignKeys(); + // Refresh the db schema caches + Craft::$app->db->schema->refresh(); + $this->insertDefaultData(); + } + + return true; + } + + /** + * This method contains the logic to be executed when removing this migration. + * This method differs from [[down()]] in that the DB logic implemented here will + * be enclosed within a DB transaction. + * Child classes may implement this method instead of [[down()]] if the DB logic + * needs to be within a transaction. + * + * @return boolean return a false value to indicate the migration fails + * and should not proceed further. All other return values mean the migration succeeds. + */ + public function safeDown() + { + $this->driver = Craft::$app->getConfig()->getDb()->driver; + $this->removeTables(); + + return true; + } + + // Protected Methods + // ========================================================================= + + /** + * Creates the tables needed for the Records used by the plugin + * + * @return bool + */ + protected function createTables() + { + $tablesCreated = false; + + // olivemenus table + $tableSchema = Craft::$app->db->schema->getTableSchema('{{%olivemenus}}'); + if ($tableSchema === null) { + $tablesCreated = true; + $this->createTable( + '{{%olivemenus}}', + [ + 'id' => $this->primaryKey(), + 'name' => $this->string(255)->notNull()->defaultValue(''), + 'handle' => $this->string(255)->notNull()->defaultValue(''), + 'dateCreated' => $this->dateTime()->notNull(), + 'dateUpdated' => $this->dateTime()->notNull(), + 'uid' => $this->uid(), + ] + ); + } + + //olivemenus_items table + $tableSchema = Craft::$app->db->schema->getTableSchema('{{%olivemenus_items}}'); + if ($tableSchema === null) { + $tablesCreated = true; + $this->createTable( + '{{%olivemenus_items}}', + [ + 'id' => $this->primaryKey(), + 'menu_id' => $this->integer(11)->notNull(), + 'parent_id' => $this->integer(11)->notNull(), + 'item_order' => $this->integer(11)->notNull()->defaultValue(0), + 'name' => $this->string(255)->notNull()->defaultValue(''), + 'entry_id' => $this->integer(11), + 'custom_url' => $this->string(255), + 'class' => $this->string(255), + 'class_parent' => $this->string(255), + 'data_json' => $this->string(255), + 'target' => $this->string(255), + 'dateCreated' => $this->dateTime()->notNull(), + 'dateUpdated' => $this->dateTime()->notNull(), + 'uid' => $this->uid(), + ] + ); + } + return $tablesCreated; + } + + /** + * Creates the indexes needed for the Records used by the plugin + * + * @return void + */ + protected function createIndexes() + { + // olivemenus table + $this->createIndex( + $this->db->getIndexName( + '{{%olivemenus}}', + 'name', + true + ), + '{{%olivemenus}}', + 'name', + true + ); + $this->createIndex( + $this->db->getIndexName( + '{{%olivemenus}}', + 'handle', + true + ), + '{{%olivemenus}}', + 'handle', + true + ); + // Additional commands depending on the db driver + switch ($this->driver) { + case DbConfig::DRIVER_MYSQL: + break; + case DbConfig::DRIVER_PGSQL: + break; + } + } + + /** + * Creates the foreign keys needed for the Records used by the plugin + * + * @return void + */ + protected function addForeignKeys() + { + $this->addForeignKey( + $this->db->getForeignKeyName('{{%olivemenus_items}}', 'menu_id'), + '{{%olivemenus_items}}', + 'menu_id', + '{{%olivemenus}}', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + /** + * Populates the DB with the default data. + * + * @return void + */ + protected function insertDefaultData() + { + } + + /** + * Removes the tables needed for the Menus used by the plugin + * + * @return void + */ + protected function removeTables() + { + $this->dropTableIfExists('{{%olivemenus_items}}'); + $this->dropTableIfExists('{{%olivemenus}}'); + } +} diff --git a/src/src/migrations/m200212_124859_olivemenus_addFieldToMenusItemsTable.php b/src/src/migrations/m200212_124859_olivemenus_addFieldToMenusItemsTable.php new file mode 100644 index 0000000..117df8d --- /dev/null +++ b/src/src/migrations/m200212_124859_olivemenus_addFieldToMenusItemsTable.php @@ -0,0 +1,33 @@ +db->columnExists('{{%olivemenus_items}}', 'target')) { + $this->addColumn('{{%olivemenus_items}}', 'target', $this->string(255)->after('data_json')); + } + } + + /** + * @inheritdoc + */ + public function safeDown() + { + echo "m200212_124859_olivemenus_addFieldToMenusItemsTable cannot be reverted.\n"; + return false; + } +} \ No newline at end of file diff --git a/src/src/migrations/m200228_124859_olivemenus_addSiteIdFieldToMenusTable.php b/src/src/migrations/m200228_124859_olivemenus_addSiteIdFieldToMenusTable.php new file mode 100644 index 0000000..16ebc20 --- /dev/null +++ b/src/src/migrations/m200228_124859_olivemenus_addSiteIdFieldToMenusTable.php @@ -0,0 +1,31 @@ +db->columnExists('{{%olivemenus}}', 'site_id')) { + $this->addColumn('{{%olivemenus}}', 'site_id', $this->integer(11)->after('handle')); + } + } + + /** + * @inheritdoc + */ + public function safeDown() + { + $this->dropColumn('{{%olivemenus}}', 'site_id'); + } +} diff --git a/src/src/migrations/m200515_124130_olivemenus_fixBrokenMultisiteMigrations.php b/src/src/migrations/m200515_124130_olivemenus_fixBrokenMultisiteMigrations.php new file mode 100644 index 0000000..7026d5b --- /dev/null +++ b/src/src/migrations/m200515_124130_olivemenus_fixBrokenMultisiteMigrations.php @@ -0,0 +1,29 @@ +update('{{%olivemenus}}', ['site_id' => Craft::$app->sites->primarySite->id], ['site_id' => null]); + } + + /** + * @inheritdoc + */ + public function safeDown() + { + return true; + } +}