From e84df311c247bee04b86c8aca4eafefa2c1ace37 Mon Sep 17 00:00:00 2001 From: dignajar Date: Mon, 30 Nov 2020 22:00:54 +0100 Subject: [PATCH] a few updates for the admin panel --- bl-kernel/admin/controllers/content.php | 22 +- bl-kernel/admin/controllers/new-content.php | 21 +- bl-kernel/admin/controllers/settings.php | 21 +- .../themes/booty/css/bludit.bootstrap.css | 118 ++-- bl-kernel/admin/themes/booty/css/bludit.css | 329 +++++----- bl-kernel/admin/themes/booty/index.php | 6 +- bl-kernel/admin/views/content.php | 36 +- bl-kernel/admin/views/new-content.php | 69 ++- bl-kernel/admin/views/settings copy.php | 568 ++++++++++++++++++ bl-kernel/admin/views/settings.php | 244 ++++---- bl-kernel/boot/init.php | 1 + bl-kernel/css/jquery-ui.min.css | 6 + bl-kernel/css/tagsinput-revisited.min.css | 123 ++++ bl-kernel/functions.php | 2 - .../init.php => helpers/bootstrap.class.php} | 141 +++-- bl-kernel/js/api.js | 182 +++--- bl-kernel/js/jquery-ui.min.js | 1 + bl-kernel/js/tagsinput-revisited.min.js | 30 + 18 files changed, 1328 insertions(+), 592 deletions(-) create mode 100644 bl-kernel/admin/views/settings copy.php create mode 100644 bl-kernel/css/jquery-ui.min.css create mode 100644 bl-kernel/css/tagsinput-revisited.min.css rename bl-kernel/{admin/themes/booty/init.php => helpers/bootstrap.class.php} (96%) create mode 100644 bl-kernel/js/jquery-ui.min.js create mode 100644 bl-kernel/js/tagsinput-revisited.min.js diff --git a/bl-kernel/admin/controllers/content.php b/bl-kernel/admin/controllers/content.php index d8db3787..95a319ae 100644 --- a/bl-kernel/admin/controllers/content.php +++ b/bl-kernel/admin/controllers/content.php @@ -1,7 +1,7 @@ getList($url->pageNumber(), ITEMS_PER_PAGE_ADMIN); @@ -42,7 +34,7 @@ $static = $pages->getStaticDB(true); $sticky = $pages->getStickyDB(true); $autosave = $pages->getAutosaveDB(true); -// If the user is an Author filter the content he/she can edit +// If the user has the role "Author" filter the content so he/she can edit if (checkRole(array('author'), false)) { $published = filterContentOwner($published); $drafts = filterContentOwner($drafts); @@ -51,10 +43,10 @@ if (checkRole(array('author'), false)) { $sticky = filterContentOwner($sticky); } -// Check if out of range the pageNumber +// Check if the page number is out of range if (empty($published) && $url->pageNumber()>1) { Redirect::page('content'); } -// Title of the page -$layout['title'] .= ' - '.$L->g('Manage content'); \ No newline at end of file +// View HTML +$layout['title'] = $L->g('Manage content') . ' - ' . $layout['title']; diff --git a/bl-kernel/admin/controllers/new-content.php b/bl-kernel/admin/controllers/new-content.php index 7a23b291..213e2e07 100644 --- a/bl-kernel/admin/controllers/new-content.php +++ b/bl-kernel/admin/controllers/new-content.php @@ -1,7 +1,7 @@ <?php defined('BLUDIT') or die('Bludit CMS.'); // ============================================================================ -// Check role +// Authorization // ============================================================================ checkRole(array('admin', 'editor', 'author')); @@ -11,20 +11,7 @@ checkRole(array('admin', 'editor', 'author')); // ============================================================================ // ============================================================================ -// Main before POST -// ============================================================================ - -// ============================================================================ -// POST Method -// ============================================================================ - -if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $pageKey = createPage($_POST); - Redirect::page('edit-content/'.$pageKey); -} - -// ============================================================================ -// Main after POST +// Main // ============================================================================ // UUID of the page is need it for autosave and media manager @@ -48,5 +35,5 @@ if (IMAGE_RESTRICT) { define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_THUMBNAILS); } -// Title of the page -$layout['title'] = $L->g('New content').' - '.$layout['title']; \ No newline at end of file +// View HTML <title> +$layout['title'] = $L->g('New content') . ' - ' . $layout['title']; diff --git a/bl-kernel/admin/controllers/settings.php b/bl-kernel/admin/controllers/settings.php index 60c99564..27e7dff1 100644 --- a/bl-kernel/admin/controllers/settings.php +++ b/bl-kernel/admin/controllers/settings.php @@ -1,7 +1,7 @@ <?php defined('BLUDIT') or die('Bludit CMS.'); // ============================================================================ -// Check role +// Authorization // ============================================================================ checkRole(array('admin')); @@ -11,21 +11,8 @@ checkRole(array('admin')); // ============================================================================ // ============================================================================ -// Main after POST +// Main // ============================================================================ -// ============================================================================ -// POST Method -// ============================================================================ - -if ($_SERVER['REQUEST_METHOD'] == 'POST') { - editSettings($_POST); - Redirect::page('settings'); -} - -// ============================================================================ -// Main after POST -// ============================================================================ - -// Title of the page -$layout['title'] .= ' - '.$L->g('Advanced Settings'); \ No newline at end of file +// View HTML <title> +$layout['title'] = $L->g('Settings') . ' - ' . $layout['title']; \ No newline at end of file diff --git a/bl-kernel/admin/themes/booty/css/bludit.bootstrap.css b/bl-kernel/admin/themes/booty/css/bludit.bootstrap.css index b68431c7..f62896e4 100644 --- a/bl-kernel/admin/themes/booty/css/bludit.bootstrap.css +++ b/bl-kernel/admin/themes/booty/css/bludit.bootstrap.css @@ -1,111 +1,143 @@ +/* Tables */ + +.table { + background-color: #F4F4F4; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.02); +} + +.table thead th { + font-size: 0.8em; + text-transform: uppercase!important; +} + +.table td { + border-top: none; +} + + +/* Common elements */ + a { - color: #1A66A6; + color: #1A66A6; } a:hover { - color: #1A66A6; - text-decoration: none; + color: #1A66A6; + text-decoration: none; } .bg-success { - background-color: #8BC34A!important; + background-color: #8BC34A!important; } .text-primary { - color: #06A8C5!important; + color: #06A8C5!important; } .text-danger { - color: #D40000!important; -} -a.text-danger:focus, -a.text-danger:hover { - color: #790000!important; + color: #D40000!important; } +a.text-danger:focus, +a.text-danger:hover { + color: #790000!important; +} + + /* Buttons */ + .btn { - border-radius: 2px; + border-radius: 2px; } .btn-sm { - padding: .25rem .75rem; + padding: .25rem .75rem; } .btn-save { - color: #5b8e09; + color: #5b8e09; } .btn-save:hover { - color: #466d07; + color: #466d07; } .btn-cancel:hover { - color: #000; + color: #000; } .btn-primary { - background-color: #0378D3; - border-color: #0378D3; + background-color: #0378D3; + border-color: #0378D3; } .btn-primary:hover { - background-color: #0270c4; - border-color: #0270c4; + background-color: #0270c4; + border-color: #0270c4; } .btn-primary-disabled { - background-color: #71b6ff !important; - border-color: #71b6ff !important; + background-color: #71b6ff !important; + border-color: #71b6ff !important; } .btn-secondary { - background-color: #6c757d; - border-color: #6c757d; + background-color: #6c757d; + border-color: #6c757d; } .btn-secondary:hover { - background-color: #5a6268; - border-color: #5a6268; + background-color: #5a6268; + border-color: #5a6268; } .btn-light { - color: #212529; - background-color: #f3f3f3; - border-color: #ced4d9; + color: #212529; + background-color: #f3f3f3; + border-color: #ced4d9; } .btn-light.focus, .btn-light:focus { - box-shadow: none !important; + box-shadow: none !important; } .btn.focus, .btn:focus { - box-shadow: none !important; + box-shadow: none !important; } + /* Form */ + .form-control:focus { - box-shadow: none; + box-shadow: none; } -/* Tables */ -.table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(0, 0, 0, 0.02); -} - -.table thead th { - font-size: 0.8em; - text-transform: uppercase!important; -} /* Right sidebar Options */ + #sidebarOptions .card { - background: none; - border: none; + background: none; + border: none; } #sidebarOptions a { - color: #212529; + color: #212529; +} + +.nav-link { + border-color: #f9f9f9; +} + +.nav-link.active { + background-color: #f9f9f9 !important; + border-color: #dee2e6 #dee2e6 #f9f9f9 !important; +} + +.tab-content>.active { + background-color: #f9f9f9 !important; } \ No newline at end of file diff --git a/bl-kernel/admin/themes/booty/css/bludit.css b/bl-kernel/admin/themes/booty/css/bludit.css index 0b032ffc..2c023194 100644 --- a/bl-kernel/admin/themes/booty/css/bludit.css +++ b/bl-kernel/admin/themes/booty/css/bludit.css @@ -1,86 +1,98 @@ html { - font-size: 0.9rem; - background: #EFEFEF; + font-size: 0.9rem; + background: #EFEFEF; } body { - background: #EFEFEF; - color: #1b1b1b; + background: #EFEFEF; + color: #1b1b1b; } +nav.paginator { + background: #EFEFEF; +} + + /* ICONS */ + .fa { - padding-right: 2px; - line-height: inherit; + padding-right: 2px; + line-height: inherit; } + /* SIDEBAR */ + div.sidebar .nav-item a { - padding-left:0; - padding-right:0; - color: #555; - padding-top: 5px; - padding-bottom: 5px; + padding-left: 0; + padding-right: 0; + color: #555; + padding-top: 5px; + padding-bottom: 5px; } div.sidebar .nav-item a:hover { - color: #0078D4; + color: #0078D4; } div.sidebar .nav-item h4 { - font-size: 1.2em; - text-transform: uppercase; - font-weight: 400; - margin-top: 10px; + font-size: 1.2em; + text-transform: uppercase; + font-weight: 400; + margin-top: 10px; } + /* AUTOCOMPLETE SEARCH */ + .search-suggestion { - padding: 5px; + padding: 5px; } .search-suggestion-options { - font-size: 0.9em; - padding-top: 2px; + font-size: 0.9em; + padding-top: 2px; } + /* BOOTSTRAP Hacks */ @media (min-width: 1300px) { - .container { - max-width: 1350px; - } + .container { + max-width: 1350px; + } } + /* for small devices */ + @media (max-width: 575.98px) { - #jsmediaManagerButton, - #jscategoryButton, - #jsdescriptionButton { - width: 100%; - text-align: left; - } + #jsmediaManagerButton, + #jscategoryButton, + #jsdescriptionButton { + width: 100%; + text-align: left; + } } - code { - padding: 3px 5px 2px; - margin: 0 1px; - background: #eaeaea; - background: rgba(0,0,0,.07); - color: #444; + padding: 3px 5px 2px; + margin: 0 1px; + background: #eaeaea; + background: rgba(0, 0, 0, .07); + color: #444; } .list-group-sortable { - cursor: pointer; + cursor: pointer; } @@ -89,235 +101,238 @@ code { */ #dashboard ul.list-group.list-group-striped li { - border: none; - word-break: break-word; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; + border: none; + word-break: break-word; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; } #dashboard ul.list-group.list-group-striped li:nth-of-type(even) { - background: #f1f1f1; - + background: #f1f1f1; } #dashboard div.quick-links-icons { - font-size: 3em; - width: 100%; + font-size: 3em; + width: 100%; } #dashboard a.quick-links { - color: #777; + color: #777; } #dashboard a.quick-links:hover { - text-decoration: none; - color: #4586d4; + text-decoration: none; + color: #4586d4; } #hello-message { - padding: 10px 0; - color: #777; - margin-bottom: 20px; + padding: 10px 0; + color: #777; + margin-bottom: 20px; } #hello-message span.oi { - top: 3px; + top: 3px; } .ct-series-a .ct-line { - /* Set the colour of this series line */ - stroke: #4a90e2; - /* Control the thikness of your lines */ - stroke-width: 2px; - /* Create a dashed line with a pattern */ + /* Set the colour of this series line */ + stroke: #4a90e2; + /* Control the thikness of your lines */ + stroke-width: 2px; + /* Create a dashed line with a pattern */ } .ct-series-a .ct-point { - /* Colour of your points */ - stroke: #4a90e2; - /* Size of your points */ - stroke-width: 8px; + /* Colour of your points */ + stroke: #4a90e2; + /* Size of your points */ + stroke-width: 8px; } + /* ALERT */ #alert { - display: none; - position: fixed; - text-align: center; - border-radius: 0px; - border: 0; - z-index: 1000; - bottom: 0; - right: 0; - margin: 0; + display: none; + position: fixed; + text-align: center; + border-radius: 0px; + border: 0; + z-index: 1000; + bottom: 0; + right: 0; + margin: 0; } .alert-success { - background-color: #4586d4; - border-left: 6px solid #abd1ff !important; - color: #ffffff; + background-color: #4586d4; + border-left: 6px solid #abd1ff !important; + color: #ffffff; } .alert-danger { - background-color: #d44545; - border-left: 6px solid #ff9c9c !important; - color: #ffffff; + background-color: #d44545; + border-left: 6px solid #ff9c9c !important; + color: #ffffff; } - /* PLUGINS */ .plugin-form label { - display: block; - margin-top: 1rem !important; + display: block; + margin-top: 1rem !important; } .plugin-form input[type="text"], .plugin-form textarea, .plugin-form select { - display: block; - width: 100%; - padding: .375rem .75rem; - font-size: 1rem; - line-height: 1.5; - color: #495057; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #ced4da; - border-radius: .25rem; - transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: .25rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; } .plugin-form textarea { - min-height: 120px; + min-height: 120px; } .plugin-form span.tip { - display: block; - font-size: 80%; - font-weight: 400; - margin-top: .25rem; - color: #6c757d !important; + display: block; + font-size: 80%; + font-weight: 400; + margin-top: .25rem; + color: #6c757d !important; } + /* Manage > Content */ td.child { - padding-left: 30px; + padding-left: 30px; } + /* Manage > New Content */ #jseditor { - background: #fff; - padding: 10px 5% !important; - font-size: 16px; - line-height: 1.5em; - border: 1px solid #ced4da; + background: #fff; + padding: 10px 5% !important; + font-size: 16px; + line-height: 1.5em; + border: 1px solid #ced4da; } #jseditorSidebar { - display: none; - height: calc(100% - 45px); - width: 50%; - max-width: 350px; - position: absolute; - z-index: 50; - top: 45px; - right: 15px; - background-color: #fff; - overflow-x: hidden; - transition: 0.5s; - border-left: 1px solid #ccc; - border-right: 1px solid #ccc; - border-top: 1px solid #ccc; + display: none; + height: calc(100% - 45px); + width: 50%; + max-width: 350px; + position: absolute; + z-index: 50; + top: 45px; + right: 15px; + background-color: #fff; + overflow-x: hidden; + transition: 0.5s; + border-left: 1px solid #ccc; + border-right: 1px solid #ccc; + border-top: 1px solid #ccc; } @media (max-width: 575.98px) { - #jseditorSidebar { - width: 100%; - max-width: 100%; - right: 0; - } - #editorToolbarRight button { - font-size: 0px !important; - } - #editorToolbarRight button span { - font-size: 16px !important; - } - .contentTools .btn { - font-size: 0px !important; - margin-right: 5px; - } - .contentTools .btn span { - font-size: 16px !important; - } + #jseditorSidebar { + width: 100%; + max-width: 100%; + right: 0; + } + #editorToolbarRight button { + font-size: 0px !important; + } + #editorToolbarRight button span { + font-size: 16px !important; + } + .contentTools .btn { + font-size: 0px !important; + margin-right: 5px; + } + .contentTools .btn span { + font-size: 16px !important; + } } #jseditorSidebar nav { - background: #f3f3f3; + background: #f3f3f3; } #jseditorSidebar nav a { - color: #000; + color: #000; } #jseditorSidebar .nav-tabs .nav-link { - border: none; + border: none; } #jseditorSidebar .nav-link.active { - background: none; - border: none; - border-bottom: 3px solid #ccc; + background: none; + border: none; + border-bottom: 3px solid #ccc; } #jsshadow { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: rgba(72,72,72,0.7); - z-index: 10; - display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(72, 72, 72, 0.7); + z-index: 10; + display: none; } img.profilePicture { - width: 30px; - height: 30px; - border-radius: 30px; - border: 1px solid #ccc; + width: 30px; + height: 30px; + border-radius: 30px; + border: 1px solid #ccc; } + /* Switch button */ + .switch-button { - font-size: 0.9em; - text-transform: uppercase; - cursor: pointer; + font-size: 0.9em; + text-transform: uppercase; + cursor: pointer; } .switch-icon-published { - color: #1cb11c; + color: #1cb11c; } .switch-icon-draft { - color: #b11c1c; + color: #b11c1c; } .switch-icon-unlisted, .switch-icon-static, .switch-icon-sticky { - color: #1c81b1; + color: #1c81b1; } \ No newline at end of file diff --git a/bl-kernel/admin/themes/booty/index.php b/bl-kernel/admin/themes/booty/index.php index d8adf596..8a756a41 100644 --- a/bl-kernel/admin/themes/booty/index.php +++ b/bl-kernel/admin/themes/booty/index.php @@ -20,9 +20,10 @@ ), DOMAIN_ADMIN_THEME_CSS); echo Theme::css(array( 'jquery.datetimepicker.min.css', + 'jquery-ui.min.css', 'select2.min.css', 'select2-bootstrap4.min.css', - 'token-autocomplete.css' + 'tagsinput-revisited.min.css' ), DOMAIN_CORE_CSS); ?> @@ -33,8 +34,9 @@ echo Theme::jsSortable(); echo Theme::js(array( 'jquery.datetimepicker.full.min.js', + 'jquery-ui.min.js', 'select2.full.min.js', - 'token-autocomplete.js', + 'tagsinput-revisited.min.js', 'functions.js', 'api.js' ), DOMAIN_CORE_JS, null); diff --git a/bl-kernel/admin/views/content.php b/bl-kernel/admin/views/content.php index 4922d6cf..18d5cc66 100644 --- a/bl-kernel/admin/views/content.php +++ b/bl-kernel/admin/views/content.php @@ -15,7 +15,7 @@ function table($type) { if ($type=='published') { $list = $published; if (empty($list)) { - echo '<p class="mt-4 text-muted">'; + echo '<p class="text-muted p-4">'; echo $L->g('There are no pages at this moment.'); echo '</p>'; return false; @@ -23,7 +23,7 @@ function table($type) { } elseif ($type=='draft') { $list = $drafts; if (empty($list)) { - echo '<p class="mt-4 text-muted">'; + echo '<p class="text-muted p-4">'; echo $L->g('There are no draft pages at this moment.'); echo '</p>'; return false; @@ -31,7 +31,7 @@ function table($type) { } elseif ($type=='scheduled') { $list = $scheduled; if (empty($list)) { - echo '<p class="mt-4 text-muted">'; + echo '<p class="text-muted p-4">'; echo $L->g('There are no scheduled pages at this moment.'); echo '</p>'; return false; @@ -39,7 +39,7 @@ function table($type) { } elseif ($type=='static') { $list = $static; if (empty($list)) { - echo '<p class="mt-4 text-muted">'; + echo '<p class="text-muted p-4">'; echo $L->g('There are no static pages at this moment.'); echo '</p>'; return false; @@ -47,7 +47,7 @@ function table($type) { } elseif ($type=='sticky') { $list = $sticky; if (empty($list)) { - echo '<p class="mt-4 text-muted">'; + echo '<p class="text-muted p-4">'; echo $L->g('There are no sticky pages at this moment.'); echo '</p>'; return false; @@ -56,22 +56,7 @@ function table($type) { $list = $autosave; } - echo ' - <table class="table mt-3"> - <thead> - <tr> - <th class="border-0" scope="col">'.$L->g('Title').'</th> - '; - - if ($type=='published' || $type=='static' || $type=='sticky') { - echo '<th class="border-0 d-none d-lg-table-cell" scope="col">'.$L->g('URL').'</th>'; - } - - echo ' <th class="border-0 text-center d-sm-table-cell" scope="col">'.$L->g('Actions').'</th> - </tr> - </thead> - <tbody> - '; + echo '<table class="table table-striped m-0"><tbody><tr></tr>'; if ( (ORDER_BY=='position') || $type=='static' ) { foreach ($list as $pageKey) { @@ -156,10 +141,7 @@ function table($type) { </div> </td>'; - if ($type=='published' || $type=='static' || $type=='sticky') { - $friendlyURL = Text::isEmpty($url->filters('page')) ? '/'.$page->key() : '/'.$url->filters('page').'/'.$page->key(); - echo '<td class="pt-3 d-none d-lg-table-cell"><a target="_blank" href="'.$page->permalink().'">'.$friendlyURL.'</a></td>'; - } + echo '<td class="pt-3 d-none d-lg-table-cell">'.$L->get('Category').': '.($page->category()?$page->category():$L->get('uncategorized')).'</td>'; echo '<td class="contentTools pt-3 text-center d-sm-table-cell">'.PHP_EOL; if ($type=='published' || $type=='static' || $type=='sticky') { @@ -187,7 +169,7 @@ function table($type) { ?> <!-- TABS --> -<ul class="nav nav-tabs" role="tablist"> +<ul class="nav nav-tabs pl-3" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="pages-tab" data-toggle="tab" href="#pages" role="tab"><?php $L->p('Pages') ?></a> </li> @@ -217,7 +199,7 @@ function table($type) { <?php if (Paginator::numberOfPages() > 1): ?> <!-- Paginator --> - <nav class="paginator"> + <nav class="paginator pt-3"> <ul class="pagination flex-wrap justify-content-center"> <!-- First button --> diff --git a/bl-kernel/admin/views/new-content.php b/bl-kernel/admin/views/new-content.php index fb5710e1..17dfeffc 100644 --- a/bl-kernel/admin/views/new-content.php +++ b/bl-kernel/admin/views/new-content.php @@ -17,9 +17,9 @@ if (typeof editorGetContent != 'function') { return $('#editor').val(); }; } -if (typeof editorInsertMedia != 'function') { - window.editorInsertMedia = function(filename){ - $('#editor').val($('#editor').val()+'<img src="'+filename+'" alt="">'); +if (typeof editorInsertContent != 'function') { + window.editorInsertContent = function(html){ + $('#editor').val($('#editor').val()+html); }; } @@ -57,7 +57,7 @@ function save(args) { } // Open the modal and store the current value -// The current value is store to recover it if the user click in the button "Cancel" +// The current value is store to recover it if the user click on the button "Cancel" function openModal(fieldName) { var value = $('#'+fieldName).val(); localStorage.setItem(fieldName, value); @@ -76,7 +76,7 @@ function closeModal(fieldName) { // Provides Shortcuts // The editor plugin need to call this function for the event "keydown" function keypress(event) { - console.log(event); + logs(event); // Shortcuts // ------------------------------------------------------------------------ @@ -84,7 +84,9 @@ function keypress(event) { if ((event.ctrlKey || event.metaKey) && event.which == 83) { var args = { title: $('#title').val(), - content: editorGetContent() + content: editorGetContent(), + category: $('#category option:selected').val(), + tags: $('#tags').val() } save(args); $('#btnSave').addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>'); @@ -109,7 +111,9 @@ $(document).ready(function() { $('#btnSave').on('click', function() { var args = { title: $('#title').val(), - content: editorGetContent() + content: editorGetContent(), + category: $('#category option:selected').val(), + tags: $('#tags').val() } save(args); $(this).addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>'); @@ -168,7 +172,7 @@ $(document).ready(function() { }); $('#btnCancelFriendlyURL').on('click', function() { - closeModal('FriendlyURL'); + closeModal('friendlyURL'); }); $('#btnGenURLFromTitle').on('click', function() { @@ -207,6 +211,19 @@ $(document).ready(function() { closeModal('status'); }); + // Modal SEO events + // ------------------------------------------------------------------------ + $('#btnSaveSeo').on('click', function() { + var args = { + parent: $('#parent').val() + }; + save(args); + }); + + $('#btnCancelSeo').on('click', function() { + closeModal('parent'); + }); + // Modal parent events // ------------------------------------------------------------------------ $('#btnSaveParent').on('click', function() { @@ -319,8 +336,8 @@ $(document).ready(function() { </div> </div> <div class="modal-footer modal-footer pl-2 pr-2 pt-1 pb-1"> - <button id="btnCancelfriendlyURL" type="button" class="btn btn-cancel font-weight-bold mr-auto"><i class="fa fa-times"></i> Cancel</button> - <button id="btnSavefriendlyURL" type="button" class="btn btn-save font-weight-bold"><i class="fa fa-check"></i> Save</button> + <button id="btnCancelFriendlyURL" type="button" class="btn btn-cancel font-weight-bold mr-auto"><i class="fa fa-times"></i> Cancel</button> + <button id="btnSaveFriendlyURL" type="button" class="btn btn-save font-weight-bold"><i class="fa fa-check"></i> Save</button> </div> </div> </div> @@ -449,8 +466,8 @@ $(document).ready(function() { </div> </div> <div class="modal-footer modal-footer pl-2 pr-2 pt-1 pb-1"> - <button type="button" class="btn btn-cancel font-weight-bold mr-auto" data-dismiss="modal"><i class="fa fa-times"></i> Cancel</button> - <button type="button" class="btn btn-save font-weight-bold"><i class="fa fa-check"></i> Save</button> + <button id="btnCancelSeo" type="button" class="btn btn-cancel font-weight-bold mr-auto" data-dismiss="modal"><i class="fa fa-times"></i> Cancel</button> + <button id="btnSaveSeo" type="button" class="btn btn-save font-weight-bold"><i class="fa fa-check"></i> Save</button> </div> </div> </div> @@ -520,23 +537,23 @@ $(document).ready(function() { <!-- Tags --> <h6 class="mt-4 mb-2 pb-2 text-uppercase">Tags</h6> - <div id="tags"></div> + <input id="tags" name="tags" type="text" value=""> <script> $(document).ready(function() { - let tokenAutocomplete = new TokenAutocomplete({ - name: 'tags', - selector: '#tags', - noMatchesText: 'No matching results...', - minCharactersForSuggestion: 2, - initialSuggestions: [ - <?php - foreach ($tags->db as $key=>$fields) { - echo '{value: "'.$key.'", text: "'.$fields['name'].'"},'; - } - ?> - ] + $('#tags').tagsInput({ + placeholder:'Add a tag', + delimiter:',', + removeWithBackspace:true, + 'autocomplete': { + source: [ + <?php + foreach ($tags->db as $key=>$fields) { + echo '"'.$fields['name'].'",'; + } + ?> + ] + } }); - tokenAutocomplete.debug(true); }); </script> <!-- End Tags --> diff --git a/bl-kernel/admin/views/settings copy.php b/bl-kernel/admin/views/settings copy.php new file mode 100644 index 00000000..41874245 --- /dev/null +++ b/bl-kernel/admin/views/settings copy.php @@ -0,0 +1,568 @@ +<?php defined('BLUDIT') or die('Bludit CMS.'); ?> + +<div class="align-middle"> + <div class="float-right mt-1"> + <button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button> + <a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>" role="button"><?php $L->p('Cancel') ?></a> + </div> + <?php echo Bootstrap::pageTitle(array('title'=>$L->g('Settings'), 'icon'=>'cog')); ?> +</div> + +<!-- Tabs --> +<nav> + <div class="nav nav-tabs pl-3" id="nav-tab" role="tablist"> + <a class="nav-item nav-link active" id="nav-general-tab" data-toggle="tab" href="#general" role="tab" aria-controls="nav-general" aria-selected="false"><?php $L->p('General') ?></a> + <a class="nav-item nav-link" id="nav-advanced-tab" data-toggle="tab" href="#advanced" role="tab" aria-controls="nav-advanced" aria-selected="false"><?php $L->p('Advanced') ?></a> + <a class="nav-item nav-link" id="nav-seo-tab" data-toggle="tab" href="#seo" role="tab" aria-controls="nav-seo" aria-selected="false"><?php $L->p('SEO') ?></a> + <a class="nav-item nav-link" id="nav-social-tab" data-toggle="tab" href="#social" role="tab" aria-controls="nav-social" aria-selected="false"><?php $L->p('Social Networks') ?></a> + <a class="nav-item nav-link" id="nav-images-tab" data-toggle="tab" href="#images" role="tab" aria-controls="nav-images" aria-selected="false"><?php $L->p('Images') ?></a> + <a class="nav-item nav-link" id="nav-language-tab" data-toggle="tab" href="#language" role="tab" aria-controls="nav-language" aria-selected="false"><?php $L->p('Language') ?></a> + <a class="nav-item nav-link" id="nav-custom-fields-tab" data-toggle="tab" href="#custom-fields" role="tab" aria-controls="nav-custom-fields" aria-selected="false"><?php $L->p('Custom fields') ?></a> + <a class="nav-item nav-link" id="nav-logo-tab" data-toggle="tab" href="#logo" role="tab" aria-controls="nav-logo" aria-selected="false"><?php $L->p('Logo') ?></a> + </div> +</nav> +<!-- End Tabs --> + +<div class="tab-content" id="myTabContent"> + + <!-- General tab --> + <div class="tab-pane fade show active pt-1 pb-1 pl-3 pr-3" id="general" role="tabpanel" aria-labelledby="general-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Site'))); + + echo Bootstrap::formInputText(array( + 'name'=>'title', + 'label'=>$L->g('Site title'), + 'value'=>$site->title(), + 'tip'=>$L->g('use-this-field-to-name-your-site') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'slogan', + 'label'=>$L->g('Site slogan'), + 'value'=>$site->slogan(), + 'tip'=>$L->g('use-this-field-to-add-a-catchy-phrase') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'description', + 'label'=>$L->g('Site description'), + 'value'=>$site->description(), + 'tip'=>$L->g('you-can-add-a-site-description-to-provide') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'footer', + 'label'=>$L->g('Footer text'), + 'value'=>$site->footer(), + 'tip'=>$L->g('you-can-add-a-small-text-on-the-bottom') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Content'))); + + echo Bootstrap::formSelect(array( + 'name'=>'itemsPerPage', + 'label'=>$L->g('Items per page'), + 'options'=>array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6','7'=>'7','8'=>'8', '-1'=>$L->g('All content')), + 'selected'=>$site->itemsPerPage(), + 'tip'=>$L->g('Number of items to show per page') + )); + + echo Bootstrap::formSelect(array( + 'name'=>'orderBy', + 'label'=>$L->g('Order content by'), + 'options'=>array('date'=>$L->g('Date'),'position'=>$L->g('Position')), + 'selected'=>$site->orderBy(), + 'tip'=>$L->g('order-the-content-by-date-to-build-a-blog') + )); + ?> + </div> + <!-- End General tab --> + + <!-- Advanced tab --> + <div class="tab-pane fade pt-1 pb-1 pl-3 pr-3" id="advanced" role="tabpanel" aria-labelledby="advanced-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Page content'))); + + echo Bootstrap::formSelect(array( + 'name'=>'markdownParser', + 'label'=>$L->g('Markdown parser'), + 'options'=>array('true'=>$L->g('Enabled'), 'false'=>$L->g('Disabled')), + 'selected'=>($site->markdownParser()?'true':'false'), + 'tip'=>$L->g('Enable the markdown parser for the content of the page.') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Predefined pages'))); + + // Homepage + try { + $options = array(); + $homeKey = $site->homepage(); + if (!empty($homeKey)) { + $home = new Page($homeKey); + $options = array($homeKey=>$home->title()); + } + } catch (Exception $e) { + // continue + } + echo Bootstrap::formSelect(array( + 'name'=>'homepage', + 'label'=>$L->g('Homepage'), + 'options'=>$options, + 'selected'=>false, + 'class'=>'', + 'tip'=>$L->g('Returning page for the main page') + )); + ?> + <script> + $(document).ready(function() { + var homepage = $("#jshomepage").select2({ + placeholder: "<?php $L->p('Start typing to see a list of suggestions.') ?>", + allowClear: true, + theme: "bootstrap4", + minimumInputLength: 2, + ajax: { + url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", + data: function (params) { + var query = { query: params.term } + return query; + }, + processResults: function (data) { + return data; + } + }, + escapeMarkup: function(markup) { + return markup; + } + }); + }); + </script> + + <?php + // Page not found 404 + try { + $options = array(); + $pageNotFoundKey = $site->pageNotFound(); + if (!empty($pageNotFoundKey)) { + $pageNotFound = new Page($pageNotFoundKey); + $options = array($pageNotFoundKey=>$pageNotFound->title()); + } + } catch (Exception $e) { + // continue + } + echo Bootstrap::formSelect(array( + 'name'=>'pageNotFound', + 'label'=>$L->g('Page not found'), + 'options'=>$options, + 'selected'=>false, + 'class'=>'', + 'tip'=>$L->g('Returning page when the page doesnt exist') + )); + ?> + + <script> + $(document).ready(function() { + var homepage = $("#jspageNotFound").select2({ + placeholder: "<?php $L->p('Start typing to see a list of suggestions.') ?>", + allowClear: true, + theme: "bootstrap4", + minimumInputLength: 2, + ajax: { + url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", + data: function (params) { + var query = { query: params.term } + return query; + }, + processResults: function (data) { + return data; + } + }, + escapeMarkup: function(markup) { + return markup; + } + }); + }); + </script> + + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Email account settings'))); + + echo Bootstrap::formInputText(array( + 'name'=>'emailFrom', + 'label'=>$L->g('Sender email'), + 'value'=>$site->emailFrom(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Emails will be sent from this address') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Autosave'))); + + echo Bootstrap::formInputText(array( + 'name'=>'autosaveInterval', + 'label'=>$L->g('Interval'), + 'value'=>$site->autosaveInterval(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Number in minutes for every execution of autosave') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Site URL'))); + + echo Bootstrap::formInputText(array( + 'name'=>'url', + 'label'=>'URL', + 'value'=>$site->url(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('full-url-of-your-site'), + 'placeholder'=>'https://' + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('URL Filters'))); + + echo Bootstrap::formInputText(array( + 'name'=>'uriPage', + 'label'=>$L->g('Pages'), + 'value'=>$site->uriFilters('page'), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>DOMAIN_PAGES + )); + + echo Bootstrap::formInputText(array( + 'name'=>'uriTag', + 'label'=>$L->g('Tags'), + 'value'=>$site->uriFilters('tag'), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>DOMAIN_TAGS + )); + + echo Bootstrap::formInputText(array( + 'name'=>'uriCategory', + 'label'=>$L->g('Category'), + 'value'=>$site->uriFilters('category'), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>DOMAIN_CATEGORIES + )); + + echo Bootstrap::formInputText(array( + 'name'=>'uriBlog', + 'label'=>$L->g('Blog'), + 'value'=>$site->uriFilters('blog'), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>DOMAIN.$site->uriFilters('blog'), + 'disabled'=>Text::isEmpty($site->uriFilters('blog')) + )); + ?> + </div> + + <!-- SEO tab --> + <div class="tab-pane fade" id="seo" role="tabpanel" aria-labelledby="seo-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Extreme friendly URL'))); + + echo Bootstrap::formSelect(array( + 'name'=>'extremeFriendly', + 'label'=>$L->g('Allow Unicode'), + 'options'=>array('true'=>$L->g('Enabled'), 'false'=>$L->g('Disabled')), + 'selected'=>($site->extremeFriendly()?'true':'false'), + 'class'=>'', + 'tip'=>$L->g('Allow unicode characters in the URL and some part of the system.') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Title formats'))); + + echo Bootstrap::formInputText(array( + 'name'=>'titleFormatHomepage', + 'label'=>$L->g('Homepage'), + 'value'=>$site->titleFormatHomepage(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Variables allowed').' <code>{{site-title}}</code> <code>{{site-slogan}}</code> <code>{{site-description}}</code>', + 'placeholder'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'titleFormatPages', + 'label'=>$L->g('Pages'), + 'value'=>$site->titleFormatPages(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Variables allowed').' <code>{{page-title}}</code> <code>{{page-description}}</code> <code>{{site-title}}</code> <code>{{site-slogan}}</code> <code>{{site-description}}</code>', + 'placeholder'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'titleFormatCategory', + 'label'=>$L->g('Category'), + 'value'=>$site->titleFormatCategory(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Variables allowed').' <code>{{category-name}}</code> <code>{{site-title}}</code> <code>{{site-slogan}}</code> <code>{{site-description}}</code>', + 'placeholder'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'titleFormatTag', + 'label'=>$L->g('Tag'), + 'value'=>$site->titleFormatTag(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Variables allowed').' <code>{{tag-name}}</code> <code>{{site-title}}</code> <code>{{site-slogan}}</code> <code>{{site-description}}</code>', + 'placeholder'=>'' + )); + ?> + </div> + + <!-- Social Network tab --> + <div class="tab-pane fade" id="social" role="tabpanel" aria-labelledby="social-tab"> + <?php + echo Bootstrap::formInputText(array( + 'name'=>'twitter', + 'label'=>'Twitter', + 'value'=>$site->twitter(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'facebook', + 'label'=>'Facebook', + 'value'=>$site->facebook(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'codepen', + 'label'=>'CodePen', + 'value'=>$site->codepen(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'instagram', + 'label'=>'Instagram', + 'value'=>$site->instagram(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'gitlab', + 'label'=>'GitLab', + 'value'=>$site->gitlab(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'github', + 'label'=>'GitHub', + 'value'=>$site->github(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'linkedin', + 'label'=>'LinkedIn', + 'value'=>$site->linkedin(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'xing', + 'label'=>'Xing', + 'value'=>$site->xing(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'mastodon', + 'label'=>'Mastodon', + 'value'=>$site->mastodon(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'dribbble', + 'label'=>'Dribbble', + 'value'=>$site->dribbble(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + + echo Bootstrap::formInputText(array( + 'name'=>'vk', + 'label'=>'VK', + 'value'=>$site->vk(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>'' + )); + ?> + </div> + + <!-- Images tab --> + <div class="tab-pane fade" id="images" role="tabpanel" aria-labelledby="images-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Thumbnails'))); + + echo Bootstrap::formInputText(array( + 'name'=>'thumbnailWidth', + 'label'=>$L->g('Width'), + 'value'=>$site->thumbnailWidth(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Thumbnail width in pixels') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'thumbnailHeight', + 'label'=>$L->g('Height'), + 'value'=>$site->thumbnailHeight(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Thumbnail height in pixels') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'thumbnailQuality', + 'label'=>$L->g('Quality'), + 'value'=>$site->thumbnailQuality(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Thumbnail quality in percentage') + )); + ?> + </div> + + <!-- Timezone and language tab --> + <div class="tab-pane fade" id="language" role="tabpanel" aria-labelledby="language-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Language and timezone'))); + + echo Bootstrap::formSelect(array( + 'name'=>'language', + 'label'=>$L->g('Language'), + 'options'=>$L->getLanguageList(), + 'selected'=>$site->language(), + 'class'=>'', + 'tip'=>$L->g('select-your-sites-language') + )); + + echo Bootstrap::formSelect(array( + 'name'=>'timezone', + 'label'=>$L->g('Timezone'), + 'options'=>Date::timezoneList(), + 'selected'=>$site->timezone(), + 'class'=>'', + 'tip'=>$L->g('select-a-timezone-for-a-correct') + )); + + echo Bootstrap::formInputText(array( + 'name'=>'locale', + 'label'=>$L->g('Locale'), + 'value'=>$site->locale(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('with-the-locales-you-can-set-the-regional-user-interface') + )); + + echo Bootstrap::formTitle(array('title'=>$L->g('Date and time formats'))); + + echo Bootstrap::formInputText(array( + 'name'=>'dateFormat', + 'label'=>$L->g('Date format'), + 'value'=>$site->dateFormat(), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('Current format').': '.Date::current($site->dateFormat()) + )); + ?> + </div> + + <!-- Custom fields --> + <div class="tab-pane fade" id="custom-fields" role="tabpanel" aria-labelledby="custom-fields-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Custom fields'))); + + echo Bootstrap::formTextarea(array( + 'name'=>'customFields', + 'label'=>'JSON Format', + 'value'=>json_encode($site->customFields(), JSON_PRETTY_PRINT), + 'class'=>'', + 'placeholder'=>'', + 'tip'=>$L->g('define-custom-fields-for-the-content'), + 'rows'=>15 + )); + ?> + </div> + + <!-- Site logo tab --> + <div class="tab-pane fade" id="logo" role="tabpanel" aria-labelledby="logo-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Site logo'))); + ?> + + <div class="container"> + <div class="row"> + <div class="col-lg-4 col-sm-12 p-0 pr-2"> + <div class="custom-file"> + <input id="jssiteLogoInputFile" class="custom-file-input" type="file" name="inputFile"> + <label for="jssiteLogoInputFile" class="custom-file-label"><?php $L->p('Upload image'); ?></label> + </div> + <button id="jsbuttonRemoveLogo" type="button" class="btn btn-primary w-100 mt-4 mb-4"><i class="fa fa-trash"></i><?php $L->p('Remove logo') ?></button> + </div> + <div class="col-lg-8 col-sm-12 p-0 text-center"> + <img id="jssiteLogoPreview" class="img-fluid img-thumbnail" alt="Site logo preview" src="<?php echo ($site->logo()?DOMAIN_UPLOADS.$site->logo(false).'?version='.time():HTML_PATH_CORE_IMG.'default.svg') ?>" /> + </div> + </div> + </div> + <script> + $("#jsbuttonRemoveLogo").on("click", function() { + bluditAjax.removeLogo(); + $("#jssiteLogoPreview").attr("src", "<?php echo HTML_PATH_CORE_IMG.'default.svg' ?>"); + }); + + $("#jssiteLogoInputFile").on("change", function() { + var formData = new FormData(); + formData.append('tokenCSRF', tokenCSRF); + formData.append('inputFile', $(this)[0].files[0]); + $.ajax({ + url: HTML_PATH_ADMIN_ROOT+"ajax/logo-upload", + type: "POST", + data: formData, + cache: false, + contentType: false, + processData: false + }).done(function(data) { + if (data.status==0) { + $("#jssiteLogoPreview").attr('src',data.absoluteURL+"?time="+Math.random()); + } else { + showAlert(data.message); + } + }); + }); + </script> + </div> + diff --git a/bl-kernel/admin/views/settings.php b/bl-kernel/admin/views/settings.php index b0ff9031..0bbb795f 100644 --- a/bl-kernel/admin/views/settings.php +++ b/bl-kernel/admin/views/settings.php @@ -1,18 +1,96 @@ <?php defined('BLUDIT') or die('Bludit CMS.'); ?> -<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?> +<script> +// ============================================================================ +// Variables for the view +// ============================================================================ + +// ============================================================================ +// Functions for the view +// ============================================================================ + +// This function catch all key press +// Provide shortcuts for the view +function keypress(event) { + logs(event); + + // Shortcuts + // ------------------------------------------------------------------------ + // Ctrl+S or Command+S + if ((event.ctrlKey || event.metaKey) && event.which == 83) { + save(); + $('#btnSave').addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>'); + event.preventDefault(); + return false; + } + + $('#btnSave').removeClass('btn-primary-disabled').html('<?php $L->p('Save') ?>'); + return true; +} + +function save() { + var args = {} + + // Get values from all inputs['text'] + $('input[type=text]').each(function(){ + var key = $(this).attr('name'); + var value = $(this).val(); + args[key] = value; + }); + + // Get values from all selects + $('select').each(function() { + var key = $(this).attr('name'); + var value = $(this).val(); + args[key] = value; + }); + + logs('Saving settings'); + api.saveSettings(args).then(function() { + logs('Settings saved'); + }); + + return true; +} + +// ============================================================================ +// Events for the view +// ============================================================================ +$(document).ready(function() { + + // Main interface events + // ------------------------------------------------------------------------ + $(this).keydown(function(event){ + keypress(event); + }); + + $('#btnSave').on('click', function() { + save(); + $(this).addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>'); + }); + +}); + +// ============================================================================ +// Initlization for the view +// ============================================================================ +$(document).ready(function() { + // nothing here yet + // how do you hang your toilet paper ? over or under ? +}); +</script> <div class="align-middle"> <div class="float-right mt-1"> - <button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button> + <button type="button" class="btn btn-primary btn-sm btn-primary-disabled" id="btnSave"><?php $L->p('Saved') ?></button> <a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>" role="button"><?php $L->p('Cancel') ?></a> </div> <?php echo Bootstrap::pageTitle(array('title'=>$L->g('Settings'), 'icon'=>'cog')); ?> </div> -<!-- TABS --> -<nav class="mb-3"> - <div class="nav nav-tabs" id="nav-tab" role="tablist"> +<!-- Tabs --> +<nav> + <div class="nav nav-tabs pl-3" id="nav-tab" role="tablist"> <a class="nav-item nav-link active" id="nav-general-tab" data-toggle="tab" href="#general" role="tab" aria-controls="nav-general" aria-selected="false"><?php $L->p('General') ?></a> <a class="nav-item nav-link" id="nav-advanced-tab" data-toggle="tab" href="#advanced" role="tab" aria-controls="nav-advanced" aria-selected="false"><?php $L->p('Advanced') ?></a> <a class="nav-item nav-link" id="nav-seo-tab" data-toggle="tab" href="#seo" role="tab" aria-controls="nav-seo" aria-selected="false"><?php $L->p('SEO') ?></a> @@ -23,18 +101,12 @@ <a class="nav-item nav-link" id="nav-logo-tab" data-toggle="tab" href="#logo" role="tab" aria-controls="nav-logo" aria-selected="false"><?php $L->p('Logo') ?></a> </div> </nav> +<!-- End Tabs --> -<?php - // Token CSRF - echo Bootstrap::formInputHidden(array( - 'name'=>'tokenCSRF', - 'value'=>$security->getTokenCSRF() - )); -?> +<div class="tab-content" id="myTabContent"> <!-- General tab --> - <div class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-tab"> - + <div class="tab-pane show active pt-1 pb-1 pl-3 pr-3" id="general" role="tabpanel" aria-labelledby="general-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Site'))); @@ -42,8 +114,6 @@ 'name'=>'title', 'label'=>$L->g('Site title'), 'value'=>$site->title(), - 'class'=>'', - 'placeholder'=>'', 'tip'=>$L->g('use-this-field-to-name-your-site') )); @@ -51,8 +121,6 @@ 'name'=>'slogan', 'label'=>$L->g('Site slogan'), 'value'=>$site->slogan(), - 'class'=>'', - 'placeholder'=>'', 'tip'=>$L->g('use-this-field-to-add-a-catchy-phrase') )); @@ -60,8 +128,6 @@ 'name'=>'description', 'label'=>$L->g('Site description'), 'value'=>$site->description(), - 'class'=>'', - 'placeholder'=>'', 'tip'=>$L->g('you-can-add-a-site-description-to-provide') )); @@ -69,16 +135,9 @@ 'name'=>'footer', 'label'=>$L->g('Footer text'), 'value'=>$site->footer(), - 'class'=>'', - 'placeholder'=>'', 'tip'=>$L->g('you-can-add-a-small-text-on-the-bottom') )); - ?> - </div> - <!-- Advanced tab --> - <div class="tab-pane fade" id="advanced" role="tabpanel" aria-labelledby="advanced-tab"> - <?php echo Bootstrap::formTitle(array('title'=>$L->g('Content'))); echo Bootstrap::formSelect(array( @@ -86,7 +145,6 @@ 'label'=>$L->g('Items per page'), 'options'=>array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6','7'=>'7','8'=>'8', '-1'=>$L->g('All content')), 'selected'=>$site->itemsPerPage(), - 'class'=>'', 'tip'=>$L->g('Number of items to show per page') )); @@ -95,23 +153,27 @@ 'label'=>$L->g('Order content by'), 'options'=>array('date'=>$L->g('Date'),'position'=>$L->g('Position')), 'selected'=>$site->orderBy(), - 'class'=>'', 'tip'=>$L->g('order-the-content-by-date-to-build-a-blog') )); + ?> + </div> + <!-- End General tab --> + + <!-- Advanced tab --> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="advanced" role="tabpanel" aria-labelledby="advanced-tab"> + <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Page content'))); + + echo Bootstrap::formSelect(array( + 'name'=>'markdownParser', + 'label'=>$L->g('Markdown parser'), + 'options'=>array('true'=>$L->g('Enabled'), 'false'=>$L->g('Disabled')), + 'selected'=>($site->markdownParser()?'true':'false'), + 'tip'=>$L->g('Enable the markdown parser for the content of the page.') + )); echo Bootstrap::formTitle(array('title'=>$L->g('Predefined pages'))); - // Homepage - try { - $options = array(); - $homeKey = $site->homepage(); - if (!empty($homeKey)) { - $home = new Page($homeKey); - $options = array($homeKey=>$home->title()); - } - } catch (Exception $e) { - // continue - } echo Bootstrap::formSelect(array( 'name'=>'homepage', 'label'=>$L->g('Homepage'), @@ -120,43 +182,7 @@ 'class'=>'', 'tip'=>$L->g('Returning page for the main page') )); - ?> - <script> - $(document).ready(function() { - var homepage = $("#jshomepage").select2({ - placeholder: "<?php $L->p('Start typing to see a list of suggestions.') ?>", - allowClear: true, - theme: "bootstrap4", - minimumInputLength: 2, - ajax: { - url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", - data: function (params) { - var query = { query: params.term } - return query; - }, - processResults: function (data) { - return data; - } - }, - escapeMarkup: function(markup) { - return markup; - } - }); - }); - </script> - <?php - // Page not found 404 - try { - $options = array(); - $pageNotFoundKey = $site->pageNotFound(); - if (!empty($pageNotFoundKey)) { - $pageNotFound = new Page($pageNotFoundKey); - $options = array($pageNotFoundKey=>$pageNotFound->title()); - } - } catch (Exception $e) { - // continue - } echo Bootstrap::formSelect(array( 'name'=>'pageNotFound', 'label'=>$L->g('Page not found'), @@ -165,33 +191,7 @@ 'class'=>'', 'tip'=>$L->g('Returning page when the page doesnt exist') )); - ?> - <script> - $(document).ready(function() { - var homepage = $("#jspageNotFound").select2({ - placeholder: "<?php $L->p('Start typing to see a list of suggestions.') ?>", - allowClear: true, - theme: "bootstrap4", - minimumInputLength: 2, - ajax: { - url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", - data: function (params) { - var query = { query: params.term } - return query; - }, - processResults: function (data) { - return data; - } - }, - escapeMarkup: function(markup) { - return markup; - } - }); - }); - </script> - - <?php echo Bootstrap::formTitle(array('title'=>$L->g('Email account settings'))); echo Bootstrap::formInputText(array( @@ -226,17 +226,6 @@ 'placeholder'=>'https://' )); - echo Bootstrap::formTitle(array('title'=>$L->g('Page content'))); - - echo Bootstrap::formSelect(array( - 'name'=>'markdownParser', - 'label'=>$L->g('Markdown parser'), - 'options'=>array('true'=>$L->g('Enabled'), 'false'=>$L->g('Disabled')), - 'selected'=>($site->markdownParser()?'true':'false'), - 'class'=>'', - 'tip'=>$L->g('Enable the markdown parser for the content of the page.') - )); - echo Bootstrap::formTitle(array('title'=>$L->g('URL Filters'))); echo Bootstrap::formInputText(array( @@ -279,7 +268,7 @@ </div> <!-- SEO tab --> - <div class="tab-pane fade" id="seo" role="tabpanel" aria-labelledby="seo-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="seo" role="tabpanel" aria-labelledby="seo-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Extreme friendly URL'))); @@ -337,8 +326,10 @@ </div> <!-- Social Network tab --> - <div class="tab-pane fade" id="social" role="tabpanel" aria-labelledby="social-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="social" role="tabpanel" aria-labelledby="social-tab"> <?php + echo Bootstrap::formTitle(array('title'=>$L->g('Social Networks'))); + echo Bootstrap::formInputText(array( 'name'=>'twitter', 'label'=>'Twitter', @@ -441,7 +432,7 @@ </div> <!-- Images tab --> - <div class="tab-pane fade" id="images" role="tabpanel" aria-labelledby="images-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="images" role="tabpanel" aria-labelledby="images-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Thumbnails'))); @@ -475,7 +466,7 @@ </div> <!-- Timezone and language tab --> - <div class="tab-pane fade" id="language" role="tabpanel" aria-labelledby="language-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="language" role="tabpanel" aria-labelledby="language-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Language and timezone'))); @@ -520,7 +511,7 @@ </div> <!-- Custom fields --> - <div class="tab-pane fade" id="custom-fields" role="tabpanel" aria-labelledby="custom-fields-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="custom-fields" role="tabpanel" aria-labelledby="custom-fields-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Custom fields'))); @@ -537,7 +528,7 @@ </div> <!-- Site logo tab --> - <div class="tab-pane fade" id="logo" role="tabpanel" aria-labelledby="logo-tab"> + <div class="tab-pane pt-1 pb-1 pl-3 pr-3" id="logo" role="tabpanel" aria-labelledby="logo-tab"> <?php echo Bootstrap::formTitle(array('title'=>$L->g('Site logo'))); ?> @@ -584,18 +575,3 @@ </script> </div> -<?php echo Bootstrap::formClose(); ?> - -<script> - // Open current tab after refresh page - $(function() { - $('a[data-toggle="tab"]').on('click', function(e) { - window.localStorage.setItem('activeTab', $(e.target).attr('href')); - }); - var activeTab = window.localStorage.getItem('activeTab'); - if (activeTab) { - $('#nav-tab a[href="' + activeTab + '"]').tab('show'); - //window.localStorage.removeItem("activeTab"); - } - }); -</script> diff --git a/bl-kernel/boot/init.php b/bl-kernel/boot/init.php index 6c67b67b..748e4782 100644 --- a/bl-kernel/boot/init.php +++ b/bl-kernel/boot/init.php @@ -112,6 +112,7 @@ include(PATH_HELPERS.'image.class.php'); include(PATH_HELPERS.'tcp.class.php'); include(PATH_HELPERS.'dom.class.php'); include(PATH_HELPERS.'cookie.class.php'); +include(PATH_HELPERS.'bootstrap.class.php'); if (file_exists(PATH_KERNEL.'bludit.pro.php')) { include(PATH_KERNEL.'bludit.pro.php'); diff --git a/bl-kernel/css/jquery-ui.min.css b/bl-kernel/css/jquery-ui.min.css new file mode 100644 index 00000000..4dbfe2e4 --- /dev/null +++ b/bl-kernel/css/jquery-ui.min.css @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.12.1 - 2020-11-01 +* http://jqueryui.com +* Includes: core.css, autocomplete.css, menu.css +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0} \ No newline at end of file diff --git a/bl-kernel/css/tagsinput-revisited.min.css b/bl-kernel/css/tagsinput-revisited.min.css new file mode 100644 index 00000000..8fa5c0f8 --- /dev/null +++ b/bl-kernel/css/tagsinput-revisited.min.css @@ -0,0 +1,123 @@ +.tagsinput, +.tagsinput * { + box-sizing: border-box +} + +.tagsinput { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + background: #fff; + font-family: sans-serif; + font-size: 14px; + line-height: 20px; + color: #6c757d; + padding: 5px 5px 0; + border: 1px solid #e6e6e6; + border-radius: 2px +} + +.tagsinput.focus { + border-color: #ccc +} + +.tagsinput .tag { + position: relative; + background: #6c757d; + display: block; + max-width: 100%; + word-wrap: break-word; + color: #fff; + padding: 5px 30px 5px 5px; + border-radius: 2px; + margin: 0 5px 5px 0 +} + +.tagsinput .tag .tag-remove { + position: absolute; + background: 0 0; + display: block; + width: 30px; + height: 30px; + top: 0; + right: 0; + cursor: pointer; + text-decoration: none; + text-align: center; + color: #ccc; + line-height: 30px; + padding: 0; + border: 0 +} + +.tagsinput .tag .tag-remove:after, +.tagsinput .tag .tag-remove:before { + background: #ccc; + position: absolute; + display: block; + width: 10px; + height: 2px; + top: 14px; + left: 10px; + content: '' +} + +.tagsinput .tag .tag-remove:before { + -webkit-transform: rotateZ(45deg); + transform: rotateZ(45deg) +} + +.tagsinput .tag .tag-remove:after { + -webkit-transform: rotateZ(-45deg); + transform: rotateZ(-45deg) +} + +.tagsinput div { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1 +} + +.tagsinput div input { + background: 0 0; + display: block; + width: 100%; + font-size: 14px; + line-height: 20px; + padding: 5px; + border: 0; + margin: 0 5px 5px 0 +} + +.tagsinput div input.error { + color: #ccc +} + +.tagsinput div input::-ms-clear { + display: none +} + +.tagsinput div input::-webkit-input-placeholder { + color: #ccc; + opacity: 1 +} + +.tagsinput div input:-moz-placeholder { + color: #ccc; + opacity: 1 +} + +.tagsinput div input::-moz-placeholder { + color: #ccc; + opacity: 1 +} + +.tagsinput div input:-ms-input-placeholder { + color: #ccc; + opacity: 1 +} \ No newline at end of file diff --git a/bl-kernel/functions.php b/bl-kernel/functions.php index 4cc0026e..bf136a57 100644 --- a/bl-kernel/functions.php +++ b/bl-kernel/functions.php @@ -647,8 +647,6 @@ function editSettings($args) { 'notes'=>'' )); - // Create alert - Alert::set($L->g('The changes have been saved')); return true; } diff --git a/bl-kernel/admin/themes/booty/init.php b/bl-kernel/helpers/bootstrap.class.php similarity index 96% rename from bl-kernel/admin/themes/booty/init.php rename to bl-kernel/helpers/bootstrap.class.php index 7fc78db3..5feb9dc0 100644 --- a/bl-kernel/admin/themes/booty/init.php +++ b/bl-kernel/helpers/bootstrap.class.php @@ -2,6 +2,74 @@ class Bootstrap { + public static function formInputText($args) + { + $name = $args['name']; + $id = isset($args['id'])?$args['id']:$name; + $disabled = empty($args['disabled'])?'':'disabled'; + $readonly = empty($args['readonly'])?'':'readonly'; + $placeholder = isset($args['placeholder'])?$args['placeholder']:''; + $value = isset($args['value'])?$args['value']:''; + $type = isset($args['type'])?$args['type']:'text'; + + $tip = ''; + if (isset($args['tip'])) { + $tip = '<small class="form-text text-muted">'.$args['tip'].'</small>'; + } + + $label = ''; + if (isset($args['label'])) { + $label = '<label for="'.$id.'" class="col-sm-2 col-form-label">'.$args['label'].'</label>'; + } + + $class = 'form-control'; + if (isset($args['class'])) { + $class = $class.' '.$args['class']; + } + +return <<<EOF +<div class="form-group row"> + $label + <div class="col-sm-10"> + <input class="$class" id="$id" name="$name" value="$value" placeholder="$placeholder" type="$type" $disabled $readonly> + $tip + </div> +</div> +EOF; + } + + public static function formSelect($args) + { + $name = $args['name']; + $id = isset($args['id'])?$args['id']:$name; + $value = isset($args['value'])?$args['value']:''; + + $class = 'custom-select'; + if (isset($args['class'])) { + $class = $class.' '.$args['class']; + } + + $html = '<div class="form-group row">'; + if (isset($args['label'])) { + $html .= '<label for="'.$id.'" class="col-sm-2 col-form-label">'.$args['label'].'</label>'; + } + $html .= '<div class="col-sm-10">'; + $html .= '<select id="'.$id.'" name="'.$name.'" class="'.$class.'">'; + foreach ($args['options'] as $key=>$value) { + $html .= '<option '.(($key==$args['selected'])?'selected':'').' value="'.$key.'">'.$value.'</option>'; + } + $html .= '</select>'; + if (isset($args['tip'])) { + $html .= '<small class="form-text text-muted">'.$args['tip'].'</small>'; + } + $html .= '</div>'; + $html .= '</div>'; + + return $html; + } + + + // -- OLD -------- public static function modal($args) { $buttonSecondary = $args['buttonSecondary']; @@ -221,49 +289,7 @@ EOF; return $html; } - public static function formInputText($args) - { - $name = $args['name']; - $disabled = empty($args['disabled'])?'':'disabled'; - $readonly = empty($args['readonly'])?'':'readonly'; - $placeholder = isset($args['placeholder'])?$args['placeholder']:''; - $value = isset($args['value'])?$args['value']:''; - $id = 'js'.$name; - if (isset($args['id'])) { - $id = $args['id']; - } - - $tip = ''; - if (isset($args['tip'])) { - $tip = '<small class="form-text text-muted">'.$args['tip'].'</small>'; - } - - $label = ''; - if (isset($args['label'])) { - $label = '<label for="'.$id.'" class="col-sm-2 col-form-label">'.$args['label'].'</label>'; - } - - $class = 'form-control'; - if (isset($args['class'])) { - $class = $class.' '.$args['class']; - } - - $type = 'text'; - if (isset($args['type'])) { - $type = $args['type']; - } - -return <<<EOF -<div class="form-group row"> - $label - <div class="col-sm-10"> - <input class="$class" id="$id" name="$name" value="$value" placeholder="$placeholder" type="$type" $disabled $readonly> - $tip - </div> -</div> -EOF; - } public static function formCheckbox($args) { @@ -313,38 +339,7 @@ return <<<EOF EOF; } - public static function formSelect($args) - { - $id = 'js'.$args['name']; - if (isset($args['id'])) { - $id = $args['id']; - } - $class = 'custom-select'; - if (isset($args['class'])) { - $class = $class.' '.$args['class']; - } - - $html = '<div class="form-group row">'; - - if (isset($args['label'])) { - $html .= '<label for="'.$id.'" class="col-sm-2 col-form-label">'.$args['label'].'</label>'; - } - - $html .= '<div class="col-sm-10">'; - $html .= '<select id="'.$id.'" name="'.$args['name'].'" class="'.$class.'">'; - foreach ($args['options'] as $key=>$value) { - $html .= '<option '.(($key==$args['selected'])?'selected':'').' value="'.$key.'">'.$value.'</option>'; - } - $html .= '</select>'; - if (isset($args['tip'])) { - $html .= '<small class="form-text text-muted">'.$args['tip'].'</small>'; - } - $html .= '</div>'; - $html .= '</div>'; - - return $html; - } public static function formSelectBlock($args) { diff --git a/bl-kernel/js/api.js b/bl-kernel/js/api.js index 748d7705..aeacfd1e 100644 --- a/bl-kernel/js/api.js +++ b/bl-kernel/js/api.js @@ -1,89 +1,113 @@ class API { - constructor(apiURL, apiToken, apiAuth) { - this.apiURL = "http://localhost:9000/api/"; - this.body = { - token: '45643a4071fad6a12261bb0763550feb', - authentication: '18a8410f0043d004c2e87f404170e112' - } - } + constructor(apiURL, apiToken, apiAuth) { + this.apiURL = "http://localhost:9000/api/"; + this.body = { + token: '45643a4071fad6a12261bb0763550feb', + authentication: '18a8410f0043d004c2e87f404170e112' + } + } - async createPage(args) { - var url = this.apiURL+"pages"; - var body = Object.assign({}, this.body, args); - try { - var response = await fetch(url, { - credentials: "same-origin", - method: "POST", - body: JSON.stringify(body), - headers: new Headers({ - "Content-Type": "application/json" - }) - }); - var json = await response.json(); - return json.data.key; - } - catch (err) { - console.log(err); - return true; - } - } + async createPage(args) { + var url = this.apiURL + "pages"; + var body = Object.assign({}, this.body, args); + try { + var response = await fetch(url, { + credentials: "same-origin", + method: "POST", + body: JSON.stringify(body), + headers: new Headers({ + "Content-Type": "application/json" + }) + }); + var json = await response.json(); + return json.data.key; + } catch (err) { + console.log(err); + return true; + } + } - /* - Save page fields + /* + Save page fields - $args['pageKey'] string Page key for the page to edit - $args array Arguments can be any of the fields from a page + $args['pageKey'] string Page key for the page to edit + $args array Arguments can be any of the fields from a page - returns string New page key - */ - async savePage(args) { - var url = this.apiURL+"pages/"+args['pageKey']; - var body = Object.assign({}, this.body, args); - try { - var response = await fetch(url, { - credentials: "same-origin", - method: "PUT", - body: JSON.stringify(body), - headers: new Headers({ - "Content-Type": "application/json" - }) - }); - var json = await response.json(); - return json.data.key; - } - catch (err) { - console.log(err); - return true; - } - } + returns string New page key + */ + async savePage(args) { + var url = this.apiURL + "pages/" + args['pageKey']; + var body = Object.assign({}, this.body, args); + try { + var response = await fetch(url, { + credentials: "same-origin", + method: "PUT", + body: JSON.stringify(body), + headers: new Headers({ + "Content-Type": "application/json" + }) + }); + var json = await response.json(); + return json.data.key; + } catch (err) { + console.log(err); + return true; + } + } - /* - Generates unique slug text for the a page + /* + Generates unique slug text for the a page - $args['pageKey'] string Page key for the page to generate the slug url - $args['text'] string Text that you want to generate the slug url - $args['parentKey'] string Parent page key if the page has one, if not empty string + $args['pageKey'] string Page key for the page to generate the slug url + $args['text'] string Text that you want to generate the slug url + $args['parentKey'] string Parent page key if the page has one, if not empty string - returns string Slug text - */ - async friendlyURL(args) { - var url = this.apiURL+"helper/friendly-url/"; - var parameters = "?token="+this.body.token+"&authentication="+this.body.authentication; - parameters = parameters+"&pageKey="+args['pageKey']; - parameters = parameters+"&text="+args['text']; - parameters = parameters+"&parentKey="+args['parentKey']; - try { - const response = await fetch(url+parameters, { - method: "GET" - }); - var json = await response.json(); - return json.data; - } - catch (err) { - console.log(err); - return true; - } - } + returns string Slug text + */ + async friendlyURL(args) { + var url = this.apiURL + "helper/friendly-url/"; + var parameters = "?token=" + this.body.token + "&authentication=" + this.body.authentication; + parameters = parameters + "&pageKey=" + args['pageKey']; + parameters = parameters + "&text=" + args['text']; + parameters = parameters + "&parentKey=" + args['parentKey']; + try { + const response = await fetch(url + parameters, { + method: "GET" + }); + var json = await response.json(); + return json.data; + } catch (err) { + console.log(err); + return true; + } + } -} + /* + Save settings + + $args array Arguments can be any of the fields from settings + + returns array + */ + async saveSettings(args) { + var url = this.apiURL + "settings"; + var body = Object.assign({}, this.body, args); + try { + var response = await fetch(url, { + credentials: "same-origin", + method: "PUT", + body: JSON.stringify(body), + headers: new Headers({ + "Content-Type": "application/json" + }) + }); + var json = await response.json(); + return json.data; + } catch (err) { + console.log(err); + return true; + } + } + +} \ No newline at end of file diff --git a/bl-kernel/js/jquery-ui.min.js b/bl-kernel/js/jquery-ui.min.js new file mode 100644 index 00000000..41de1ea7 --- /dev/null +++ b/bl-kernel/js/jquery-ui.min.js @@ -0,0 +1 @@ +!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(x){x.ui=x.ui||{};x.ui.version="1.12.1";var n,i=0,a=Array.prototype.slice;x.cleanData=(n=x.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)try{(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove")}catch(t){}n(t)}),x.widget=function(t,i,e){var s,n,o,l={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=x.Widget),x.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr[":"][r.toLowerCase()]=function(t){return!!x.data(t,r)},x[a]=x[a]||{},s=x[a][t],n=x[a][t]=function(t,e){if(!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},x.extend(n,s,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(o=new i).options=x.widget.extend({},o.options),x.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}x.isFunction(s)?l[e]=function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:l[e]=s}),n.prototype=x.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},l,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(x.each(s._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),x.widget.bridge(t,n),n},x.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n<o;n++)for(e in s[n])i=s[n][e],s[n].hasOwnProperty(e)&&void 0!==i&&(x.isPlainObject(i)?t[e]=x.isPlainObject(t[e])?x.widget.extend({},t[e],i):x.widget.extend({},i):t[e]=i);return t},x.widget.bridge=function(o,e){var l=e.prototype.widgetFullName||o;x.fn[o]=function(i){var t="string"==typeof i,s=a.call(arguments,1),n=this;return t?this.length||"instance"!==i?this.each(function(){var t,e=x.data(this,l);return"instance"===i?(n=e,!1):e?x.isFunction(e[i])&&"_"!==i.charAt(0)?(t=e[i].apply(e,s))!==e&&void 0!==t?(n=t&&t.jquery?n.pushStack(t.get()):t,!1):void 0:x.error("no such method '"+i+"' for "+o+" widget instance"):x.error("cannot call methods on "+o+" prior to initialization; attempted to call method '"+i+"'")}):n=void 0:(s.length&&(i=x.widget.extend.apply(null,[i].concat(s))),this.each(function(){var t=x.data(this,l);t?(t.option(i||{}),t._init&&t._init()):x.data(this,l,new e(i,this))})),n}},x.Widget=function(){},x.Widget._childConstructors=[],x.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n<i.length-1;n++)s[i[n]]=s[i[n]]||{},s=s[i[n]];if(t=i.pop(),1===arguments.length)return void 0===s[t]?null:s[t];s[t]=e}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=e}return this._setOptions(o),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(t){var e,i,s;for(e in t)s=this.classesElementLookup[e],t[e]!==this.options.classes[e]&&s&&s.length&&(i=x(s.get()),this._removeClass(s,e),i.addClass(this._classes({element:i,keys:e,classes:t,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(n){var o=[],l=this;function t(t,e){for(var i,s=0;s<t.length;s++)i=l.classesElementLookup[t[s]]||x(),i=n.add?x(x.unique(i.get().concat(n.element.get()))):x(i.not(n.element).get()),l.classesElementLookup[t[s]]=i,o.push(t[s]),e&&n.classes[t[s]]&&o.push(n.classes[t[s]])}return n=x.extend({element:this.element,classes:this.options.classes||{}},n),this._on(n.element,{remove:"_untrackClassesElement"}),n.keys&&t(n.keys.match(/\S+/g)||[],!0),n.extra&&t(n.extra.match(/\S+/g)||[]),o.join(" ")},_untrackClassesElement:function(i){var s=this;x.each(s.classesElementLookup,function(t,e){-1!==x.inArray(i.target,e)&&(s.classesElementLookup[t]=x(e.not(i.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(l,a,t){var r,u=this;"boolean"!=typeof l&&(t=a,a=l,l=!1),t?(a=r=x(a),this.bindings=this.bindings.add(a)):(t=a,a=this.element,r=this.widget()),x.each(t,function(t,e){function i(){if(l||!0!==u.options.disabled&&!x(this).hasClass("ui-state-disabled"))return("string"==typeof e?u[e]:e).apply(u,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||x.guid++);var s=t.match(/^([\w:-]*)\s*(.*)$/),n=s[1]+u.eventNamespace,o=s[2];o?r.on(n,o,i):a.on(n,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e).off(e),this.bindings=x(this.bindings.not(t).get()),this.focusable=x(this.focusable.not(t).get()),this.hoverable=x(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(x(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(x(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,n,o=this.options[t];if(i=i||{},(e=x.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],n=e.originalEvent)for(s in n)s in e||(e[s]=n[s]);return this.element.trigger(e,i),!(x.isFunction(o)&&!1===o.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},x.each({show:"fadeIn",hide:"fadeOut"},function(o,l){x.Widget.prototype["_"+o]=function(e,t,i){var s;"string"==typeof t&&(t={effect:t});var n=t?!0!==t&&"number"!=typeof t&&t.effect||l:o;"number"==typeof(t=t||{})&&(t={duration:t}),s=!x.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&x.effects&&x.effects.effect[n]?e[o](t):n!==o&&e[n]?e[n](t.duration,t.easing,i):e.queue(function(t){x(this)[o](),i&&i.call(e[0]),t()})}});var o,C,E,s,l,r,u,h,k;x.widget;function T(t,e,i){return[parseFloat(t[0])*(h.test(t[0])?e/100:1),parseFloat(t[1])*(h.test(t[1])?i/100:1)]}function W(t,e){return parseInt(x.css(t,e),10)||0}C=Math.max,E=Math.abs,s=/left|center|right/,l=/top|center|bottom/,r=/[\+\-]\d+(\.[\d]+)?%?/,u=/^\w+/,h=/%$/,k=x.fn.position,x.position={scrollbarWidth:function(){if(void 0!==o)return o;var t,e,i=x("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),s=i.children()[0];return x("body").append(i),t=s.offsetWidth,i.css("overflow","scroll"),t===(e=s.offsetWidth)&&(e=i[0].clientWidth),i.remove(),o=t-e},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),s="scroll"===e||"auto"===e&&t.width<t.element[0].scrollWidth;return{width:"scroll"===i||"auto"===i&&t.height<t.element[0].scrollHeight?x.position.scrollbarWidth():0,height:s?x.position.scrollbarWidth():0}},getWithinInfo:function(t){var e=x(t||window),i=x.isWindow(e[0]),s=!!e[0]&&9===e[0].nodeType;return{element:e,isWindow:i,isDocument:s,offset:!i&&!s?x(t).offset():{left:0,top:0},scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop(),width:e.outerWidth(),height:e.outerHeight()}}},x.fn.position=function(c){if(!c||!c.of)return k.apply(this,arguments);c=x.extend({},c);var d,f,m,p,v,t,e,g=x(c.of),_=x.position.getWithinInfo(c.within),y=x.position.getScrollInfo(_),b=(c.collision||"flip").split(" "),w={},i=9===(e=(t=g)[0]).nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:x.isWindow(e)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:e.preventDefault?{width:0,height:0,offset:{top:e.pageY,left:e.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()};return g[0].preventDefault&&(c.at="left top"),f=i.width,m=i.height,p=i.offset,v=x.extend({},p),x.each(["my","at"],function(){var t,e,i=(c[this]||"").split(" ");1===i.length&&(i=s.test(i[0])?i.concat(["center"]):l.test(i[0])?["center"].concat(i):["center","center"]),i[0]=s.test(i[0])?i[0]:"center",i[1]=l.test(i[1])?i[1]:"center",t=r.exec(i[0]),e=r.exec(i[1]),w[this]=[t?t[0]:0,e?e[0]:0],c[this]=[u.exec(i[0])[0],u.exec(i[1])[0]]}),1===b.length&&(b[1]=b[0]),"right"===c.at[0]?v.left+=f:"center"===c.at[0]&&(v.left+=f/2),"bottom"===c.at[1]?v.top+=m:"center"===c.at[1]&&(v.top+=m/2),d=T(w.at,f,m),v.left+=d[0],v.top+=d[1],this.each(function(){var i,t,l=x(this),a=l.outerWidth(),r=l.outerHeight(),e=W(this,"marginLeft"),s=W(this,"marginTop"),n=a+e+W(this,"marginRight")+y.width,o=r+s+W(this,"marginBottom")+y.height,u=x.extend({},v),h=T(w.my,l.outerWidth(),l.outerHeight());"right"===c.my[0]?u.left-=a:"center"===c.my[0]&&(u.left-=a/2),"bottom"===c.my[1]?u.top-=r:"center"===c.my[1]&&(u.top-=r/2),u.left+=h[0],u.top+=h[1],i={marginLeft:e,marginTop:s},x.each(["left","top"],function(t,e){x.ui.position[b[t]]&&x.ui.position[b[t]][e](u,{targetWidth:f,targetHeight:m,elemWidth:a,elemHeight:r,collisionPosition:i,collisionWidth:n,collisionHeight:o,offset:[d[0]+h[0],d[1]+h[1]],my:c.my,at:c.at,within:_,elem:l})}),c.using&&(t=function(t){var e=p.left-u.left,i=e+f-a,s=p.top-u.top,n=s+m-r,o={target:{element:g,left:p.left,top:p.top,width:f,height:m},element:{element:l,left:u.left,top:u.top,width:a,height:r},horizontal:i<0?"left":0<e?"right":"center",vertical:n<0?"top":0<s?"bottom":"middle"};f<a&&E(e+i)<f&&(o.horizontal="center"),m<r&&E(s+n)<m&&(o.vertical="middle"),C(E(e),E(i))>C(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,o=s.width,l=t.left-e.collisionPosition.marginLeft,a=n-l,r=l+e.collisionWidth-o-n;e.collisionWidth>o?0<a&&r<=0?(i=t.left+a+e.collisionWidth-o-n,t.left+=a-i):t.left=!(0<r&&a<=0)&&r<a?n+o-e.collisionWidth:n:0<a?t.left+=a:0<r?t.left-=r:t.left=C(t.left-l,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,o=e.within.height,l=t.top-e.collisionPosition.marginTop,a=n-l,r=l+e.collisionHeight-o-n;e.collisionHeight>o?0<a&&r<=0?(i=t.top+a+e.collisionHeight-o-n,t.top+=a-i):t.top=!(0<r&&a<=0)&&r<a?n+o-e.collisionHeight:n:0<a?t.top+=a:0<r?t.top-=r:t.top=C(t.top-l,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,l=n.width,a=n.isWindow?n.scrollLeft:n.offset.left,r=t.left-e.collisionPosition.marginLeft,u=r-a,h=r+e.collisionWidth-l-a,c="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,d="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];u<0?((i=t.left+c+d+f+e.collisionWidth-l-o)<0||i<E(u))&&(t.left+=c+d+f):0<h&&(0<(s=t.left-e.collisionPosition.marginLeft+c+d+f-a)||E(s)<h)&&(t.left+=c+d+f)},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,l=n.height,a=n.isWindow?n.scrollTop:n.offset.top,r=t.top-e.collisionPosition.marginTop,u=r-a,h=r+e.collisionHeight-l-a,c="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,d="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,f=-2*e.offset[1];u<0?((s=t.top+c+d+f+e.collisionHeight-l-o)<0||s<E(u))&&(t.top+=c+d+f):0<h&&(0<(i=t.top-e.collisionPosition.marginTop+c+d+f-a)||E(i)<h)&&(t.top+=c+d+f)}},flipfit:{left:function(){x.ui.position.flip.left.apply(this,arguments),x.ui.position.fit.left.apply(this,arguments)},top:function(){x.ui.position.flip.top.apply(this,arguments),x.ui.position.fit.top.apply(this,arguments)}}};var t;x.ui.position,x.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},x.fn.extend({uniqueId:(t=0,function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&x(this).removeAttr("id")})}}),x.ui.safeActiveElement=function(e){var i;try{i=e.activeElement}catch(t){i=e.body}return(i=i||e.body).nodeName||(i=e.body),i},x.widget("ui.menu",{version:"1.12.1",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var e,i;this.previousFilter||(e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i)))},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n,o=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:o=!1,i=this.previousFilter||"",n=!1,s=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),s===i?n=!0:s=i+s,e=this._filterMenuItems(s),(e=n&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(s=String.fromCharCode(t.keyCode),e=this._filterMenuItems(s)),e.length?(this.focus(t,e),this.previousFilter=s,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}o&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,i,s,n=this,o=this.options.icons.submenu,l=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=l.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("<span>").data("ui-menu-submenu-caret",!0);n._addClass(i,"ui-menu-icon","ui-icon "+o),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=l.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);n._isDivider(t)&&n._addClass(t,"ui-menu-divider","ui-widget-content")}),s=(i=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(i,"ui-menu-item")._addClass(s,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s,n,o,l;this._hasScroll()&&(e=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,i=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,s=t.offset().top-this.activeMenu.offset().top-e-i,n=this.activeMenu.scrollTop(),o=this.activeMenu.height(),l=t.outerHeight(),s<0?this.activeMenu.scrollTop(n+s):o<s+l&&this.activeMenu.scrollTop(n+s-o+l))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(t){var e=x.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(e)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var t=i?this.element:x(e&&e.target).closest(this.element.find(".ui-menu"));t.length||(t=this.element),this._close(t),this.blur(e),this._removeClass(t.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=t},this.delay)},_close:function(t){(t=t||(this.active?this.active.parent():this.element)).find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(t){return!x(t.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(t){var e,i,s;this.active?this.isLastItem()||(this._hasScroll()?(i=this.active.offset().top,s=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return(e=x(this)).offset().top-i-s<0}),this.focus(t,e)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())):this.next(t)},previousPage:function(t){var e,i,s;this.active?this.isFirstItem()||(this._hasScroll()?(i=this.active.offset().top,s=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return 0<(e=x(this)).offset().top-i+s}),this.focus(t,e)):this.focus(t,this.activeMenu.find(this.options.items).first())):this.next(t)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||x(t.target).closest(".ui-menu-item");var e={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,e)},_filterMenuItems:function(t){var e=t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),i=new RegExp("^"+e,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return i.test(x.trim(x(this).children(".ui-menu-item-wrapper").text()))})}});x.widget("ui.autocomplete",{version:"1.12.1",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,o="input"===t;this.isMultiLine=e||!o&&this._isContentEditable(this.element),this.valueMethod=this.element[e||o?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){this.cancelBlur?delete this.cancelBlur:(clearTimeout(this.searching),this.close(t),this._change(t))}}),this._initSource(),this.menu=x("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==x.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&x.trim(i).length&&(this.liveRegion.children().hide(),x("<div>").text(i).appendTo(this.liveRegion))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))&&t[0]||(t=this.element.closest(".ui-front, dialog")),t.length||(t=this.document[0].body),t},_initSource:function(){var i,s,n=this;x.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(!t||e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):!1!==this._trigger("search",e)?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return x.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")},this)},__response:function(t){t=t&&this._normalize(t),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:x.map(t,function(t){return"string"==typeof t?{label:t,value:t}:x.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var e=this.menu.element.empty();this._renderMenu(e,t),this.isNewMenu=!0,this.menu.refresh(),e.show(),this._resizeMenu(),e.position(x.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(i,t){var s=this;x.each(t,function(t,e){s._renderItemData(i,e)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(t,e){return x("<li>").append(x("<div>").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1<t?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.children().hide(),x("<div>").text(e).appendTo(this.liveRegion))}});x.ui.autocomplete}); \ No newline at end of file diff --git a/bl-kernel/js/tagsinput-revisited.min.js b/bl-kernel/js/tagsinput-revisited.min.js new file mode 100644 index 00000000..17612650 --- /dev/null +++ b/bl-kernel/js/tagsinput-revisited.min.js @@ -0,0 +1,30 @@ +/* jQuery Tags Input Revisited Plugin +https://www.jqueryscript.net/form/Tags-Input-Autocomplete.html +* Copyright (c) Krzysztof Rusnarczyk +* Licensed under the MIT license */ +! function(a) { var b = [], + c = [], + d = []; + a.fn.addTag = function(g, h) { return h = jQuery.extend({ focus: !1, callback: !0 }, h), this.each(function() { var i = a(this).attr("id"), + j = a(this).val().split(e(b[i])); "" === j[0] && (j = []), g = jQuery.trim(g); var k = c[i]; if (k.whitelist && k.whitelist.indexOf(g) === -1) return !1; if (c[i].unique && a(this).tagExist(g) || !f(g, c[i], j, b[i])) return a("#" + i + "_tag").addClass("error"), !1; if (a("<span>", { class: "tag" }).append(a("<span>", { class: "tag-text" }).text(g), a("<button>", { class: "tag-remove" }).click(function() { return a("#" + i).removeTag(encodeURI(g)) })).insertBefore("#" + i + "_addTag"), j.push(g), a("#" + i + "_tag").val(""), h.focus ? a("#" + i + "_tag").focus() : a("#" + i + "_tag").blur(), a.fn.tagsInput.updateTagsField(this, j), h.callback && d[i] && d[i].onAddTag) { var l = d[i].onAddTag; + l.call(this, this, g) } if (d[i] && d[i].onChange) { var l = (j.length, d[i].onChange); + l.call(this, this, g) } }), !1 }, a.fn.removeTag = function(c) { return c = decodeURI(c), this.each(function() { var f = a(this).attr("id"), + g = a(this).val().split(e(b[f])); + a("#" + f + "_tagsinput .tag").remove(); var h = ""; for (i = 0; i < g.length; ++i) g[i] != c && (h = h + e(b[f]) + g[i]); if (a.fn.tagsInput.importTags(this, h), d[f] && d[f].onRemoveTag) { var j = d[f].onRemoveTag; + j.call(this, this, c) } }), !1 }, a.fn.tagExist = function(c) { var d = a(this).attr("id"), + f = a(this).val().split(e(b[d])); return jQuery.inArray(c, f) >= 0 }, a.fn.importTags = function(b) { var c = a(this).attr("id"); + a("#" + c + "_tagsinput .tag").remove(), a.fn.tagsInput.importTags(this, b) }, a.fn.tagsInput = function(f) { var i = jQuery.extend({ interactive: !0, placeholder: "Add a tag", minChars: 0, maxChars: null, limit: null, validationPattern: null, width: "auto", height: "auto", autocomplete: null, hide: !0, delimiter: ",", unique: !0, removeWithBackspace: !0, whitelist: null }, f), + j = 0; return this.each(function() { if ("undefined" == typeof a(this).data("tagsinput-init")) { a(this).data("tagsinput-init", !0), i.hide && a(this).hide(); var f = a(this).attr("id"); + f && !e(b[a(this).attr("id")]) || (f = a(this).attr("id", "tags" + (new Date).getTime() + ++j).attr("id")); var k = jQuery.extend({ pid: f, real_input: "#" + f, holder: "#" + f + "_tagsinput", input_wrapper: "#" + f + "_addTag", fake_input: "#" + f + "_tag" }, i); + b[f] = k.delimiter, c[f] = { minChars: i.minChars, maxChars: i.maxChars, limit: i.limit, validationPattern: i.validationPattern, unique: i.unique, whitelist: i.whitelist }, (i.onAddTag || i.onRemoveTag || i.onChange) && (d[f] = [], d[f].onAddTag = i.onAddTag, d[f].onRemoveTag = i.onRemoveTag, d[f].onChange = i.onChange); var l = a("<div>", { id: f + "_tagsinput", class: "tagsinput" }).append(a("<div>", { id: f + "_addTag" }).append(i.interactive ? a("<input>", { id: f + "_tag", class: "tag-input", value: "", placeholder: i.placeholder }) : null)); + a(l).insertAfter(this), a(k.holder).css("width", i.width), a(k.holder).css("min-height", i.height), a(k.holder).css("height", i.height), "" !== a(k.real_input).val() && a.fn.tagsInput.importTags(a(k.real_input), a(k.real_input).val()), i.interactive && (a(k.fake_input).val(""), a(k.fake_input).data("pasted", !1), a(k.fake_input).on("focus", k, function(b) { a(k.holder).addClass("focus"), "" === a(this).val() && a(this).removeClass("error") }), a(k.fake_input).on("blur", k, function(b) { a(k.holder).removeClass("focus") }), null !== i.autocomplete && void 0 !== jQuery.ui.autocomplete ? (a(k.fake_input).autocomplete(i.autocomplete), a(k.fake_input).on("autocompleteselect", k, function(b, c) { return a(b.data.real_input).addTag(c.item.value, { focus: !0, unique: i.unique }), !1 }), a(k.fake_input).on("keypress", k, function(b) { g(b) && a(this).autocomplete("close") })) : a(k.fake_input).on("blur", k, function(b) { return a(b.data.real_input).addTag(a(b.data.fake_input).val(), { focus: !0, unique: i.unique }), !1 }), a(k.fake_input).on("keypress", k, function(b) { if (g(b)) return b.preventDefault(), a(b.data.real_input).addTag(a(b.data.fake_input).val(), { focus: !0, unique: i.unique }), !1 }), a(k.fake_input).on("paste", function() { a(this).data("pasted", !0) }), a(k.fake_input).on("input", k, function(b) { if (a(this).data("pasted")) { a(this).data("pasted", !1); var c = a(b.data.fake_input).val(); + c = c.replace(/\n/g, ""), c = c.replace(/\s/g, ""); var d = h(b.data.delimiter, c); if (d.length > 1) { for (var e = 0; e < d.length; ++e) a(b.data.real_input).addTag(d[e], { focus: !0, unique: i.unique }); return !1 } } }), k.removeWithBackspace && a(k.fake_input).on("keydown", function(b) { if (8 == b.keyCode && "" === a(this).val()) { b.preventDefault(); var c = a(this).closest(".tagsinput").find(".tag:last > span").text(), + d = a(this).attr("id").replace(/_tag$/, ""); + a("#" + d).removeTag(encodeURI(c)), a(this).trigger("focus") } }), a(k.fake_input).keydown(function(b) { jQuery.inArray(b.keyCode, [13, 37, 38, 39, 40, 27, 16, 17, 18, 225]) === -1 && a(this).removeClass("error") })) } }), this }, a.fn.tagsInput.updateTagsField = function(c, d) { var f = a(c).attr("id"); + a(c).val(d.join(e(b[f]))) }, a.fn.tagsInput.importTags = function(c, e) { a(c).val(""); var f = a(c).attr("id"), + g = h(b[f], e); for (i = 0; i < g.length; ++i) a(c).addTag(g[i], { focus: !1, callback: !1 }); if (d[f] && d[f].onChange) { var j = d[f].onChange; + j.call(c, c, g) } }; var e = function(a) { return "undefined" == typeof a ? a : "string" == typeof a ? a : a[0] }, + f = function(b, c, d, e) { var f = !0; return "" === b && (f = !1), b.length < c.minChars && (f = !1), null !== c.maxChars && b.length > c.maxChars && (f = !1), null !== c.limit && d.length >= c.limit && (f = !1), null === c.validationPattern || c.validationPattern.test(b) || (f = !1), "string" == typeof e ? b.indexOf(e) > -1 && (f = !1) : a.each(e, function(a, c) { return b.indexOf(c) > -1 && (f = !1), !1 }), f }, + g = function(b) { var c = !1; return 13 === b.which || ("string" == typeof b.data.delimiter ? b.which === b.data.delimiter.charCodeAt(0) && (c = !0) : a.each(b.data.delimiter, function(a, d) { b.which === d.charCodeAt(0) && (c = !0) }), c) }, + h = function(b, c) { if ("" === c) return []; if ("string" == typeof b) return c.split(b); var d = "∞", + e = c; return a.each(b, function(a, b) { e = e.split(b).join(d) }), e.split(d) } }(jQuery); \ No newline at end of file