diff --git a/package.json b/package.json index bc5486cb6..ed6c096bb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hashbrown-cms", "repository": "https://github.com/Putaitu/hashbrown-cms.git", - "version": "0.10.0", + "version": "0.10.1", "description": "The pluggable CMS", "main": "hashbrown.js", "scripts": { @@ -40,7 +40,6 @@ "json-loader": "^0.5.4", "node-sass": "^3.13.1", "sass-loader": "^6.0.6", - "sass-material-colors": "0.0.5", "style-loader": "^0.13.1", "webpack": "^3.0.0" } diff --git a/public/css/client.css b/public/css/client.css index 8e60ac854..32383fa0f 100644 --- a/public/css/client.css +++ b/public/css/client.css @@ -251,7 +251,7 @@ h1, h2, h3, h4, h5, h6 { opacity: 1; position: relative; z-index: 2; } - @media (max-width: 767px) { + @media (max-width: 991px) { .page--environment__spaces { flex-direction: column; } } @@ -279,8 +279,8 @@ h1, h2, h3, h4, h5, h6 { width: 100%; height: 80vh; } .page--environment__space--nav:not(.expanded) { - flex-basis: 6rem; - height: 6rem; } } + flex-basis: 8rem; + height: 8rem; } } .page--environment__space--editor { flex-grow: 1; height: 100%; @@ -361,7 +361,7 @@ h1, h2, h3, h4, h5, h6 { width: 100%; position: relative; z-index: 100; } - @media (max-width: 767px) { + @media (max-width: 991px) { .navbar-main { flex-direction: column; } } .navbar-main.hide-tabs .navbar-main__tabs { @@ -369,6 +369,24 @@ h1, h2, h3, h4, h5, h6 { .navbar-main__panes, .navbar-main__tabs { transition: opacity 0.5s, width 0.5s; overflow-x: hidden; } + .navbar-main__toggle { + display: none; + line-height: 0; + height: 2rem; + padding: 0; + margin: 0; + color: #ffffff; + background-color: #21303b; + border: 0; + flex-shrink: 0; } + .navbar-main__toggle:after { + font-family: 'FontAwesome'; + content: '\F107'; } + .page--environment__space--nav.expanded .navbar-main__toggle:after { + content: '\F106'; } + @media (max-width: 991px) { + .navbar-main__toggle { + display: block; } } .navbar-main__tabs { width: 6rem; flex-shrink: 0; @@ -379,10 +397,11 @@ h1, h2, h3, h4, h5, h6 { background-image: url("/img/bg-secondary.jpg"); background-attachment: fixed; background-position: 0px 0px; } - @media (max-width: 767px) { + @media (max-width: 991px) { .navbar-main__tabs { display: flex; width: 100%; + justify-content: center; height: 6rem; overflow-x: auto; } } .navbar-main__tabs:after { @@ -432,7 +451,7 @@ h1, h2, h3, h4, h5, h6 { position: relative; z-index: 5; border-right: 1px solid #21303b; } - @media (max-width: 767px) { + @media (max-width: 991px) { .navbar-main__panes { border-right: 0; border-bottom: 1px solid #21303b; } } @@ -727,7 +746,7 @@ h1, h2, h3, h4, h5, h6 { border-bottom: 1px solid #dddddd; } .editor__field:last-of-type { border-bottom: 0; } - @media (max-width: 767px) { + @media (max-width: 991px) { .editor__field { display: block; } } .editor__field__value.collapsed .editor__field, @@ -765,9 +784,15 @@ h1, h2, h3, h4, h5, h6 { top: 60px; } .editor__field__key .widget:not(:last-child) { margin-bottom: 0.5rem; } + @media (max-width: 991px) { + .editor__field__key__label { + margin-bottom: 0.5rem; } } .editor__field__key__description { margin-top: 0.5rem; color: #666666; } + @media (max-width: 991px) { + .editor__field__key__description { + margin-bottom: 0.5rem; } } .editor__field__key__actions { position: absolute; line-height: 2rem; } @@ -961,6 +986,9 @@ h1, h2, h3, h4, h5, h6 { width: 100px; border-radius: 0.2rem; border: 1px solid #dddddd; } + @media (max-width: 991px) { + .editor__field--rich-text-editor { + width: auto; } } .editor__field--rich-text-editor__header { padding: 1rem 0 0 1rem; background-color: #dddddd; @@ -1523,7 +1551,7 @@ h1, h2, h3, h4, h5, h6 { font-family: 'FontAwesome'; content: '\F1CE'; position: absolute; - right: 0.5rem; + right: 0rem; top: 50%; z-index: 10; display: block; @@ -1848,11 +1876,7 @@ h1, h2, h3, h4, h5, h6 { .widget--input.checkbox:hover { background-color: #b70a2f; } .widget--input.checkbox.working:after { - color: #ffffff; - width: 2rem; - height: 2rem; - line-height: 2rem; - margin-top: -1rem; } + color: #ffffff; } .widget--input__checkbox-input, .widget--input__checkbox-extra { position: absolute; top: 0; diff --git a/public/js/client.js b/public/js/client.js index 8013b0009..cbb142015 100644 --- a/public/js/client.js +++ b/public/js/client.js @@ -33381,8 +33381,6 @@ var UIHelper = function () { document.body.appendChild(dropdown.element); }; - var touchTimeout = null; - element.addEventListener('contextmenu', function (e) { e.preventDefault(); e.stopPropagation(); @@ -33400,16 +33398,11 @@ var UIHelper = function () { }); element.addEventListener('touchstart', function (e) { - e.preventDefault(); + if (e.touchTargets && e.touchTargets.length > 1) { + e.preventDefault(); + e.stopPropagation(); - touchTimeout = setTimeout(function () { openContextMenu(e); - }, 400); - }); - - element.addEventListener('touchend', function (e) { - if (touchTimeout) { - clearTimeout(touchTimeout); } }); }; @@ -40784,7 +40777,7 @@ module.exports = ["address", "article", "aside", "blockquote", "canvas", "dd", " module.exports = { "name": "hashbrown-cms", "repository": "https://github.com/Putaitu/hashbrown-cms.git", - "version": "0.9.9", + "version": "0.10.1", "description": "The pluggable CMS", "main": "hashbrown.js", "scripts": { @@ -40823,7 +40816,6 @@ module.exports = { "json-loader": "^0.5.4", "node-sass": "^3.13.1", "sass-loader": "^6.0.6", - "sass-material-colors": "0.0.5", "style-loader": "^0.13.1", "webpack": "^3.0.0" } @@ -43332,7 +43324,12 @@ module.exports = function () { } return $pane; - }))); + })), + + // Toggle button (mobile only) + _.button({ class: 'navbar-main__toggle' }).click(function (e) { + $('.page--environment__space--nav').toggleClass('expanded'); + })); }; /***/ }), @@ -45777,17 +45774,22 @@ var ArrayEditor = function (_FieldEditor) { // Perform sanity check on item value item.value = ContentHelper.fieldSanityCheck(item.value, schema); - // Instantiate editor + // Init the field editor var editorInstance = new editorClass({ value: item.value, config: schema.config, schema: schema }); + // Hook up the change event editorInstance.on('change', function (newValue) { item.value = newValue; }); + editorInstance.on('silentchange', function (newValue) { + item.value = newValue; + }); + // Render Schema picker if (_this4.config.allowedSchemas.length > 1) { editorInstance.$element.prepend(_.div({ class: 'editor__field' }, _.div({ class: 'editor__field__key' }, 'Schema'), _.div({ class: 'editor__field__value' }, new HashBrown.Views.Widgets.Dropdown({ @@ -47668,6 +47670,10 @@ var StructEditor = function (_FieldEditor) { _this2.onChange(newValue, k, keySchema); }); + fieldEditorInstance.on('silentchange', function (newValue) { + _this2.onChange(newValue, k, keySchema); + }); + // Return the DOM element return _.div({ class: 'editor__field' }, _.div({ class: 'editor__field__key' }, _.div({ class: 'editor__field__key__label' }, keySchema.label), _.if(keySchema.description, _.div({ class: 'editor__field__key__description' }, keySchema.description)), fieldEditorInstance.renderKeyActions()), fieldEditorInstance.$element); })); @@ -47872,7 +47878,7 @@ var TemplateReferenceEditor = function (_FieldEditor) { // Apply changes on next CPU cycle setTimeout(function () { _this2.trigger('silentchange', _this2.value); - }, 1); + }, 500); } }; diff --git a/public/js/dashboard.js b/public/js/dashboard.js index a8e662986..bdfcb929a 100644 --- a/public/js/dashboard.js +++ b/public/js/dashboard.js @@ -28555,8 +28555,6 @@ var UIHelper = function () { document.body.appendChild(dropdown.element); }; - var touchTimeout = null; - element.addEventListener('contextmenu', function (e) { e.preventDefault(); e.stopPropagation(); @@ -28574,16 +28572,11 @@ var UIHelper = function () { }); element.addEventListener('touchstart', function (e) { - e.preventDefault(); + if (e.touchTargets && e.touchTargets.length > 1) { + e.preventDefault(); + e.stopPropagation(); - touchTimeout = setTimeout(function () { openContextMenu(e); - }, 400); - }); - - element.addEventListener('touchend', function (e) { - if (touchTimeout) { - clearTimeout(touchTimeout); } }); }; @@ -35958,7 +35951,7 @@ module.exports = ["address", "article", "aside", "blockquote", "canvas", "dd", " module.exports = { "name": "hashbrown-cms", "repository": "https://github.com/Putaitu/hashbrown-cms.git", - "version": "0.9.9", + "version": "0.10.1", "description": "The pluggable CMS", "main": "hashbrown.js", "scripts": { @@ -35997,7 +35990,6 @@ module.exports = { "json-loader": "^0.5.4", "node-sass": "^3.13.1", "sass-loader": "^6.0.6", - "sass-material-colors": "0.0.5", "style-loader": "^0.13.1", "webpack": "^3.0.0" } diff --git a/src/Client/Helpers/UIHelper.js b/src/Client/Helpers/UIHelper.js index 185fe5fa4..084a9e010 100644 --- a/src/Client/Helpers/UIHelper.js +++ b/src/Client/Helpers/UIHelper.js @@ -634,8 +634,6 @@ class UIHelper { document.body.appendChild(dropdown.element); }; - let touchTimeout = null; - element.addEventListener('contextmenu', (e) => { e.preventDefault(); e.stopPropagation(); @@ -653,16 +651,11 @@ class UIHelper { }); element.addEventListener('touchstart', (e) => { - e.preventDefault(); + if(e.touchTargets && e.touchTargets.length > 1) { + e.preventDefault(); + e.stopPropagation(); - touchTimeout = setTimeout(() => { openContextMenu(e); - }, 400); - }); - - element.addEventListener('touchend', (e) => { - if(touchTimeout) { - clearTimeout(touchTimeout); } }); } diff --git a/src/Client/Style/Pages/Environment.scss b/src/Client/Style/Pages/Environment.scss index 2ea22d369..49a9971b5 100644 --- a/src/Client/Style/Pages/Environment.scss +++ b/src/Client/Style/Pages/Environment.scss @@ -20,8 +20,8 @@ position: relative; z-index: 2; - // Mobile mode - @media($xs) { + // Tablet mode + @media($sm) { flex-direction: column; } } @@ -58,8 +58,8 @@ height: 80vh; &:not(.expanded) { - flex-basis: 6rem; - height: 6rem; + flex-basis: 8rem; + height: 8rem; } } } diff --git a/src/Client/Style/Views/Editors/Editor.scss b/src/Client/Style/Views/Editors/Editor.scss index 85ec18ab6..700c4dc0a 100644 --- a/src/Client/Style/Views/Editors/Editor.scss +++ b/src/Client/Style/Views/Editors/Editor.scss @@ -150,8 +150,8 @@ border-bottom: 0; } - // Mobile mode - @media($xs) { + // Tablet mode + @media($sm) { display: block; } @@ -211,11 +211,24 @@ .widget:not(:last-child) { margin-bottom: 0.5rem; } - + + // Label + &__label { + // Tablet mode + @media($sm) { + margin-bottom: 0.5rem; + } + } + // Description &__description { margin-top: 0.5rem; color: $standard-darkest; + + // Tablet mode + @media($sm) { + margin-bottom: 0.5rem; + } } // Key actions diff --git a/src/Client/Style/Views/Editors/FieldEditors/RichTextEditor.scss b/src/Client/Style/Views/Editors/FieldEditors/RichTextEditor.scss index 72765d59a..830313d4f 100644 --- a/src/Client/Style/Views/Editors/FieldEditors/RichTextEditor.scss +++ b/src/Client/Style/Views/Editors/FieldEditors/RichTextEditor.scss @@ -7,6 +7,11 @@ border-radius: 0.2rem; border: 1px solid $standard-darker; + // Tablet mode + @media($sm) { + width: auto; + } + // Header &__header { padding: 1rem 0 0 1rem; diff --git a/src/Client/Style/Views/Navigation/NavbarMain.scss b/src/Client/Style/Views/Navigation/NavbarMain.scss index cab5cc4ce..f095a0b7e 100644 --- a/src/Client/Style/Views/Navigation/NavbarMain.scss +++ b/src/Client/Style/Views/Navigation/NavbarMain.scss @@ -17,8 +17,8 @@ position: relative; z-index: 100; - // Mobile mode - @media($xs) { + // Tablet mode + @media($sm) { flex-direction: column; } @@ -30,7 +30,34 @@ transition: opacity 0.5s, width 0.5s; overflow-x: hidden; } - + + // Toggle + &__toggle { + display: none; + line-height: 0; + height: 2rem; + padding: 0; + margin: 0; + color: $secondary-text; + background-color: $secondary; + border: 0; + flex-shrink: 0; + + &:after { + font-family: 'FontAwesome'; + content: '\f107'; + } + + .page--environment__space--nav.expanded &:after { + content: '\f106'; + } + + // Tablet mode + @media($sm) { + display: block; + } + } + // Tabs &__tabs { width: 6rem; @@ -42,10 +69,11 @@ @include background('secondary'); - // Mobile mode - @media($xs) { + // Tablet mode + @media($sm) { display: flex; width: 100%; + justify-content: center; height: 6rem; overflow-x: auto; } @@ -77,11 +105,6 @@ display: block; z-index: 2; - // Mobile mode - @media($xs) { - - } - &[data-route="about"] { font-weight: bold; } @@ -118,8 +141,8 @@ z-index: 5; border-right: 1px solid $secondary; - // Mobile mode - @media($xs) { + // Tablet mode + @media($sm) { border-right: 0; border-bottom: 1px solid $secondary; } diff --git a/src/Client/Style/Views/Widgets/Input.scss b/src/Client/Style/Views/Widgets/Input.scss index e28d02a46..6715832ab 100644 --- a/src/Client/Style/Views/Widgets/Input.scss +++ b/src/Client/Style/Views/Widgets/Input.scss @@ -152,10 +152,6 @@ &.working { &:after { color: $primary-text; - width: 2rem; - height: 2rem; - line-height: 2rem; - margin-top: -1rem; } } } diff --git a/src/Client/Style/Views/Widgets/Widget.scss b/src/Client/Style/Views/Widgets/Widget.scss index ea39d9b9d..671e57e3c 100644 --- a/src/Client/Style/Views/Widgets/Widget.scss +++ b/src/Client/Style/Views/Widgets/Widget.scss @@ -97,7 +97,7 @@ font-family: 'FontAwesome'; content: '\f1ce'; position: absolute; - right: 0.5rem; + right: 0rem; top: 50%; z-index: 10; display: block; diff --git a/src/Client/Templates/Navigation/NavbarMain.js b/src/Client/Templates/Navigation/NavbarMain.js index 1f9c9549c..7ae31b2ac 100644 --- a/src/Client/Templates/Navigation/NavbarMain.js +++ b/src/Client/Templates/Navigation/NavbarMain.js @@ -109,6 +109,12 @@ module.exports = function() { return $pane; }) - ) + ), + + // Toggle button (mobile only) + _.button({class: 'navbar-main__toggle'}) + .click((e) => { + $('.page--environment__space--nav').toggleClass('expanded'); + }) ); }; diff --git a/src/Client/Views/Editors/FieldEditors/ArrayEditor.js b/src/Client/Views/Editors/FieldEditors/ArrayEditor.js index 7d541e6c1..6a580bc93 100644 --- a/src/Client/Views/Editors/FieldEditors/ArrayEditor.js +++ b/src/Client/Views/Editors/FieldEditors/ArrayEditor.js @@ -233,16 +233,21 @@ class ArrayEditor extends FieldEditor { // Perform sanity check on item value item.value = ContentHelper.fieldSanityCheck(item.value, schema); - // Instantiate editor + // Init the field editor let editorInstance = new editorClass({ value: item.value, config: schema.config, schema: schema }); + // Hook up the change event editorInstance.on('change', (newValue) => { item.value = newValue; }); + + editorInstance.on('silentchange', (newValue) => { + item.value = newValue; + }); // Render Schema picker if(this.config.allowedSchemas.length > 1) { diff --git a/src/Client/Views/Editors/FieldEditors/StructEditor.js b/src/Client/Views/Editors/FieldEditors/StructEditor.js index b0aa964a7..7d72c38ae 100644 --- a/src/Client/Views/Editors/FieldEditors/StructEditor.js +++ b/src/Client/Views/Editors/FieldEditors/StructEditor.js @@ -291,6 +291,10 @@ class StructEditor extends FieldEditor { fieldEditorInstance.on('change', (newValue) => { this.onChange(newValue, k, keySchema); }); + + fieldEditorInstance.on('silentchange', (newValue) => { + this.onChange(newValue, k, keySchema); + }); // Return the DOM element return _.div({class: 'editor__field'}, diff --git a/src/Client/Views/Editors/FieldEditors/TemplateReferenceEditor.js b/src/Client/Views/Editors/FieldEditors/TemplateReferenceEditor.js index d9b1ae308..a0e6934a9 100644 --- a/src/Client/Views/Editors/FieldEditors/TemplateReferenceEditor.js +++ b/src/Client/Views/Editors/FieldEditors/TemplateReferenceEditor.js @@ -111,7 +111,7 @@ class TemplateReferenceEditor extends FieldEditor { // Apply changes on next CPU cycle setTimeout(() => { this.trigger('silentchange', this.value); - }, 1); + }, 500); } } diff --git a/src/Server/Helpers/ContentHelper.js b/src/Server/Helpers/ContentHelper.js index cb710459c..a511a065c 100644 --- a/src/Server/Helpers/ContentHelper.js +++ b/src/Server/Helpers/ContentHelper.js @@ -6,7 +6,7 @@ const SyncHelper = require('Server/Helpers/SyncHelper'); const SchemaHelper = require('Server/Helpers/SchemaHelper'); const DatabaseHelper = require('Server/Helpers/DatabaseHelper'); -const Content = require('Common/Models/Content'); +const Content = require('Server/Models/Content'); const ContentSchema = require('Common/Models/ContentSchema'); const FieldSchema = require('Common/Models/FieldSchema'); const User = require('Server/Models/User');