From 6e5448c16335add08018b3344a20a5f6715d1309 Mon Sep 17 00:00:00 2001 From: Colin Tucker Date: Tue, 12 Sep 2017 11:27:38 +1000 Subject: [PATCH] Updated for new version --- _config/config.yml | 3 + _config/styles.yml | 4 + admin/client/dist/images/icons/ListPage.png | Bin 0 -> 610 bytes .../dist/images/icons/ListSourceSlide.png | Bin 0 -> 566 bytes admin/client/dist/js/bundle.js | 2 +- admin/client/dist/styles/bundle.css | 2 +- admin/client/src/bundles/bundle.js | 2 +- admin/client/src/forms/AutoCompleteField.js | 152 -------- admin/client/src/forms/ToggleGroup.js | 58 +++ admin/client/src/images/icons/ListPage.png | Bin 0 -> 610 bytes .../src/images/icons/ListSourceSlide.png | Bin 0 -> 566 bytes admin/client/src/styles/bundle.scss | 1 - .../src/styles/forms/AutoCompleteField.scss | 24 -- client/dist/js/bundle.js | 2 +- client/dist/styles/bundle.css | 2 +- client/src/bundles/bundle.js | 5 + client/src/components/TagCloudComponent.js | 21 +- client/src/forms/MessageHandler.js | 136 +++++++ client/src/forms/ToggleGroup.js | 24 ++ client/src/styles/_variables.scss | 1 + .../styles/components/BaseListComponent.scss | 36 +- client/src/styles/mixins/_icon-size.scss | 2 +- composer.json | 2 + src/Components/BaseComponent.php | 14 +- src/Components/BaseListComponent.php | 48 ++- src/Components/ContentComponent.php | 10 +- src/Extensions/Admin/LeftAndMainExtension.php | 43 +++ .../Lists/ListItemExtension.php} | 134 +++++-- src/Extensions/Model/MetaDataExtension.php | 4 +- src/Extensions/Style/CornerStyle.php | 1 - src/Forms/AutoCompleteField.php | 349 ------------------ src/Forms/TagField.php | 257 +++++++++++++ src/Forms/ToggleGroup.php | 224 +++++++++++ src/Grid/Column.php | 2 +- src/Grid/Frameworks/Bootstrap/Row.php | 13 + src/Grid/Frameworks/Bootstrap/Section.php | 22 +- src/Grid/Row.php | 90 ++++- src/Grid/Section.php | 70 +++- src/Lists/ListAlert.php | 110 ++++++ src/Lists/ListSourceSlide.php | 178 +++++++++ src/Model/Component.php | 39 +- src/Model/ComponentController.php | 27 ++ src/Model/Link.php | 1 + src/Model/Slide.php | 193 +++++++++- src/Pages/ListPage.php | 87 +++++ src/Sections/LayoutSection.php | 3 +- src/Tags/Tag.php | 2 +- src/View/Renderable.php | 18 +- .../Components/BaseListComponent.ss | 1 + .../Components/BaseListComponent/CustomCSS.ss | 7 + .../BaseListComponent/Includes/Alerts.ss | 7 + templates/SilverWare/Forms/ToggleGroup.ss | 6 + .../Lists/ListItem/Includes/Details.ss | 2 +- .../Lists/ListItem/Includes/Image.ss | 3 + templates/SilverWare/Model/Slide.ss | 4 +- 55 files changed, 1817 insertions(+), 631 deletions(-) create mode 100644 admin/client/dist/images/icons/ListPage.png create mode 100644 admin/client/dist/images/icons/ListSourceSlide.png delete mode 100644 admin/client/src/forms/AutoCompleteField.js create mode 100644 admin/client/src/forms/ToggleGroup.js create mode 100644 admin/client/src/images/icons/ListPage.png create mode 100644 admin/client/src/images/icons/ListSourceSlide.png delete mode 100644 admin/client/src/styles/forms/AutoCompleteField.scss create mode 100644 client/src/forms/MessageHandler.js create mode 100644 client/src/forms/ToggleGroup.js rename src/{Lists/ListItem.php => Extensions/Lists/ListItemExtension.php} (64%) delete mode 100644 src/Forms/AutoCompleteField.php create mode 100644 src/Forms/TagField.php create mode 100644 src/Forms/ToggleGroup.php create mode 100644 src/Lists/ListAlert.php create mode 100644 src/Lists/ListSourceSlide.php create mode 100644 src/Pages/ListPage.php create mode 100644 templates/SilverWare/Components/BaseListComponent/CustomCSS.ss create mode 100644 templates/SilverWare/Components/BaseListComponent/Includes/Alerts.ss create mode 100644 templates/SilverWare/Forms/ToggleGroup.ss diff --git a/_config/config.yml b/_config/config.yml index 6d901c8..612bec2 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -9,6 +9,7 @@ Page: - SilverWare\Extensions\PageExtension - SilverWare\Extensions\AreaExtension - SilverWare\Extensions\Model\MetaDataExtension + - SilverWare\Extensions\Lists\ListItemExtension disable_metadata_toggle: true # Controller Extensions: @@ -27,6 +28,8 @@ SilverStripe\Admin\LeftAndMain: - silverware/admin/client/dist/styles/bundle.css extra_requirements_javascript: - silverware/admin/client/dist/js/bundle.js + themed_editor_css: + - production/styles/editor.css # Site Configuration Extensions: diff --git a/_config/styles.yml b/_config/styles.yml index 7e1c40f..267d63e 100644 --- a/_config/styles.yml +++ b/_config/styles.yml @@ -59,6 +59,10 @@ SilverWare\Grid\Frameworks\Bootstrap\Framework: bottom: rounded-bottom left: rounded-left circle: rounded-circle + row: + no-gutters: no-gutters + section: + edge-to-edge: pl-0 pr-0 text: text: text primary: text-primary diff --git a/admin/client/dist/images/icons/ListPage.png b/admin/client/dist/images/icons/ListPage.png new file mode 100644 index 0000000000000000000000000000000000000000..a2a4a08985f27483f1b271367e858441eb74ac1a GIT binary patch literal 610 zcmV-o0-gPdP)?RpkRaKl z!JVD-z1K`!Nhl7yeZ$Q6zWLravsR+7sfn(dSXsuK#VPSn8*>rmG?D%-x)Hx9aHW$C!dX2)! z4;-GHAeBm?yQ>RO3fXK{+DRsp*mm7=8-Zd4M6f&h6Pkc;`}-xcAO8Rfidr<-HiA$o zX~F$GiA;VTN5vu%i3Do3nq>BeGb>u4KyKmViY=f$ zdb($HGOO@zZ{>6os?#mdvz7Vsdx!@^~YM#V}Rx`6y w&Ci-5ifs{8ecyZ0+dGFR3?lK&{I38500#3ktt9ak-v9sr07*qoM6N<$f@F3SBLDyZ literal 0 HcmV?d00001 diff --git a/admin/client/dist/images/icons/ListSourceSlide.png b/admin/client/dist/images/icons/ListSourceSlide.png new file mode 100644 index 0000000000000000000000000000000000000000..212067fa11f692edbe7585d4938cad17af330b9e GIT binary patch literal 566 zcmV-60?GY}P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^MlX|MGF00E{+L_t(IPoSp46J^5IQ?BE(4HezA^}m$^J?Vy(A{6<+QGrq!$1HBe*d4G-P|Dg z^@VD^zB8|~%HTpgnM5VWb>&sA>zzd`kwBS7)16njM(4!q=O;?lY8|5;WK9SM*+?%p znbz_0@qv<-mR?3X$l5w~gdUqOh0f}OcFG5h#fxU6M^x^Z+ClXF9mOhDAEO;)9hyIf zbt4SRS_tNqD@-f}F}ipGP7pO{w?t*f_BJB17-UMNp3x4n4%mYjafZOpUBWI1rdNYd zo4jc3*@sfICn`JKZbaj8NXyHI80{cypXC~yB@E-jEp`td;5mK-KXZX*{uKR=u&6Ap zs5p@n6^$3j'+n+"")}})}},findTab:function(t){return this.find(this.getTabId(t))},getTabId:function(t){return"a#tab-"+t.replace(".","_")}}),t(".cms-tree li").entwine({updateBadge:function(e){if(this.find("span.status-number-badge").length){var n="#"+this.attr("id"),i=n+".status-number-badge > a span.jstree-pageicon::before",a='content: "'+(e>0?e:"")+'";';t("head").append('")}}}),t("span.status-number-badge-value").entwine({onmatch:function(){if(this._super(),!this.data("updated")){var t=parseInt(this.attr("title"));this.closest("li").updateBadge(t),this.data("updated",!0)}}})})},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(0);n.n(i).a.entwine("silverware.listviewextension",function(t){t(".tabset.silverware-extensions-lists-listviewextension").entwine({onmatch:function(){var e=t(this);this.handlePagination(),this.getPaginateItemsField().entwine({onchange:function(t){e.handlePagination(),this._super(t)}}),this._super()},handlePagination:function(){1==this.getPaginateItemsField().val()?this.getPaginationHolder().show():this.getPaginationHolder().hide()},getPaginateItemsField:function(){return t(this).find("#Form_EditForm_ListPaginateItems")},getPaginationHolder:function(){return t(this).find("#Form_EditForm_ListItemsPerPage_Holder")}})})},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(0);n.n(i).a.entwine("ss.autocompletefield",function(t){t(".field.autocomplete input.text").entwine({onmatch:function(){this._super(),this.initField(),this.initClear()},onfocusin:function(){this.getValue()>=this.getMinLength()&&t(this).autocomplete("search")},initField:function(){var e=this;t(this).autocomplete({source:e.getSourceURL(),minLength:e.getMinLength(),delay:e.getDelay(),change:function(t,n){e.update(t,n)},select:function(t,n){e.update(t,n)}})},initClear:function(){var e=this;t(this).parent().find("a.clear").click(function(t){t.preventDefault(),e.clearValue()})},setValue:function(e){t(this).val(e)},getValue:function(){return t(this).val()},getSourceURL:function(){return t(this).attr("data-source-url")},getMinLength:function(){return t(this).attr("data-min-length")},isFreeTextAllowed:function(){return!!t(this).attr("data-free-text")},getDelay:function(){return t(this).attr("data-delay")},getEmptyValue:function(){return t(this).attr("data-empty-value")},getHiddenInput:function(){return t(this).parent().find(":hidden")},getValueWrapper:function(){return t(this).parent().find(".value-wrapper")},getValueElement:function(){return t(this).parent().find(".value-wrapper > .value")},update:function(t,e){var n=this.getValue();n&&(e.item?this.updateValue(e.item.value,e.item.label):this.isFreeTextAllowed()&&this.updateValue(n))},updateValue:function(t,e){e||(e=t),this.getHiddenInput().val()!==t&&(this.getHiddenInput().val(t),this.getValueElement().text(e),this.getValueWrapper().addClass("has-value"))},clearValue:function(){this.getHiddenInput().val(""),this.getValueElement().text(this.getEmptyValue()),this.getValueWrapper().removeClass("has-value")}})})}]); \ No newline at end of file +!function(e){function t(i){if(n[i])return n[i].exports;var a=n[i]={i:i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/silverware/admin/client/dist/",t(t.s=1)}([function(e,t){e.exports=jQuery},function(e,t,n){n(2),n(3),n(4),n(5)},function(e,t){},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=n(0);n.n(i).a.entwine("silverware.numberbadges",function(e){e("div.ss-tabset").entwine({onmatch:function(){this._super();var t=this;if(this.attr("data-number-badges")){var n=e.parseJSON(this.attr("data-number-badges"));e.each(n,function(e,n){if(n){var i=t.findTab(e);i.length&&i.append(''+n+"")}})}},findTab:function(e){return this.find(this.getTabId(e))},getTabId:function(e){return"a#tab-"+e.replace(".","_")}}),e(".cms-tree li").entwine({updateBadge:function(t){if(this.find("span.status-number-badge").length){var n="#"+this.attr("id"),i=n+".status-number-badge > a span.jstree-pageicon::before",a='content: "'+(t>0?t:"")+'";';e("head").append('")}}}),e("span.status-number-badge-value").entwine({onmatch:function(){if(this._super(),!this.data("updated")){var e=parseInt(this.attr("title"));this.closest("li").updateBadge(e),this.data("updated",!0)}}})})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=n(0);n.n(i).a.entwine("silverware.listviewextension",function(e){e(".tabset.silverware-extensions-lists-listviewextension").entwine({onmatch:function(){var t=e(this);this.handlePagination(),this.getPaginateItemsField().entwine({onchange:function(e){t.handlePagination(),this._super(e)}}),this._super()},handlePagination:function(){1==this.getPaginateItemsField().val()?this.getPaginationHolder().show():this.getPaginationHolder().hide()},getPaginateItemsField:function(){return e(this).find("#Form_EditForm_ListPaginateItems")},getPaginationHolder:function(){return e(this).find("#Form_EditForm_ListItemsPerPage_Holder")}})})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=n(0);n.n(i).a.entwine("silverware.togglegroup",function(e){e(".field.togglegroup").entwine({onmatch:function(){var t=e(this);t.doToggle(),t.getToggleInput().entwine({onclick:function(e){t.doToggle(),this._super(e)}}),this._super()},doToggle:function(){var t=e(this.getToggleInput()),n=this.getToggleMode();this.getFields().toggle(n?t.is(":checked"):!t.is(":checked"))},getToggle:function(){return e(this).find(".group-toggle")},getFields:function(){return e(this).find(".group-fields")},getToggleInput:function(){return this.getToggle().find("input")},getToggleMode:function(){return this.getToggle().data("show-when-checked")}})})}]); \ No newline at end of file diff --git a/admin/client/dist/styles/bundle.css b/admin/client/dist/styles/bundle.css index 46d57e2..fd80536 100644 --- a/admin/client/dist/styles/bundle.css +++ b/admin/client/dist/styles/bundle.css @@ -1 +1 @@ -.cms-tree.jstree li.hidden{display:none}.cms-tree .is-cached>a span.jstree-pageicon:after{top:0;left:0;width:16px;height:16px;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAAA/0lEQVQ4T2P4//8/RRirICkYqyApGKsgKRirICkYqyApGKsgKRirIDZ8ehMjz5nNjGuQ8a7FzHuxKsaGT6xnjHpwyvLc/3dt/0EYqHkfEDtjVYyOD61k5Dm6hmXltyfZX3+/qvi/eirT4R0LmZ1Bclg1oOO9Sxljrx3Uufjtaer/W8dMbu1bxrgFhrFqQMfrZjAdXtjNeHxWC+PpTw+D/4PwjgWM23cuZHTAqgEbXj+dUefAKsGT7++5/d80i3H35tmMTiBxrIqx4RUTGWL2LBe+uHISw8FVkxlcYOIYCnHhBZ0Mk4D42MIuBldkcRRF+PDMZoZTs1oY3FHF/zMAAFD514LNcp7PAAAAAElFTkSuQmCC);position:absolute}.cms-tree .is-disabled>a span.jstree-pageicon:after{top:0;left:0;width:16px;height:16px;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAAA3ElEQVQ4T6XPoQvCQBTH8YHLc7ewP2RlfVFY3f6DgcH/wqg2o0kQFCZaLTOY5HCr1qF1hgtL4/kOTMevHIYPj325x90cIvoLjDZgtAGjDRhtwGgDRhsw2oDRBozI3nEmbMfkb050h4dNWz58FqJ557n6FMXwyjJ18v1Gd7hg2vCNzzRV9yShKo7pEkV0i2OlO1wwrfnZPElKSXVdU9u21HUd6Q4XTAu+6RCG/TEIqBSCSp678bjXHS6Y5vyvK9dtrr6vHkIMleep5WjU6A4XkBkfnvKNTOqpv4nI+QKF/8YumbPwcAAAAABJRU5ErkJggg==);position:absolute}.cms-tree .heading-h1>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNCREIzRDE2RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNCREIzRDE1RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+MOUuyAAAALdJREFUeNpi/P//PwMlgImBQjDwBrCATWFi0gZSjUji9VAaXewqlC0AxB/+/fvHwAAKREZGRhB2AuL1UBqXmCIQNwHxGhAfpBfZC2+AmBVK4xKTgdrOguIFKGCEKu7G4lVGKH0YiDmAuBCXAWxA3AnEL6BiEkBcjmQALODZsBkAk3gFxBegYkZQMSZcBiBLgPzHDqWxikFTLTPUGxAAFbQC4odI2AqHWCoQ34PiC+AYHM0LDAABBgBVkDNh2LuR6gAAAABJRU5ErkJggg==)}.cms-tree .heading-h2>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNCREIzRDFBRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNCREIzRDE5RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+52Ri6wAAAM9JREFUeNpi/P//PwMlgHEYGAAE2kC6EUmsHkqji12FssWA+BMQ/4CZAMJOQLweSuMSUwPi+UC8BohXAbEPSJwJauobIGaF0gw4xJ4C8QogjgfiI0AcCRJkgXkFqrgbmzeh9Fcg3gllPwJiJ3QD2IC4E4hfQMUkgLgcyQAY4AHiUCC+jmwAE9SAV0B8ASpmBBVjQtLMC8QdQMwNxFMYkCRlgJgdSjPgEBMA4nlArAF1KSj+WUDOswLi5UgaI6E0utgvIF6F5h1/xtG8wAAQYAC/dzmnYX+qBAAAAABJRU5ErkJggg==)}.cms-tree .heading-h3>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzY3RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzY2RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+PvPC7QAAAORJREFUeNrE078LAXEYx/E7vxcyGow2u8EiSonsEn+HskgWUkZ/Ainlv8BgsNgsTJJB2ZTO+6nn6pucksFTr576dJ67577HdhzH+qV81o/1/wE2laZ3jayj/TXbIYIYrri7E0QBC+1eWR4zzDFFRnJ3hQuC2i2PTJ6gjyb2KEsYcFfRi4fv1tR+VlIP+F8HhDDASbMEWsYAqSIqSKFnnoJPB8gdtuqsmXlSNxw1K5kDkghrtz5ka4wwRgFxCbM4GLIemXlqNawQ/eabkXeS40dtbFCXYd9UA0tMUHXXt//+b3wKMAA/FDE+b522vgAAAABJRU5ErkJggg==)}.cms-tree .heading-h4>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzZCRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzZBRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+mDLyXgAAANNJREFUeNpi/P//PwMlgHEYGAAE2kC6EUmsHkqji13FZQIIOwHxeiiNT0wMiLOBWBomxgQ15w0Qs0JpBjxiZkDsBMTfYAIsMIdAFXdjcyQS2wSIHwDxe2wGsAFxJxC/gIpJAHE5kgEgeV0g3gjEhkAcDsQVMAOYoApeAfEFqJgRVAzmTU0g5gPic0AsDcQyDEiSIA47TBCHmDkQ/4GGiTxUjh/kPCsgXo6kMRJKL0eKqUho4Hmhhc9RYhMLOk4H4i0gNgs5qQ+Yetmg4TEI8gJAgAEA5KsxwoBFcu4AAAAASUVORK5CYII=)}.cms-tree .heading-h5>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzZGRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzZFRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+x3zyIwAAAOZJREFUeNpi/P//PwMlgImBQjDwBjACgTaQbkQSq4fS6GJXcZkAwk5AvB5K4xKzA+I1SHgKSJwFas4bIGaF0gw4xEBqfwBxEZT/GyYIdghUcTc2R0JpfqgBII1/gfgTugFsQNwJxC+gYhJAXI5kADcQSwPxPCDmAOLVIDYLUmyADHgFxBegYkZQMVhMHQdiASBeAMQ+QJwIxMthkjJAzA6lGXCI3QXiKUD8BYhvQl0BMpDBCogfImErHGLIsZYOxAeBmJmUNCMHxPZATbVAfAaI/UGGkQJKgfgYNBDd4OllwHMjQIABAEoVMXBASUGAAAAAAElFTkSuQmCC)}.cms-tree .heading-h6>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMzVENjcwRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMzVENjZGRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/BEAGQAAAOhJREFUeNpi/P//PwMlgHHgDQACUvWIAbEoEL8A4rcgA7SBjEYkBfVQGl3sKhBHAnEwEH+C8ntBTgBhJyBeD6VxiclD+QFIahiYoDa8AWJWKM2AQ8wYiP9CcSgQ84MEWWBhAVXcjS2coLQkEPMCsREQawCxDRDnIxvABsSd0MABAQkgLkcygAeIvwBxCxA7AXEVSAxmABPUgFdAfAEqZgQVg3nzNxB/gHrhLVSOFyYpA8TsUJoBh9g9INYEphtxIG0PxP+A+DlIwgqIHyJhKxxiIMM2AfEtKA4nN/FJATHHIMoLlBoAEGAA/nw/0pIQ3W0AAAAASUVORK5CYII=)}.field.form-group.hidden{display:none}.cms-tree .status-number-badge>a span.jstree-pageicon:before{top:6px;right:-3px;color:#fff;padding:0 2px;font-size:9px;min-width:13px;min-height:13px;font-weight:700;line-height:13px;position:absolute;text-align:center;text-shadow:none;border-radius:7px;background-color:#d40404}ul.nav-tabs span.number-badge{color:#fff;padding:0 4px;font-size:11px;min-width:16px;min-height:16px;margin-left:4px;line-height:16px;border-radius:8px;text-align:center;font-weight:700;display:inline-block;background-color:#d40404}.message.status{margin-bottom:1.8462rem}.field.autocomplete .value-wrapper{margin-top:.5em}.field.autocomplete .value-wrapper .clear{display:none}.field.autocomplete .value-wrapper.has-value>.clear{display:inline}.field.dimensions .by{display:inline-block;line-height:30px;margin-right:.6154rem}.field.dimensions .by:last-child{display:none}.field.dimensions .by .icon:before{content:"D";font-size:16px;font-style:normal;font-weight:400;font-family:silverstripe}.field.viewports .dropdown,.field.viewports .text{min-width:140px;max-width:140px} \ No newline at end of file +.cms-tree.jstree li.hidden{display:none}.cms-tree .is-cached>a span.jstree-pageicon:after{top:0;left:0;width:16px;height:16px;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAAA/0lEQVQ4T2P4//8/RRirICkYqyApGKsgKRirICkYqyApGKsgKRirIDZ8ehMjz5nNjGuQ8a7FzHuxKsaGT6xnjHpwyvLc/3dt/0EYqHkfEDtjVYyOD61k5Dm6hmXltyfZX3+/qvi/eirT4R0LmZ1Bclg1oOO9Sxljrx3Uufjtaer/W8dMbu1bxrgFhrFqQMfrZjAdXtjNeHxWC+PpTw+D/4PwjgWM23cuZHTAqgEbXj+dUefAKsGT7++5/d80i3H35tmMTiBxrIqx4RUTGWL2LBe+uHISw8FVkxlcYOIYCnHhBZ0Mk4D42MIuBldkcRRF+PDMZoZTs1oY3FHF/zMAAFD514LNcp7PAAAAAElFTkSuQmCC);position:absolute}.cms-tree .is-disabled>a span.jstree-pageicon:after{top:0;left:0;width:16px;height:16px;content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAAA3ElEQVQ4T6XPoQvCQBTH8YHLc7ewP2RlfVFY3f6DgcH/wqg2o0kQFCZaLTOY5HCr1qF1hgtL4/kOTMevHIYPj325x90cIvoLjDZgtAGjDRhtwGgDRhsw2oDRBozI3nEmbMfkb050h4dNWz58FqJ557n6FMXwyjJ18v1Gd7hg2vCNzzRV9yShKo7pEkV0i2OlO1wwrfnZPElKSXVdU9u21HUd6Q4XTAu+6RCG/TEIqBSCSp678bjXHS6Y5vyvK9dtrr6vHkIMleep5WjU6A4XkBkfnvKNTOqpv4nI+QKF/8YumbPwcAAAAABJRU5ErkJggg==);position:absolute}.cms-tree .heading-h1>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNCREIzRDE2RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNCREIzRDE1RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+MOUuyAAAALdJREFUeNpi/P//PwMlgImBQjDwBrCATWFi0gZSjUji9VAaXewqlC0AxB/+/fvHwAAKREZGRhB2AuL1UBqXmCIQNwHxGhAfpBfZC2+AmBVK4xKTgdrOguIFKGCEKu7G4lVGKH0YiDmAuBCXAWxA3AnEL6BiEkBcjmQALODZsBkAk3gFxBegYkZQMSZcBiBLgPzHDqWxikFTLTPUGxAAFbQC4odI2AqHWCoQ34PiC+AYHM0LDAABBgBVkDNh2LuR6gAAAABJRU5ErkJggg==)}.cms-tree .heading-h2>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNCREIzRDFBRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNCREIzRDE5RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+52Ri6wAAAM9JREFUeNpi/P//PwMlgHEYGAAE2kC6EUmsHkqji12FssWA+BMQ/4CZAMJOQLweSuMSUwPi+UC8BohXAbEPSJwJauobIGaF0gw4xJ4C8QogjgfiI0AcCRJkgXkFqrgbmzeh9Fcg3gllPwJiJ3QD2IC4E4hfQMUkgLgcyQAY4AHiUCC+jmwAE9SAV0B8ASpmBBVjQtLMC8QdQMwNxFMYkCRlgJgdSjPgEBMA4nlArAF1KSj+WUDOswLi5UgaI6E0utgvIF6F5h1/xtG8wAAQYAC/dzmnYX+qBAAAAABJRU5ErkJggg==)}.cms-tree .heading-h3>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzY3RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzY2RTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+PvPC7QAAAORJREFUeNrE078LAXEYx/E7vxcyGow2u8EiSonsEn+HskgWUkZ/Ainlv8BgsNgsTJJB2ZTO+6nn6pucksFTr576dJ67577HdhzH+qV81o/1/wE2laZ3jayj/TXbIYIYrri7E0QBC+1eWR4zzDFFRnJ3hQuC2i2PTJ6gjyb2KEsYcFfRi4fv1tR+VlIP+F8HhDDASbMEWsYAqSIqSKFnnoJPB8gdtuqsmXlSNxw1K5kDkghrtz5ka4wwRgFxCbM4GLIemXlqNawQ/eabkXeS40dtbFCXYd9UA0tMUHXXt//+b3wKMAA/FDE+b522vgAAAABJRU5ErkJggg==)}.cms-tree .heading-h4>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzZCRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzZBRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+mDLyXgAAANNJREFUeNpi/P//PwMlgHEYGAAE2kC6EUmsHkqji13FZQIIOwHxeiiNT0wMiLOBWBomxgQ15w0Qs0JpBjxiZkDsBMTfYAIsMIdAFXdjcyQS2wSIHwDxe2wGsAFxJxC/gIpJAHE5kgEgeV0g3gjEhkAcDsQVMAOYoApeAfEFqJgRVAzmTU0g5gPic0AsDcQyDEiSIA47TBCHmDkQ/4GGiTxUjh/kPCsgXo6kMRJKL0eKqUho4Hmhhc9RYhMLOk4H4i0gNgs5qQ+Yetmg4TEI8gJAgAEA5KsxwoBFcu4AAAAASUVORK5CYII=)}.cms-tree .heading-h5>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMDYyNzZGRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMDYyNzZFRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+x3zyIwAAAOZJREFUeNpi/P//PwMlgImBQjDwBjACgTaQbkQSq4fS6GJXcZkAwk5AvB5K4xKzA+I1SHgKSJwFas4bIGaF0gw4xEBqfwBxEZT/GyYIdghUcTc2R0JpfqgBII1/gfgTugFsQNwJxC+gYhJAXI5kADcQSwPxPCDmAOLVIDYLUmyADHgFxBegYkZQMVhMHQdiASBeAMQ+QJwIxMthkjJAzA6lGXCI3QXiKUD8BYhvQl0BMpDBCogfImErHGLIsZYOxAeBmJmUNCMHxPZATbVAfAaI/UGGkQJKgfgYNBDd4OllwHMjQIABAEoVMXBASUGAAAAAAElFTkSuQmCC)}.cms-tree .heading-h6>a span.jstree-pageicon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2lpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDMzVENjcwRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNDMzVENjZGRTM1NjExRTA4OENEQUVCOTM3NUM0NUQ5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ1dWlkOkFDMUYyRTgzMzI0QURGMTFBQUI4QzUzOTBEODVCNUIzIiBzdFJlZjpkb2N1bWVudElEPSJ1dWlkOkM5RDM0OTY2NEEzQ0REMTFCMDhBQkJCQ0ZGMTcyMTU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/BEAGQAAAOhJREFUeNpi/P//PwMlgHHgDQACUvWIAbEoEL8A4rcgA7SBjEYkBfVQGl3sKhBHAnEwEH+C8ntBTgBhJyBeD6VxiclD+QFIahiYoDa8AWJWKM2AQ8wYiP9CcSgQ84MEWWBhAVXcjS2coLQkEPMCsREQawCxDRDnIxvABsSd0MABAQkgLkcygAeIvwBxCxA7AXEVSAxmABPUgFdAfAEqZgQVg3nzNxB/gHrhLVSOFyYpA8TsUJoBh9g9INYEphtxIG0PxP+A+DlIwgqIHyJhKxxiIMM2AfEtKA4nN/FJATHHIMoLlBoAEGAA/nw/0pIQ3W0AAAAASUVORK5CYII=)}.field.form-group.hidden{display:none}.cms-tree .status-number-badge>a span.jstree-pageicon:before{top:6px;right:-3px;color:#fff;padding:0 2px;font-size:9px;min-width:13px;min-height:13px;font-weight:700;line-height:13px;position:absolute;text-align:center;text-shadow:none;border-radius:7px;background-color:#d40404}ul.nav-tabs span.number-badge{color:#fff;padding:0 4px;font-size:11px;min-width:16px;min-height:16px;margin-left:4px;line-height:16px;border-radius:8px;text-align:center;font-weight:700;display:inline-block;background-color:#d40404}.message.status{margin-bottom:1.8462rem}.field.dimensions .by{display:inline-block;line-height:30px;margin-right:.6154rem}.field.dimensions .by:last-child{display:none}.field.dimensions .by .icon:before{content:"D";font-size:16px;font-style:normal;font-weight:400;font-family:silverstripe}.field.viewports .dropdown,.field.viewports .text{min-width:140px;max-width:140px} \ No newline at end of file diff --git a/admin/client/src/bundles/bundle.js b/admin/client/src/bundles/bundle.js index 98ef6bd..a1950e9 100644 --- a/admin/client/src/bundles/bundle.js +++ b/admin/client/src/bundles/bundle.js @@ -12,4 +12,4 @@ require('entwine/ListViewExtension.js'); // Load Form Fields: -require('forms/AutoCompleteField.js'); +require('forms/ToggleGroup.js'); diff --git a/admin/client/src/forms/AutoCompleteField.js b/admin/client/src/forms/AutoCompleteField.js deleted file mode 100644 index 83e2b29..0000000 --- a/admin/client/src/forms/AutoCompleteField.js +++ /dev/null @@ -1,152 +0,0 @@ -/* Auto Complete Field -===================================================================================================================== */ - -import $ from 'jquery'; - -$.entwine('ss.autocompletefield', function($) { - - // Handle Autocomplete Fields: - - $('.field.autocomplete input.text').entwine({ - - // Handle onMatch: - - onmatch: function() { - - // Call Super: - - this._super(); - - // Initialise: - - this.initField(); - this.initClear(); - - }, - - // Handle onFocusIn: - - onfocusin: function() { - if (this.getValue() >= this.getMinLength()) { - $(this).autocomplete('search'); - } - }, - - // Initialise Field: - - initField: function() { - - var self = this; - - $(this).autocomplete({ - source: self.getSourceURL(), - minLength: self.getMinLength(), - delay: self.getDelay(), - change: function (event, ui) { - self.update(event, ui); - }, - select: function(event, ui) { - self.update(event, ui); - } - }); - - }, - - // Initialise Clear: - - initClear: function() { - - var self = this; - - $(this).parent().find('a.clear').click(function(e) { - e.preventDefault(); - self.clearValue(); - }); - - }, - - setValue: function(val) { - $(this).val(val); - }, - - getValue: function() { - return $(this).val(); - }, - - getSourceURL: function() { - return $(this).attr('data-source-url'); - }, - - getMinLength: function() { - return $(this).attr('data-min-length'); - }, - - isFreeTextAllowed: function() { - return $(this).attr('data-free-text') ? true : false; - }, - - getDelay: function() { - return $(this).attr('data-delay'); - }, - - getEmptyValue: function() { - return $(this).attr('data-empty-value'); - }, - - getHiddenInput: function() { - return $(this).parent().find(':hidden'); - }, - - getValueWrapper: function() { - return $(this).parent().find('.value-wrapper'); - }, - - getValueElement: function() { - return $(this).parent().find('.value-wrapper > .value'); - }, - - // Update Field: - - update: function(event, ui) { - - var value = this.getValue(); - - if (value) { - - if (ui.item) { - this.updateValue(ui.item.value, ui.item.label); - } else if (this.isFreeTextAllowed()) { - this.updateValue(value); - } - - } - - }, - - // Update Value: - - updateValue: function(value, label) { - - if (!label) { - label = value; - } - - if (this.getHiddenInput().val() !== value) { - this.getHiddenInput().val(value); - this.getValueElement().text(label); - this.getValueWrapper().addClass('has-value'); - } - - }, - - // Clear Value: - - clearValue: function() { - this.getHiddenInput().val(''); - this.getValueElement().text(this.getEmptyValue()); - this.getValueWrapper().removeClass('has-value'); - } - - }); - -}); diff --git a/admin/client/src/forms/ToggleGroup.js b/admin/client/src/forms/ToggleGroup.js new file mode 100644 index 0000000..a15e5e7 --- /dev/null +++ b/admin/client/src/forms/ToggleGroup.js @@ -0,0 +1,58 @@ +/* Toggle Group +===================================================================================================================== */ + +import $ from 'jquery'; + +$.entwine('silverware.togglegroup', function($) { + + // Handle Toggle Groups: + + $('.field.togglegroup').entwine({ + + onmatch: function() { + + var $self = $(this); + + $self.doToggle(); + + $self.getToggleInput().entwine({ + + onclick: function(e) { + $self.doToggle(); + this._super(e); + } + + }); + + this._super(); + + }, + + doToggle: function() { + + var $input = $(this.getToggleInput()); + var whenChecked = this.getToggleMode(); + + this.getFields().toggle(whenChecked ? $input.is(':checked') : !$input.is(':checked')); + + }, + + getToggle: function() { + return $(this).find('.group-toggle'); + }, + + getFields: function() { + return $(this).find('.group-fields'); + }, + + getToggleInput: function() { + return this.getToggle().find('input'); + }, + + getToggleMode: function() { + return this.getToggle().data('show-when-checked'); + } + + }); + +}); diff --git a/admin/client/src/images/icons/ListPage.png b/admin/client/src/images/icons/ListPage.png new file mode 100644 index 0000000000000000000000000000000000000000..a2a4a08985f27483f1b271367e858441eb74ac1a GIT binary patch literal 610 zcmV-o0-gPdP)?RpkRaKl z!JVD-z1K`!Nhl7yeZ$Q6zWLravsR+7sfn(dSXsuK#VPSn8*>rmG?D%-x)Hx9aHW$C!dX2)! z4;-GHAeBm?yQ>RO3fXK{+DRsp*mm7=8-Zd4M6f&h6Pkc;`}-xcAO8Rfidr<-HiA$o zX~F$GiA;VTN5vu%i3Do3nq>BeGb>u4KyKmViY=f$ zdb($HGOO@zZ{>6os?#mdvz7Vsdx!@^~YM#V}Rx`6y w&Ci-5ifs{8ecyZ0+dGFR3?lK&{I38500#3ktt9ak-v9sr07*qoM6N<$f@F3SBLDyZ literal 0 HcmV?d00001 diff --git a/admin/client/src/images/icons/ListSourceSlide.png b/admin/client/src/images/icons/ListSourceSlide.png new file mode 100644 index 0000000000000000000000000000000000000000..212067fa11f692edbe7585d4938cad17af330b9e GIT binary patch literal 566 zcmV-60?GY}P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^MlX|MGF00E{+L_t(IPoSp46J^5IQ?BE(4HezA^}m$^J?Vy(A{6<+QGrq!$1HBe*d4G-P|Dg z^@VD^zB8|~%HTpgnM5VWb>&sA>zzd`kwBS7)16njM(4!q=O;?lY8|5;WK9SM*+?%p znbz_0@qv<-mR?3X$l5w~gdUqOh0f}OcFG5h#fxU6M^x^Z+ClXF9mOhDAEO;)9hyIf zbt4SRS_tNqD@-f}F}ipGP7pO{w?t*f_BJB17-UMNp3x4n4%mYjafZOpUBWI1rdNYd zo4jc3*@sfICn`JKZbaj8NXyHI80{cypXC~yB@E-jEp`td;5mK-KXZX*{uKR=u&6Ap zs5p@n6^$3j .clear { - display: inline; - } - - } - - } - -} diff --git a/client/dist/js/bundle.js b/client/dist/js/bundle.js index 03cdc60..83a3a64 100644 --- a/client/dist/js/bundle.js +++ b/client/dist/js/bundle.js @@ -1 +1 @@ -!function(t){function i(s){if(e[s])return e[s].exports;var n=e[s]={i:s,l:!1,exports:{}};return t[s].call(n.exports,n,n.exports,i),n.l=!0,n.exports}var e={};i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:s})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},i.p="/silverware/client/dist/",i(i.s=1)}([function(t,i){t.exports=jQuery},function(t,i,e){e(2),e(3),e(4),e(5)},function(t,i){},function(t,i,e){(function(t){var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(e){"use strict";function s(t){return void 0!==t}function n(t){return"object"==(void 0===t?"undefined":i(t))&&null!=t}function h(t,i,e){return isNaN(t)?e:St(e,Tt(i,t))}function a(){return!1}function o(){return(new Date).valueOf()}function r(t,i){var e,s=[],n=t.length;for(e=0;e0)}function C(t,i,e,s){var n,h=t.createLinearGradient(0,0,i,0);for(n in s)h.addColorStop(1-n,s[n]);t.fillStyle=h,t.fillRect(0,e,i,1)}function z(t,i,e){var s,h,a,o,r=1024,l=1,u=t.weightGradient;if(t.gCanvas)h=t.gCanvas.getContext("2d"),l=t.gCanvas.height;else{if(n(u[0])?l=u.length:u=[u],t.gCanvas=s=S(r,l),!s)return null;for(h=s.getContext("2d"),a=0;a0?o=r*o/100:o*=n,a=h.getContext("2d"),a.globalCompositeOperation="source-over",a.fillStyle="#fff",o>=r/2?(o=St(e,s)/2,a.beginPath(),a.moveTo(e/2,s/2),a.arc(e/2,s/2,o,0,2*Math.PI,!1),a.fill(),a.closePath()):(o=St(e/2,s/2,o),I(a,0,0,e,s,o,!0),a.fill()),a.globalCompositeOperation="source-in",a.drawImage(t,0,0,e,s),h):null}function P(t,i,e,s,n,h,a){var o,r,l=xt(a[0]),u=xt(a[1]),c=i+(l>h?l+h:2*h)*s,g=e+(u>h?u+h:2*h)*s,f=s*((h||0)+(a[0]<0?l:0)),d=s*((h||0)+(a[1]<0?u:0));return(o=S(c,g))?(r=o.getContext("2d"),n&&(r.shadowColor=n),h&&(r.shadowBlur=h*s),a&&(r.shadowOffsetX=a[0]*s,r.shadowOffsetY=a[1]*s),r.drawImage(t,f,d,i,e),{image:o,width:c/s,height:g/s}):null}function E(t,i,e){var s,n,h,a,o,r,l,u,c=parseInt(t.toString().length*e),g=parseInt(2*e*t.length),f=S(c,g);if(!f)return null;for(s=f.getContext("2d"),s.fillStyle="#000",s.fillRect(0,0,c,g),D(s,e+"px "+i,"#fff",t,0,0,0,0,[],"centre"),n=s.getImageData(0,0,c,g),h=n.width,a=n.height,u={min:{x:h,y:a},max:{x:-1,y:-1}},r=0;r0&&(ou.max.x&&(u.max.x=o),ru.max.y&&(u.max.y=r));return h!=c&&(u.min.x*=c/h,u.max.x*=c/h),a!=g&&(u.min.y*=c/a,u.max.y*=c/a),f=null,u}function R(t){return"'"+t.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'"}function B(t,i,e){e=e||Mt,e.addEventListener?e.addEventListener(t,i,!1):e.attachEvent("on"+t,i)}function _(t,i,e){e=e||Mt,e.removeEventListener?e.removeEventListener(t,i):e.detachEvent("on"+t,i)}function N(t,i,e,s){var n,h,a,o,r,l,u=s.imageScale;return i.complete?t.complete?(i.width=i.width,i.height=i.height,u&&(t.width=i.width*u,t.height=i.height*u),e.iw=t.width,e.ih=t.height,s.txtOpt&&(h=t,n=s.zoomMax*s.txtScale,r=e.iw*n,l=e.ih*n,r0?(e.iw+=2*s.outlineIncrease,e.ih+=2*s.outlineIncrease,r=n*e.iw,l=n*e.ih,h=F(e.fimage,r,l),e.oimage=h,e.fimage=M(e.fimage,e.oimage.width,e.oimage.height)):(r=n*(e.iw+2*s.outlineIncrease),l=n*(e.ih+2*s.outlineIncrease),h=F(e.fimage,r,l),e.oimage=M(h,e.fimage.width,e.fimage.height))))),void e.Init()):B("load",function(){N(t,i,e,s)},t):B("load",function(){N(t,i,e,s)},i)}function L(t,i){var e=Mt.defaultView,s=i.replace(/\-([a-z])/g,function(t){return t.charAt(1).toUpperCase()});return e&&e.getComputedStyle&&e.getComputedStyle(t,null).getPropertyValue(i)||t.currentStyle&&t.currentStyle[s]}function H(t,i,e){var s,n=1;return i?n=1*(t.getAttribute(i)||e):(s=L(t,"font-size"))&&(n=s.indexOf("px")>-1&&1*s.replace("px","")||s.indexOf("pt")>-1&&1.25*s.replace("pt","")||3.3*s),n}function W(t){return t.target&&s(t.target.id)?t.target.id:t.srcElement.parentNode.id}function X(t,i){var e,n,h=parseInt(L(i,"width"))/i.width,a=parseInt(L(i,"height"))/i.height;return s(t.offsetX)?e={x:t.offsetX,y:t.offsetY}:(n=tt(i.id),s(t.changedTouches)&&(t=t.changedTouches[0]),t.pageX&&(e={x:t.pageX-n.x,y:t.pageY-n.y})),e&&h&&a&&(e.x/=h,e.y/=a),e}function Y(t){var i=t.target||t.fromElement.parentNode,e=ht.tc[i.id];e&&(e.mx=e.my=-1,e.UnFreeze(),e.EndDrag())}function U(t){var i,e,s,n=ht,h=W(t);for(i in n.tc)e=n.tc[i],e.tttimer&&(clearTimeout(e.tttimer),e.tttimer=null);h&&n.tc[h]&&(e=n.tc[h],(s=X(t,e.canvas))&&(e.mx=s.x,e.my=s.y,e.Drag(t,s)),e.drawn=0)}function V(t){var i=ht,e=Mt.addEventListener?0:1,s=W(t);s&&t.button==e&&i.tc[s]&&i.tc[s].BeginDrag(t)}function j(t){var i,e=ht,s=Mt.addEventListener?0:1,n=W(t);n&&t.button==s&&e.tc[n]&&(i=e.tc[n],U(t),i.EndDrag()||i.touchState||i.Clicked(t))}function q(t){var i,e=W(t),s=e&&ht.tc[e];s&&t.changedTouches&&(1==t.touches.length&&0==s.touchState?(s.touchState=1,s.BeginDrag(t),(i=X(t,s.canvas))&&(s.mx=i.x,s.my=i.y,s.drawn=0)):2==t.targetTouches.length&&s.pinchZoom?(s.touchState=3,s.EndDrag(),s.BeginPinch(t)):(s.EndDrag(),s.EndPinch(),s.touchState=0))}function G(t){var i=W(t),e=i&&ht.tc[i];if(e&&t.changedTouches){switch(e.touchState){case 1:e.Draw(),e.Clicked();break;case 2:e.EndDrag();break;case 3:e.EndPinch()}e.touchState=0}}function Z(t){var i,e,s,n=ht,h=W(t);for(i in n.tc)e=n.tc[i],e.tttimer&&(clearTimeout(e.tttimer),e.tttimer=null);if((e=h&&n.tc[h])&&t.changedTouches&&e.touchState){switch(e.touchState){case 1:case 2:(s=X(t,e.canvas))&&(e.mx=s.x,e.my=s.y,e.Drag(t,s)&&(e.touchState=2));break;case 3:e.Pinch(t)}e.drawn=0}}function Q(t){var i=ht,e=W(t);e&&i.tc[e]&&(t.cancelBubble=!0,t.returnValue=!1,t.preventDefault&&t.preventDefault(),i.tc[e].Wheel((t.wheelDelta||t.detail)>0))}function J(t){var i,e=ht;clearTimeout(e.scrollTimer);for(i in e.tc)e.tc[i].Pause();e.scrollTimer=setTimeout(function(){var t,i=ht;for(t in i.tc)i.tc[t].Resume()},e.scrollPause)}function K(){$(o())}function $(t){var i,e=ht.tc;ht.NextFrame(ht.interval),t=t||o();for(i in e)e[i].Draw(t)}function tt(t){var i=Mt.getElementById(t),e=i.getBoundingClientRect(),s=Mt.documentElement,n=Mt.body,h=window,a=h.pageXOffset||s.scrollLeft,o=h.pageYOffset||s.scrollTop,r=s.clientLeft||n.clientLeft,l=s.clientTop||n.clientTop;return{x:e.left+a-r,y:e.top+o-l}}function it(t,i,e,s){var n=t.radius*t.z1/(t.z1+t.z2+i.z);return{x:i.x*n*e,y:i.y*n*s,z:i.z,w:(t.z1-i.z)/t.z2}}function et(t){this.e=t,this.br=0,this.line=[],this.text=[],this.original=t.innerText||t.textContent}function st(t,i){this.ts=null,this.tc=t,this.tag=i,this.x=this.y=this.w=this.h=this.sc=1,this.z=0,this.pulse=1,this.pulsate=t.pulsateTo<1,this.colour=t.outlineColour,this.adash=~~t.outlineDash,this.agap=~~t.outlineDashSpace||this.adash,this.aspeed=1*t.outlineDashSpeed,"tag"==this.colour?this.colour=L(i.a,"color"):"tagbg"==this.colour&&(this.colour=L(i.a,"background-color")),this.Draw=this.pulsate?this.DrawPulsate:this.DrawSimple,this.radius=0|t.outlineRadius,this.SetMethod(t.outlineMethod)}function nt(t,i,e,s,n,h,a,o,r,l,c,g,f,d){this.tc=t,this.image=null,this.text=i,this.text_original=d,this.line_widths=[],this.title=e.title||null,this.a=e,this.position=new u(s[0],s[1],s[2]),this.x=this.y=this.z=0,this.w=n,this.h=h,this.colour=a||t.textColour,this.bgColour=o||t.bgColour,this.bgRadius=0|r,this.bgOutline=l||this.colour,this.bgOutlineThickness=0|c,this.textFont=g||t.textFont,this.padding=0|f,this.sc=this.alpha=1,this.weighted=!t.weight,this.outline=new st(t,this)}function ht(t,i,e){var n,r,l,u=Mt.getElementById(t),c=["id","class","innerHTML"];if(!u)throw 0;if(s(window.G_vmlCanvasManager)&&(u=window.G_vmlCanvasManager.initElement(u),this.ie=parseFloat(navigator.appVersion.split("MSIE")[1])),u&&(!u.getContext||!u.getContext("2d").fillText)){for(r=Mt.createElement("DIV"),n=0;n0?ht.scrollPause=~~this.scrollPause:this.scrollPause=0,this.minTags>0&&this.repeatTags<1&&(n=this.GetTags().length)&&(this.repeatTags=bt(this.minTags/n)-1),this.transform=g.Identity(),this.startTime=this.time=o(),this.mx=this.my=-1,this.centreImage&&y(this),this.Animate=this.dragControl?this.AnimateDrag:this.AnimatePosition,this.animTiming="function"==typeof ht[this.animTiming]?ht[this.animTiming]:ht.Smooth,this.shadowBlur||this.shadowOffset[0]||this.shadowOffset[1]?(this.ctxt.shadowColor=this.shadow,this.shadow=this.ctxt.shadowColor,this.shadowAlpha=b()):delete this.shadow,this.Load(),i&&this.hideTags&&function(t){ht.loaded?t.HideTags():B("load",function(){t.HideTags()},window)}(this),this.yaw=this.initial?this.initial[0]*this.maxSpeed:0,this.pitch=this.initial?this.initial[1]*this.maxSpeed:0,this.tooltip?(this.ctitle=u.title,u.title="","native"==this.tooltip?this.Tooltip=this.TooltipNative:(this.Tooltip=this.TooltipDiv,this.ttdiv||(this.ttdiv=Mt.createElement("div"),this.ttdiv.className=this.tooltipClass,this.ttdiv.style.position="absolute",this.ttdiv.style.zIndex=u.style.zIndex+1,B("mouseover",function(t){t.target.style.display="none"},this.ttdiv),Mt.body.appendChild(this.ttdiv)))):this.Tooltip=this.TooltipNone,!this.noMouse&&!Ft[t])for(Ft[t]=[["mousemove",U],["mouseout",Y],["mouseup",j],["touchstart",q],["touchend",G],["touchcancel",G],["touchmove",Z]],this.dragControl&&(Ft[t].push(["mousedown",V]),Ft[t].push(["selectstart",a])),this.wheelZoom&&(Ft[t].push(["mousewheel",Q]),Ft[t].push(["DOMMouseScroll",Q])),this.scrollPause&&Ft[t].push(["scroll",J,window]),n=0;n=1?0:i<=-1?Math.PI:Math.acos(i))},dt.unit=function(){var t=this.length();return new u(this.x/t,this.y/t,this.z/t)},ft=g.prototype,g.Identity=function(){return new g([1,0,0,0,1,0,0,0,1])},g.Rotation=function(t,i){var e=vt(t),s=yt(t),n=1-s;return new g([s+zt(i.x,2)*n,i.x*i.y*n-i.z*e,i.x*i.z*n+i.y*e,i.y*i.x*n+i.z*e,s+zt(i.y,2)*n,i.y*i.z*n-i.x*e,i.z*i.x*n-i.y*e,i.z*i.y*n+i.x*e,s+zt(i.z,2)*n])},ft.mul=function(t){var i,e,s=[],n=t.xform?1:0;for(i=1;i<=3;++i)for(e=1;e<=3;++e)n?s.push(this[i][1]*t[1][e]+this[i][2]*t[2][e]+this[i][3]*t[3][e]):s.push(this[i][e]*t);return new g(s)},ft.xform=function(t){var i={},e=t.x,s=t.y,n=t.z;return i.x=e*this[1][1]+s*this[2][1]+n*this[3][1],i.y=e*this[1][2]+s*this[2][2]+n*this[3][2],i.z=e*this[1][3]+s*this[2][3]+n*this[3][3],i},pt=A.prototype,pt.SetImage=function(t,i,e,s,n,h,a,o){this.image=t,this.iwidth=i*this.scale,this.iheight=e*this.scale,this.ipos=s,this.ipad=n*this.scale,this.iscale=o,this.ialign=h,this.ivalign=a},pt.Align=function(t,i,e){var s=0;return"right"==e||"bottom"==e?s=i-t:"left"!=e&&"top"!=e&&(s=(i-t)/2),s},pt.Create=function(t,i,e,s,n,h,a,o,r){var l,u,c,g,f,d,m,p,w,x,v,y,T,b,C,z,A,M=xt(a[0]),F=xt(a[1]);return o=Tt(o,M+h,F+h),f=2*(o+s),m=2*(o+s),u=this.width+f,c=this.height+m,w=x=o+s,this.image&&(v=y=o+s,T=this.iwidth,b=this.iheight,"top"==this.ipos||"bottom"==this.ipos?(Tt?(o.push(this.line.join(" ")),this.line=[a[h]]):this.line.push(a[h]);o.push(this.line.join(" "))}return this.text=o},ut=st.prototype,ut.SetMethod=function(t){var i={block:["PreDraw","DrawBlock"],colour:["PreDraw","DrawColour"],outline:["PostDraw","DrawOutline"],classic:["LastDraw","DrawOutline"],size:["PreDraw","DrawSize"],none:["LastDraw"]},e=i[t]||i.outline;"none"==t?this.Draw=function(){return 1}:this.drawFunc=this[e[1]],this[e[0]]=this.Draw},ut.Update=function(t,i,e,s,n,h,a,o){var r=this.tc.outlineOffset,l=2*r;this.x=n*t+a-r,this.y=n*i+o-r,this.w=n*e+l,this.h=n*s+l,this.sc=n,this.z=h},ut.Ants=function(t){if(this.adash){var i,e=this.adash,s=this.agap,n=this.aspeed,h=e+s,a=0,r=e,l=s,u=0,c=0;n&&(c=xt(n)*(o()-this.ts)/50,n<0&&(c=864e4-c),n=~~c%h),n?(e>=n?(a=e-n,r=n):(l=h-n,u=s-l),i=[a,l,r,u]):i=[e,s],t.setLineDash(i)}},ut.DrawOutline=function(t,i,e,s,n,h){var a=St(this.radius,n/2,s/2);t.strokeStyle=h,this.Ants(t),I(t,i,e,s,n,a,!0)},ut.DrawSize=function(t,i,e,s,n,h,a,o,r){var l,u,c,g=a.w,f=a.h;return this.pulsate?(c=a.image?(a.image.height+this.tc.outlineIncrease)/a.image.height:a.oscale,u=a.fimage||a.image,l=1+(c-1)*(1-this.pulse),a.h*=l,a.w*=l):u=a.oimage,a.alpha=1,a.Draw(t,o,r,u),a.h=f,a.w=g,1},ut.DrawColour=function(t,i,e,s,n,h,a,o,r){return a.oimage?(this.pulse<1?(a.alpha=1-zt(this.pulse,2),a.Draw(t,o,r,a.fimage),a.alpha=this.pulse):a.alpha=1,a.Draw(t,o,r,a.oimage),1):this[a.image?"DrawColourImage":"DrawColourText"](t,i,e,s,n,h,a,o,r)},ut.DrawColourText=function(t,i,e,s,n,h,a,o,r){var l=a.colour;return a.colour=h,a.alpha=1,a.Draw(t,o,r),a.colour=l,1},ut.DrawColourImage=function(t,i,e,s,n,h,a,o,r){var l,u=t.canvas,c=~~Tt(i,0),g=~~Tt(e,0),f=St(u.width-c,s)+.5|0,d=St(u.height-g,n)+.5|0;return wt?(wt.width=f,wt.height=d):wt=S(f,d),wt?(l=wt.getContext("2d"),l.drawImage(u,c,g,f,d,0,0,f,d),t.clearRect(c,g,f,d),this.pulsate?a.alpha=1-zt(this.pulse,2):a.alpha=1,a.Draw(t,o,r),t.setTransform(1,0,0,1,0,0),t.save(),t.beginPath(),t.rect(c,g,f,d),t.clip(),t.globalCompositeOperation="source-in",t.fillStyle=h,t.fillRect(c,g,f,d),t.restore(),t.globalAlpha=1,t.globalCompositeOperation="destination-over",t.drawImage(wt,0,0,f,d,c,g,f,d),t.globalCompositeOperation="source-over",1):this.SetMethod("outline")},ut.DrawBlock=function(t,i,e,s,n,h){var a=St(this.radius,n/2,s/2);t.fillStyle=h,I(t,i,e,s,n,a)},ut.DrawSimple=function(t,i,e,s,n,h){var a=this.tc;return t.setTransform(1,0,0,1,0,0),t.strokeStyle=this.colour,t.lineWidth=a.outlineThickness,t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0,t.globalAlpha=h?n:1,this.drawFunc(t,this.x,this.y,this.w,this.h,this.colour,i,e,s)},ut.DrawPulsate=function(t,i,e,s){var n=o()-this.ts,h=this.tc,a=h.pulsateTo+(1-h.pulsateTo)*(.5+yt(2*Math.PI*n/(1e3*h.pulsateTime))/2);return this.pulse=a=ht.Smooth(1,a),this.DrawSimple(t,i,e,s,a,1)},ut.Active=function(t,i,e){var s=i>=this.x&&e>=this.y&&i<=this.x+this.w&&e<=this.y+this.h;return this.ts=s?this.ts||o():null,s},ut.PreDraw=ut.PostDraw=ut.LastDraw=a,ct=nt.prototype,ct.Init=function(t){var i=this.tc;this.textHeight=i.textHeight,this.HasText()?this.Measure(i.ctxt,i):(this.w=this.iw,this.h=this.ih),this.SetShadowColour=i.shadowAlpha?this.SetShadowColourAlpha:this.SetShadowColourFixed,this.SetDraw(i)},ct.Draw=a,ct.HasText=function(){return this.text&&this.text[0].length>0},ct.EqualTo=function(t){var i=t.getElementsByTagName("img");return this.a.href!=t.href?0:i.length?this.image.src==i[0].src:(t.innerText||t.textContent)==this.text_original},ct.SetImage=function(t){this.image=this.fimage=t},ct.SetDraw=function(t){this.Draw=this.fimage?t.ie>7?this.DrawImageIE:this.DrawImage:this.DrawText,t.noSelect&&(this.CheckActive=a)},ct.MeasureText=function(t){var i,e,s=this.text.length,n=0;for(i=0;i0?l=M(l,this.oimage.width,this.oimage.height):this.oimage=M(this.oimage,l.width,l.height)),l&&(this.fimage=l,o=this.fimage.width/e,r=this.fimage.height/e),this.SetDraw(i),i.txtOpt=!!this.fimage),this.h=r,this.w=o},ct.SetFont=function(t,i,e,s){this.textFont=t,this.colour=i,this.bgColour=e,this.bgOutline=s,this.Measure(this.tc.ctxt,this.tc)},ct.SetWeight=function(t){var i,e,s=this.tc,n=s.weightMode.split(/[, ]/),h=t.length;if(this.HasText()){for(this.weighted=!0,e=0;e0&&e.weightSizeMax>e.weightSizeMin?this.textHeight=e.weightSize*(e.weightSizeMin+(e.weightSizeMax-e.weightSizeMin)*o):this.textHeight=Tt(1,t*e.weightSize))},ct.SetShadowColourFixed=function(t,i,e){t.shadowColor=i},ct.SetShadowColourAlpha=function(t,i,e){t.shadowColor=T(i,e)},ct.DrawText=function(t,i,e){var s,n,h=this.tc,a=this.x,o=this.y,r=this.sc;for(t.globalAlpha=this.alpha,t.fillStyle=this.colour,h.shadow&&this.SetShadowColour(t,h.shadow,this.alpha),t.font=this.font,a+=i/r,o+=e/r-this.h/2,s=0;sthis.max_weight[s])&&(this.max_weight[s]=i),(!this.min_weight[s]||ithis.min_weight[s]&&(n=1);if(n)for(e=0;e=0&&this.my>=0&&this.taglist[s].CheckActive(d,g,f))&&e.sc>u&&(!x||e.z<=0)&&(i=e,m=s,i.tag=this.taglist[s],u=e.sc);this.active=i}for(this.txtOpt||this.shadow&&this.SetShadow(d),d.clearRect(0,0,o,l),s=0;s=this.fadeIn?(this.fadeIn=0,this.fixedAlpha=1):this.fixedAlpha=i/this.fadeIn),!!this.fixedAnim&&(this.fixedAnim.transform||(this.fixedAnim.transform=this.transform),t=this.fixedAnim,i=o()-t.t0,e=t.angle,n=this.animTiming(t.t,i),this.transform=t.transform,i>=t.t?(this.fixedCallbackTag=t.tag,this.fixedCallback=t.cb,this.fixedAnim=this.yaw=this.pitch=0):e*=n,s=g.Rotation(e,t.axis),this.transform=this.transform.mul(s),0!=this.fixedAnim)},gt.AnimatePosition=function(t,i,e){var s,n,h=this,a=h.mx,o=h.my;!h.frozen&&a>=0&&o>=0&&ai&&(t.yaw=e>t.z0?t.yaw*t.decel:0),!t.ly&&s>i&&(t.pitch=s>t.z0?t.pitch*t.decel:0)},gt.Zoom=function(t){this.z2=this.z1*(1/t),this.drawn=0},gt.Clicked=function(t){var i=this.active;try{i&&i.tag&&(!1===this.clickToFront||null===this.clickToFront?i.tag.Clicked(t):this.TagToFront(i.tag,this.clickToFront,function(){i.tag.Clicked(t)},!0))}catch(t){}},gt.Wheel=function(t){var i=this.zoom+this.zoomStep*(t?1:-1);this.zoom=St(this.zoomMax,Tt(this.zoomMin,i)),this.Zoom(this.zoom)},gt.BeginDrag=function(t){this.down=X(t,this.canvas),t.cancelBubble=!0,t.returnValue=!1,t.preventDefault&&t.preventDefault()},gt.Drag=function(t,i){if(this.dragControl&&this.down){var e=this.dragThreshold*this.dragThreshold,s=i.x-this.down.x,n=i.y-this.down.y;(this.dragging||s*s+n*n>e)&&(this.dx=s,this.dy=n,this.dragging=1,this.down=i)}return this.dragging},gt.EndDrag=function(){var t=this.dragging;return this.dragging=this.down=null,t},gt.BeginPinch=function(t){this.pinched=[at(t),this.zoom],t.preventDefault&&t.preventDefault()},gt.Pinch=function(t){var i,e,s=this.pinched;s&&(e=at(t),i=s[1]*e/s[0],this.zoom=St(this.zoomMax,Tt(this.zoomMin,i)),this.Zoom(this.zoom))},gt.EndPinch=function(t){this.pinched=null},gt.Pause=function(){this.paused=!0},gt.Resume=function(){this.paused=!1},gt.SetSpeed=function(t){this.initial=t,this.yaw=t[0]*this.maxSpeed,this.pitch=t[1]*this.maxSpeed},gt.FindTag=function(t){if(!s(t))return null;if(s(t.index)&&(t=t.index),!n(t))return this.taglist[t];var i,e,h;for(s(t.id)?(i="id",e=t.id):s(t.text)&&(i="innerText",e=t.text),h=0;hi?t.addClass("is-visible"):t.removeClass("is-visible fade-out"),n()(this).scrollTop()>e&&t.addClass("fade-out")}),t.on("click",function(t){t.preventDefault(),n()("body, html").animate({scrollTop:0},s)})})})},function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var s=e(0),n=e.n(s);n()(function(){n()(".tagcloudcomponent").each(function(){var t=n()(this);n()(t.data("canvas")).tagcanvas({depth:parseFloat(t.data("depth")),zoom:parseFloat(t.data("zoom")),zoomMin:parseFloat(t.data("zoom-min")),zoomMax:parseFloat(t.data("zoom-max")),textColour:t.data("color-text"),outlineColour:t.data("color-outline"),initial:t.data("initial"),weightSizeMin:parseInt(t.data("weight-size-min")),weightSizeMax:parseInt(t.data("weight-size-max")),weightFrom:"data-weight",weight:t.data("weight")},t.data("tag-list"))});var t=null,i=function(){n()(".tagcloudcomponent").each(function(){var t=n()(this),i=n()(t.data("canvas")),e=t.width();i.attr("width",e)})};n()(window).resize(function(){null!==t&&clearTimeout(t),t=setTimeout(i,500)}),i()})}]); \ No newline at end of file +!function(t){function i(s){if(e[s])return e[s].exports;var n=e[s]={i:s,l:!1,exports:{}};return t[s].call(n.exports,n,n.exports,i),n.l=!0,n.exports}var e={};i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:s})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},i.p="/silverware/client/dist/",i(i.s=1)}([function(t,i){t.exports=jQuery},function(t,i,e){e(2),e(3),e(4),e(5),e(6),e(7)},function(t,i){},function(t,i,e){(function(t){var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(e){"use strict";function s(t){return void 0!==t}function n(t){return"object"==(void 0===t?"undefined":i(t))&&null!=t}function a(t,i,e){return isNaN(t)?e:St(e,Tt(i,t))}function h(){return!1}function o(){return(new Date).valueOf()}function r(t,i){var e,s=[],n=t.length;for(e=0;e0)}function C(t,i,e,s){var n,a=t.createLinearGradient(0,0,i,0);for(n in s)a.addColorStop(1-n,s[n]);t.fillStyle=a,t.fillRect(0,e,i,1)}function z(t,i,e){var s,a,h,o,r=1024,l=1,u=t.weightGradient;if(t.gCanvas)a=t.gCanvas.getContext("2d"),l=t.gCanvas.height;else{if(n(u[0])?l=u.length:u=[u],t.gCanvas=s=S(r,l),!s)return null;for(a=s.getContext("2d"),h=0;h0?o=r*o/100:o*=n,h=a.getContext("2d"),h.globalCompositeOperation="source-over",h.fillStyle="#fff",o>=r/2?(o=St(e,s)/2,h.beginPath(),h.moveTo(e/2,s/2),h.arc(e/2,s/2,o,0,2*Math.PI,!1),h.fill(),h.closePath()):(o=St(e/2,s/2,o),I(h,0,0,e,s,o,!0),h.fill()),h.globalCompositeOperation="source-in",h.drawImage(t,0,0,e,s),a):null}function P(t,i,e,s,n,a,h){var o,r,l=xt(h[0]),u=xt(h[1]),c=i+(l>a?l+a:2*a)*s,g=e+(u>a?u+a:2*a)*s,f=s*((a||0)+(h[0]<0?l:0)),d=s*((a||0)+(h[1]<0?u:0));return(o=S(c,g))?(r=o.getContext("2d"),n&&(r.shadowColor=n),a&&(r.shadowBlur=a*s),h&&(r.shadowOffsetX=h[0]*s,r.shadowOffsetY=h[1]*s),r.drawImage(t,f,d,i,e),{image:o,width:c/s,height:g/s}):null}function E(t,i,e){var s,n,a,h,o,r,l,u,c=parseInt(t.toString().length*e),g=parseInt(2*e*t.length),f=S(c,g);if(!f)return null;for(s=f.getContext("2d"),s.fillStyle="#000",s.fillRect(0,0,c,g),D(s,e+"px "+i,"#fff",t,0,0,0,0,[],"centre"),n=s.getImageData(0,0,c,g),a=n.width,h=n.height,u={min:{x:a,y:h},max:{x:-1,y:-1}},r=0;r0&&(ou.max.x&&(u.max.x=o),ru.max.y&&(u.max.y=r));return a!=c&&(u.min.x*=c/a,u.max.x*=c/a),h!=g&&(u.min.y*=c/h,u.max.y*=c/h),f=null,u}function B(t){return"'"+t.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'"}function R(t,i,e){e=e||At,e.addEventListener?e.addEventListener(t,i,!1):e.attachEvent("on"+t,i)}function _(t,i,e){e=e||At,e.removeEventListener?e.removeEventListener(t,i):e.detachEvent("on"+t,i)}function N(t,i,e,s){var n,a,h,o,r,l,u=s.imageScale;return i.complete?t.complete?(i.width=i.width,i.height=i.height,u&&(t.width=i.width*u,t.height=i.height*u),e.iw=t.width,e.ih=t.height,s.txtOpt&&(a=t,n=s.zoomMax*s.txtScale,r=e.iw*n,l=e.ih*n,r0?(e.iw+=2*s.outlineIncrease,e.ih+=2*s.outlineIncrease,r=n*e.iw,l=n*e.ih,a=F(e.fimage,r,l),e.oimage=a,e.fimage=A(e.fimage,e.oimage.width,e.oimage.height)):(r=n*(e.iw+2*s.outlineIncrease),l=n*(e.ih+2*s.outlineIncrease),a=F(e.fimage,r,l),e.oimage=A(a,e.fimage.width,e.fimage.height))))),void e.Init()):R("load",function(){N(t,i,e,s)},t):R("load",function(){N(t,i,e,s)},i)}function L(t,i){var e=At.defaultView,s=i.replace(/\-([a-z])/g,function(t){return t.charAt(1).toUpperCase()});return e&&e.getComputedStyle&&e.getComputedStyle(t,null).getPropertyValue(i)||t.currentStyle&&t.currentStyle[s]}function H(t,i,e){var s,n=1;return i?n=1*(t.getAttribute(i)||e):(s=L(t,"font-size"))&&(n=s.indexOf("px")>-1&&1*s.replace("px","")||s.indexOf("pt")>-1&&1.25*s.replace("pt","")||3.3*s),n}function W(t){return t.target&&s(t.target.id)?t.target.id:t.srcElement.parentNode.id}function X(t,i){var e,n,a=parseInt(L(i,"width"))/i.width,h=parseInt(L(i,"height"))/i.height;return s(t.offsetX)?e={x:t.offsetX,y:t.offsetY}:(n=tt(i.id),s(t.changedTouches)&&(t=t.changedTouches[0]),t.pageX&&(e={x:t.pageX-n.x,y:t.pageY-n.y})),e&&a&&h&&(e.x/=a,e.y/=h),e}function j(t){var i=t.target||t.fromElement.parentNode,e=at.tc[i.id];e&&(e.mx=e.my=-1,e.UnFreeze(),e.EndDrag())}function Y(t){var i,e,s,n=at,a=W(t);for(i in n.tc)e=n.tc[i],e.tttimer&&(clearTimeout(e.tttimer),e.tttimer=null);a&&n.tc[a]&&(e=n.tc[a],(s=X(t,e.canvas))&&(e.mx=s.x,e.my=s.y,e.Drag(t,s)),e.drawn=0)}function U(t){var i=at,e=At.addEventListener?0:1,s=W(t);s&&t.button==e&&i.tc[s]&&i.tc[s].BeginDrag(t)}function V(t){var i,e=at,s=At.addEventListener?0:1,n=W(t);n&&t.button==s&&e.tc[n]&&(i=e.tc[n],Y(t),i.EndDrag()||i.touchState||i.Clicked(t))}function q(t){var i,e=W(t),s=e&&at.tc[e];s&&t.changedTouches&&(1==t.touches.length&&0==s.touchState?(s.touchState=1,s.BeginDrag(t),(i=X(t,s.canvas))&&(s.mx=i.x,s.my=i.y,s.drawn=0)):2==t.targetTouches.length&&s.pinchZoom?(s.touchState=3,s.EndDrag(),s.BeginPinch(t)):(s.EndDrag(),s.EndPinch(),s.touchState=0))}function G(t){var i=W(t),e=i&&at.tc[i];if(e&&t.changedTouches){switch(e.touchState){case 1:e.Draw(),e.Clicked();break;case 2:e.EndDrag();break;case 3:e.EndPinch()}e.touchState=0}}function Z(t){var i,e,s,n=at,a=W(t);for(i in n.tc)e=n.tc[i],e.tttimer&&(clearTimeout(e.tttimer),e.tttimer=null);if((e=a&&n.tc[a])&&t.changedTouches&&e.touchState){switch(e.touchState){case 1:case 2:(s=X(t,e.canvas))&&(e.mx=s.x,e.my=s.y,e.Drag(t,s)&&(e.touchState=2));break;case 3:e.Pinch(t)}e.drawn=0}}function Q(t){var i=at,e=W(t);e&&i.tc[e]&&(t.cancelBubble=!0,t.returnValue=!1,t.preventDefault&&t.preventDefault(),i.tc[e].Wheel((t.wheelDelta||t.detail)>0))}function J(t){var i,e=at;clearTimeout(e.scrollTimer);for(i in e.tc)e.tc[i].Pause();e.scrollTimer=setTimeout(function(){var t,i=at;for(t in i.tc)i.tc[t].Resume()},e.scrollPause)}function K(){$(o())}function $(t){var i,e=at.tc;at.NextFrame(at.interval),t=t||o();for(i in e)e[i].Draw(t)}function tt(t){var i=At.getElementById(t),e=i.getBoundingClientRect(),s=At.documentElement,n=At.body,a=window,h=a.pageXOffset||s.scrollLeft,o=a.pageYOffset||s.scrollTop,r=s.clientLeft||n.clientLeft,l=s.clientTop||n.clientTop;return{x:e.left+h-r,y:e.top+o-l}}function it(t,i,e,s){var n=t.radius*t.z1/(t.z1+t.z2+i.z);return{x:i.x*n*e,y:i.y*n*s,z:i.z,w:(t.z1-i.z)/t.z2}}function et(t){this.e=t,this.br=0,this.line=[],this.text=[],this.original=t.innerText||t.textContent}function st(t,i){this.ts=null,this.tc=t,this.tag=i,this.x=this.y=this.w=this.h=this.sc=1,this.z=0,this.pulse=1,this.pulsate=t.pulsateTo<1,this.colour=t.outlineColour,this.adash=~~t.outlineDash,this.agap=~~t.outlineDashSpace||this.adash,this.aspeed=1*t.outlineDashSpeed,"tag"==this.colour?this.colour=L(i.a,"color"):"tagbg"==this.colour&&(this.colour=L(i.a,"background-color")),this.Draw=this.pulsate?this.DrawPulsate:this.DrawSimple,this.radius=0|t.outlineRadius,this.SetMethod(t.outlineMethod)}function nt(t,i,e,s,n,a,h,o,r,l,c,g,f,d){this.tc=t,this.image=null,this.text=i,this.text_original=d,this.line_widths=[],this.title=e.title||null,this.a=e,this.position=new u(s[0],s[1],s[2]),this.x=this.y=this.z=0,this.w=n,this.h=a,this.colour=h||t.textColour,this.bgColour=o||t.bgColour,this.bgRadius=0|r,this.bgOutline=l||this.colour,this.bgOutlineThickness=0|c,this.textFont=g||t.textFont,this.padding=0|f,this.sc=this.alpha=1,this.weighted=!t.weight,this.outline=new st(t,this)}function at(t,i,e){var n,r,l,u=At.getElementById(t),c=["id","class","innerHTML"];if(!u)throw 0;if(s(window.G_vmlCanvasManager)&&(u=window.G_vmlCanvasManager.initElement(u),this.ie=parseFloat(navigator.appVersion.split("MSIE")[1])),u&&(!u.getContext||!u.getContext("2d").fillText)){for(r=At.createElement("DIV"),n=0;n0?at.scrollPause=~~this.scrollPause:this.scrollPause=0,this.minTags>0&&this.repeatTags<1&&(n=this.GetTags().length)&&(this.repeatTags=bt(this.minTags/n)-1),this.transform=g.Identity(),this.startTime=this.time=o(),this.mx=this.my=-1,this.centreImage&&y(this),this.Animate=this.dragControl?this.AnimateDrag:this.AnimatePosition,this.animTiming="function"==typeof at[this.animTiming]?at[this.animTiming]:at.Smooth,this.shadowBlur||this.shadowOffset[0]||this.shadowOffset[1]?(this.ctxt.shadowColor=this.shadow,this.shadow=this.ctxt.shadowColor,this.shadowAlpha=b()):delete this.shadow,this.Load(),i&&this.hideTags&&function(t){at.loaded?t.HideTags():R("load",function(){t.HideTags()},window)}(this),this.yaw=this.initial?this.initial[0]*this.maxSpeed:0,this.pitch=this.initial?this.initial[1]*this.maxSpeed:0,this.tooltip?(this.ctitle=u.title,u.title="","native"==this.tooltip?this.Tooltip=this.TooltipNative:(this.Tooltip=this.TooltipDiv,this.ttdiv||(this.ttdiv=At.createElement("div"),this.ttdiv.className=this.tooltipClass,this.ttdiv.style.position="absolute",this.ttdiv.style.zIndex=u.style.zIndex+1,R("mouseover",function(t){t.target.style.display="none"},this.ttdiv),At.body.appendChild(this.ttdiv)))):this.Tooltip=this.TooltipNone,!this.noMouse&&!Ft[t])for(Ft[t]=[["mousemove",Y],["mouseout",j],["mouseup",V],["touchstart",q],["touchend",G],["touchcancel",G],["touchmove",Z]],this.dragControl&&(Ft[t].push(["mousedown",U]),Ft[t].push(["selectstart",h])),this.wheelZoom&&(Ft[t].push(["mousewheel",Q]),Ft[t].push(["DOMMouseScroll",Q])),this.scrollPause&&Ft[t].push(["scroll",J,window]),n=0;n=1?0:i<=-1?Math.PI:Math.acos(i))},dt.unit=function(){var t=this.length();return new u(this.x/t,this.y/t,this.z/t)},ft=g.prototype,g.Identity=function(){return new g([1,0,0,0,1,0,0,0,1])},g.Rotation=function(t,i){var e=vt(t),s=yt(t),n=1-s;return new g([s+zt(i.x,2)*n,i.x*i.y*n-i.z*e,i.x*i.z*n+i.y*e,i.y*i.x*n+i.z*e,s+zt(i.y,2)*n,i.y*i.z*n-i.x*e,i.z*i.x*n-i.y*e,i.z*i.y*n+i.x*e,s+zt(i.z,2)*n])},ft.mul=function(t){var i,e,s=[],n=t.xform?1:0;for(i=1;i<=3;++i)for(e=1;e<=3;++e)n?s.push(this[i][1]*t[1][e]+this[i][2]*t[2][e]+this[i][3]*t[3][e]):s.push(this[i][e]*t);return new g(s)},ft.xform=function(t){var i={},e=t.x,s=t.y,n=t.z;return i.x=e*this[1][1]+s*this[2][1]+n*this[3][1],i.y=e*this[1][2]+s*this[2][2]+n*this[3][2],i.z=e*this[1][3]+s*this[2][3]+n*this[3][3],i},pt=M.prototype,pt.SetImage=function(t,i,e,s,n,a,h,o){this.image=t,this.iwidth=i*this.scale,this.iheight=e*this.scale,this.ipos=s,this.ipad=n*this.scale,this.iscale=o,this.ialign=a,this.ivalign=h},pt.Align=function(t,i,e){var s=0;return"right"==e||"bottom"==e?s=i-t:"left"!=e&&"top"!=e&&(s=(i-t)/2),s},pt.Create=function(t,i,e,s,n,a,h,o,r){var l,u,c,g,f,d,m,p,w,x,v,y,T,b,C,z,M,A=xt(h[0]),F=xt(h[1]);return o=Tt(o,A+a,F+a),f=2*(o+s),m=2*(o+s),u=this.width+f,c=this.height+m,w=x=o+s,this.image&&(v=y=o+s,T=this.iwidth,b=this.iheight,"top"==this.ipos||"bottom"==this.ipos?(Tt?(o.push(this.line.join(" ")),this.line=[h[a]]):this.line.push(h[a]);o.push(this.line.join(" "))}return this.text=o},ut=st.prototype,ut.SetMethod=function(t){var i={block:["PreDraw","DrawBlock"],colour:["PreDraw","DrawColour"],outline:["PostDraw","DrawOutline"],classic:["LastDraw","DrawOutline"],size:["PreDraw","DrawSize"],none:["LastDraw"]},e=i[t]||i.outline;"none"==t?this.Draw=function(){return 1}:this.drawFunc=this[e[1]],this[e[0]]=this.Draw},ut.Update=function(t,i,e,s,n,a,h,o){var r=this.tc.outlineOffset,l=2*r;this.x=n*t+h-r,this.y=n*i+o-r,this.w=n*e+l,this.h=n*s+l,this.sc=n,this.z=a},ut.Ants=function(t){if(this.adash){var i,e=this.adash,s=this.agap,n=this.aspeed,a=e+s,h=0,r=e,l=s,u=0,c=0;n&&(c=xt(n)*(o()-this.ts)/50,n<0&&(c=864e4-c),n=~~c%a),n?(e>=n?(h=e-n,r=n):(l=a-n,u=s-l),i=[h,l,r,u]):i=[e,s],t.setLineDash(i)}},ut.DrawOutline=function(t,i,e,s,n,a){var h=St(this.radius,n/2,s/2);t.strokeStyle=a,this.Ants(t),I(t,i,e,s,n,h,!0)},ut.DrawSize=function(t,i,e,s,n,a,h,o,r){var l,u,c,g=h.w,f=h.h;return this.pulsate?(c=h.image?(h.image.height+this.tc.outlineIncrease)/h.image.height:h.oscale,u=h.fimage||h.image,l=1+(c-1)*(1-this.pulse),h.h*=l,h.w*=l):u=h.oimage,h.alpha=1,h.Draw(t,o,r,u),h.h=f,h.w=g,1},ut.DrawColour=function(t,i,e,s,n,a,h,o,r){return h.oimage?(this.pulse<1?(h.alpha=1-zt(this.pulse,2),h.Draw(t,o,r,h.fimage),h.alpha=this.pulse):h.alpha=1,h.Draw(t,o,r,h.oimage),1):this[h.image?"DrawColourImage":"DrawColourText"](t,i,e,s,n,a,h,o,r)},ut.DrawColourText=function(t,i,e,s,n,a,h,o,r){var l=h.colour;return h.colour=a,h.alpha=1,h.Draw(t,o,r),h.colour=l,1},ut.DrawColourImage=function(t,i,e,s,n,a,h,o,r){var l,u=t.canvas,c=~~Tt(i,0),g=~~Tt(e,0),f=St(u.width-c,s)+.5|0,d=St(u.height-g,n)+.5|0;return wt?(wt.width=f,wt.height=d):wt=S(f,d),wt?(l=wt.getContext("2d"),l.drawImage(u,c,g,f,d,0,0,f,d),t.clearRect(c,g,f,d),this.pulsate?h.alpha=1-zt(this.pulse,2):h.alpha=1,h.Draw(t,o,r),t.setTransform(1,0,0,1,0,0),t.save(),t.beginPath(),t.rect(c,g,f,d),t.clip(),t.globalCompositeOperation="source-in",t.fillStyle=a,t.fillRect(c,g,f,d),t.restore(),t.globalAlpha=1,t.globalCompositeOperation="destination-over",t.drawImage(wt,0,0,f,d,c,g,f,d),t.globalCompositeOperation="source-over",1):this.SetMethod("outline")},ut.DrawBlock=function(t,i,e,s,n,a){var h=St(this.radius,n/2,s/2);t.fillStyle=a,I(t,i,e,s,n,h)},ut.DrawSimple=function(t,i,e,s,n,a){var h=this.tc;return t.setTransform(1,0,0,1,0,0),t.strokeStyle=this.colour,t.lineWidth=h.outlineThickness,t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0,t.globalAlpha=a?n:1,this.drawFunc(t,this.x,this.y,this.w,this.h,this.colour,i,e,s)},ut.DrawPulsate=function(t,i,e,s){var n=o()-this.ts,a=this.tc,h=a.pulsateTo+(1-a.pulsateTo)*(.5+yt(2*Math.PI*n/(1e3*a.pulsateTime))/2);return this.pulse=h=at.Smooth(1,h),this.DrawSimple(t,i,e,s,h,1)},ut.Active=function(t,i,e){var s=i>=this.x&&e>=this.y&&i<=this.x+this.w&&e<=this.y+this.h;return this.ts=s?this.ts||o():null,s},ut.PreDraw=ut.PostDraw=ut.LastDraw=h,ct=nt.prototype,ct.Init=function(t){var i=this.tc;this.textHeight=i.textHeight,this.HasText()?this.Measure(i.ctxt,i):(this.w=this.iw,this.h=this.ih),this.SetShadowColour=i.shadowAlpha?this.SetShadowColourAlpha:this.SetShadowColourFixed,this.SetDraw(i)},ct.Draw=h,ct.HasText=function(){return this.text&&this.text[0].length>0},ct.EqualTo=function(t){var i=t.getElementsByTagName("img");return this.a.href!=t.href?0:i.length?this.image.src==i[0].src:(t.innerText||t.textContent)==this.text_original},ct.SetImage=function(t){this.image=this.fimage=t},ct.SetDraw=function(t){this.Draw=this.fimage?t.ie>7?this.DrawImageIE:this.DrawImage:this.DrawText,t.noSelect&&(this.CheckActive=h)},ct.MeasureText=function(t){var i,e,s=this.text.length,n=0;for(i=0;i0?l=A(l,this.oimage.width,this.oimage.height):this.oimage=A(this.oimage,l.width,l.height)),l&&(this.fimage=l,o=this.fimage.width/e,r=this.fimage.height/e),this.SetDraw(i),i.txtOpt=!!this.fimage),this.h=r,this.w=o},ct.SetFont=function(t,i,e,s){this.textFont=t,this.colour=i,this.bgColour=e,this.bgOutline=s,this.Measure(this.tc.ctxt,this.tc)},ct.SetWeight=function(t){var i,e,s=this.tc,n=s.weightMode.split(/[, ]/),a=t.length;if(this.HasText()){for(this.weighted=!0,e=0;e0&&e.weightSizeMax>e.weightSizeMin?this.textHeight=e.weightSize*(e.weightSizeMin+(e.weightSizeMax-e.weightSizeMin)*o):this.textHeight=Tt(1,t*e.weightSize))},ct.SetShadowColourFixed=function(t,i,e){t.shadowColor=i},ct.SetShadowColourAlpha=function(t,i,e){t.shadowColor=T(i,e)},ct.DrawText=function(t,i,e){var s,n,a=this.tc,h=this.x,o=this.y,r=this.sc;for(t.globalAlpha=this.alpha,t.fillStyle=this.colour,a.shadow&&this.SetShadowColour(t,a.shadow,this.alpha),t.font=this.font,h+=i/r,o+=e/r-this.h/2,s=0;sthis.max_weight[s])&&(this.max_weight[s]=i),(!this.min_weight[s]||ithis.min_weight[s]&&(n=1);if(n)for(e=0;e=0&&this.my>=0&&this.taglist[s].CheckActive(d,g,f))&&e.sc>u&&(!x||e.z<=0)&&(i=e,m=s,i.tag=this.taglist[s],u=e.sc);this.active=i}for(this.txtOpt||this.shadow&&this.SetShadow(d),d.clearRect(0,0,o,l),s=0;s=this.fadeIn?(this.fadeIn=0,this.fixedAlpha=1):this.fixedAlpha=i/this.fadeIn),!!this.fixedAnim&&(this.fixedAnim.transform||(this.fixedAnim.transform=this.transform),t=this.fixedAnim,i=o()-t.t0,e=t.angle,n=this.animTiming(t.t,i),this.transform=t.transform,i>=t.t?(this.fixedCallbackTag=t.tag,this.fixedCallback=t.cb,this.fixedAnim=this.yaw=this.pitch=0):e*=n,s=g.Rotation(e,t.axis),this.transform=this.transform.mul(s),0!=this.fixedAnim)},gt.AnimatePosition=function(t,i,e){var s,n,a=this,h=a.mx,o=a.my;!a.frozen&&h>=0&&o>=0&&hi&&(t.yaw=e>t.z0?t.yaw*t.decel:0),!t.ly&&s>i&&(t.pitch=s>t.z0?t.pitch*t.decel:0)},gt.Zoom=function(t){this.z2=this.z1*(1/t),this.drawn=0},gt.Clicked=function(t){var i=this.active;try{i&&i.tag&&(!1===this.clickToFront||null===this.clickToFront?i.tag.Clicked(t):this.TagToFront(i.tag,this.clickToFront,function(){i.tag.Clicked(t)},!0))}catch(t){}},gt.Wheel=function(t){var i=this.zoom+this.zoomStep*(t?1:-1);this.zoom=St(this.zoomMax,Tt(this.zoomMin,i)),this.Zoom(this.zoom)},gt.BeginDrag=function(t){this.down=X(t,this.canvas),t.cancelBubble=!0,t.returnValue=!1,t.preventDefault&&t.preventDefault()},gt.Drag=function(t,i){if(this.dragControl&&this.down){var e=this.dragThreshold*this.dragThreshold,s=i.x-this.down.x,n=i.y-this.down.y;(this.dragging||s*s+n*n>e)&&(this.dx=s,this.dy=n,this.dragging=1,this.down=i)}return this.dragging},gt.EndDrag=function(){var t=this.dragging;return this.dragging=this.down=null,t},gt.BeginPinch=function(t){this.pinched=[ht(t),this.zoom],t.preventDefault&&t.preventDefault()},gt.Pinch=function(t){var i,e,s=this.pinched;s&&(e=ht(t),i=s[1]*e/s[0],this.zoom=St(this.zoomMax,Tt(this.zoomMin,i)),this.Zoom(this.zoom))},gt.EndPinch=function(t){this.pinched=null},gt.Pause=function(){this.paused=!0},gt.Resume=function(){this.paused=!1},gt.SetSpeed=function(t){this.initial=t,this.yaw=t[0]*this.maxSpeed,this.pitch=t[1]*this.maxSpeed},gt.FindTag=function(t){if(!s(t))return null;if(s(t.index)&&(t=t.index),!n(t))return this.taglist[t];var i,e,a;for(s(t.id)?(i="id",e=t.id):s(t.text)&&(i="innerText",e=t.text),a=0;a").addClass(e.iconBase).addClass(r)).append(" ")}s.append(t("").html(a.message)),s.addClass(e.messageClass);var l=e.alertClasses[e.defaultAlert];e.alertClasses[a.messageType]&&(l=e.alertClasses[a.messageType]),s.addClass(l),o.after(s),s.fadeIn()})),h?e.onSuccess.call(this):e.onFailure.call(this)}},t.fn.handleMessages.defaults={messages:[],alertClasses:{good:"alert-success",info:"alert-info",error:"alert-danger",warning:"alert-warning"},iconClasses:{good:"fa-check",info:"fa-info-circle",error:"fa-times",warning:"fa-warning"},showIcons:!0,iconBase:"fa fa-fw",defaultIcon:"warning",defaultAlert:"warning",messageClass:"js-message",messageSelector:".message",onSuccess:function(){},onFailure:function(){}}}(n.a)},function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var s=e(0),n=e.n(s);n()(function(){n()(".field.togglegroup").each(function(){var t=n()(this),i=t.find(".group-toggle").data("show-when-checked"),e=t.find(".group-toggle input"),s=t.find(".group-fields");s.toggle(i?e.is(":checked"):!e.is(":checked")),e.on("click",function(){s.toggle(i?n()(this).is(":checked"):!n()(this).is(":checked"))})})})},function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var s=e(0),n=e.n(s);n()(function(){n()(".scrolltotopbutton").each(function(){var t=n()(this),i=parseInt(t.data("offset-show")),e=parseInt(t.data("offset-opacity")),s=parseInt(t.data("scroll-duration"));n()(window).scroll(function(){n()(this).scrollTop()>i?t.addClass("is-visible"):t.removeClass("is-visible fade-out"),n()(this).scrollTop()>e&&t.addClass("fade-out")}),t.on("click",function(t){t.preventDefault(),n()("body, html").animate({scrollTop:0},s)})})})},function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var s=e(0),n=e.n(s);n()(function(){n()(".tagcloudcomponent").each(function(){var t=n()(this);n()(t.data("canvas")).tagcanvas({depth:parseFloat(t.data("depth")),zoom:parseFloat(t.data("zoom")),zoomMin:parseFloat(t.data("zoom-min")),zoomMax:parseFloat(t.data("zoom-max")),textColour:t.data("color-text"),outlineColour:t.data("color-outline"),initial:t.data("initial"),weightSizeMin:parseInt(t.data("weight-size-min")),weightSizeMax:parseInt(t.data("weight-size-max")),weightFrom:"data-weight",weight:t.data("weight")},t.data("tag-list"))});var t=function(){n()(".tagcloudcomponent").each(function(){var t=n()(this),i=n()(t.data("canvas")),e=t.width();i.attr("width",e)})},i=null;n()(window).resize(function(){null!==i&&clearTimeout(i),i=setTimeout(t,500)}),n()(window).on("load",function(){t()})})}]); \ No newline at end of file diff --git a/client/dist/styles/bundle.css b/client/dist/styles/bundle.css index cccd6e6..36e2ce0 100644 --- a/client/dist/styles/bundle.css +++ b/client/dist/styles/bundle.css @@ -1 +1 @@ -.baselistcomponent .items>article.item{margin-bottom:2rem}.baselistcomponent .items>article.item>div.image{margin-bottom:1rem}.baselistcomponent .items>article.item>div.image a{display:inline-block}.baselistcomponent .items>article.item>section.content header a{color:inherit}.baselistcomponent .items>article.item>section.content div.details{color:#868e96}.baselistcomponent .items>article.item>section.content div.details>span{margin-right:.5rem}.baselistcomponent .items>article.item>section.content div.details a{color:inherit}.baselistcomponent .items>article.item>section.content footer{margin-top:1rem}.baselistcomponent .items>article.item>section.content>div,.featurecomponent article.feature div.icon{margin-bottom:.5rem}.featurecomponent article.feature div.summary>p:last-child{margin-bottom:0}.featurecomponent article.feature footer{margin-top:1rem}.imagecomponent figure{width:100%;margin-bottom:0}.imagecomponent figure>figcaption>p:last-child{margin-bottom:0}.imagecomponent a.image{display:block}@media (min-width:768px){.listcomponent .items>article.item{display:block}.listcomponent .items.image-align-left>article.item,.listcomponent .items.image-align-right>article.item,.listcomponent .items.image-align-stagger>article.item{display:flex}.listcomponent .items.image-align-left>article.item>div.image,.listcomponent .items.image-align-right>article.item>div.image,.listcomponent .items.image-align-stagger>article.item>div.image{margin-bottom:0}.listcomponent .items.image-align-left>article.item.has-image>div.image,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(odd)>div.image{order:1}.listcomponent .items.image-align-left>article.item.has-image>section.content,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(odd)>section.content{flex:1;order:2;margin-left:1rem}.listcomponent .items.image-align-right>article.item.has-image>div.image,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(2n)>div.image,.listcomponent .items>div.image{order:2}.listcomponent .items.image-align-right>article.item.has-image>section.content,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(2n)>section.content,.listcomponent .items>section.content{flex:1;order:1;margin-right:1rem}}.mediacomponent figure{width:100%;margin-bottom:0}.mediacomponent figure>figcaption>p:last-child{margin-bottom:0}.mediacomponent a.text{display:block}.mediacomponent a.text:hover{text-decoration:none}.mediacomponent a.text:hover span{text-decoration:underline}.mediacomponent a.text>i.fa{color:#868e96}.mediacomponent a.image{display:block}.mediacomponent a.image+a.text{margin-top:.5rem}.mediacomponent .rich>iframe{margin:0!important}.mediacomponent .video{width:100%;height:0;display:block;position:relative}.mediacomponent .video.four-three{padding-bottom:75%}.mediacomponent .video.sixteen-nine{padding-bottom:56.25%}.mediacomponent .video>iframe{top:0;left:0;border:0;width:100%;height:100%;position:absolute}.pagecomponent.page-title-hidden .content-container>article>header{display:none}.pagecomponent .content-container>article>div{margin-bottom:1rem}.scrolltotopbutton{opacity:0;outline:0;right:1rem;bottom:1rem;width:4rem;height:4rem;z-index:1000;position:fixed;display:block;overflow:hidden;visibility:hidden;white-space:nowrap;text-align:center;font-size:16px;line-height:4rem;box-shadow:0 0 20px rgba(0,0,0,.2);transition:opacity .3s 0s,visibility 0s .3s,color .15s ease-in-out 0s,background-color .15s ease-in-out 0s}.scrolltotopbutton.is-visible{opacity:1;visibility:visible}.scrolltotopbutton.fade-out{opacity:.5}.scrolltotopbutton:hover{opacity:1}@media (min-width:768px){.scrolltotopbutton{width:5rem;height:5rem;right:2rem;bottom:2rem;line-height:5rem}}@media (min-width:992px){.scrolltotopbutton{width:6rem;height:6rem;font-size:20px;line-height:6rem}}.tilecomponent .items{display:flex;flex-flow:row wrap;align-items:stretch}.tilecomponent .items>article.item{display:flex;flex-direction:column;flex:1 100%;padding:2%}.tilecomponent .items>article.item>section.content{margin-top:auto}.tilecomponent .items>article.item>section.content header>*{font-size:1rem;line-height:1.2}.tilecomponent .items>article.item>section.content div.details>span{display:block;margin-right:0;margin-bottom:.5rem}@media (min-width:576px){.tilecomponent .items>article.item{flex:1 50%}}@media (min-width:768px){.tilecomponent .items>article.item{flex:1 33.3%}}@media (min-width:992px){.tilecomponent .items>article.item{flex:1 25%}}.component.link{text-decoration:none}.component.link,.component.link>i.fa{display:inline-block}.component.link:active,.component.link:focus,.component.link:hover{text-decoration:none}.show-icons.hide-text .component.link{overflow:hidden;text-align:center;transition:color .15s ease-in-out 0s,background-color .15s ease-in-out 0s}.show-icons.hide-text .component.link>i.fa{display:block}.show-icons.hide-text .component.link.size-16{width:16px;height:16px;font-size:10.56px;line-height:16px}.show-icons.hide-text .component.link.size-16>i.fa{height:16px;line-height:16px}.show-icons.hide-text .component.link.size-24{width:24px;height:24px;font-size:15.84px;line-height:24px}.show-icons.hide-text .component.link.size-24>i.fa{height:24px;line-height:24px}.show-icons.hide-text .component.link.size-32{width:32px;height:32px;font-size:21.12px;line-height:32px}.show-icons.hide-text .component.link.size-32>i.fa{height:32px;line-height:32px}.show-icons.hide-text .component.link.size-48{width:48px;height:48px;font-size:31.68px;line-height:48px}.show-icons.hide-text .component.link.size-48>i.fa{height:48px;line-height:48px}.show-icons.hide-text .component.link.size-64{width:64px;height:64px;font-size:42.24px;line-height:64px}.show-icons.hide-text .component.link.size-64>i.fa{height:64px;line-height:64px}.show-icons.hide-text .component.link.size-96{width:96px;height:96px;font-size:63.36px;line-height:96px}.show-icons.hide-text .component.link.size-96>i.fa{height:96px;line-height:96px}.show-icons.hide-text .component.link.size-128{width:128px;height:128px;font-size:84.48px;line-height:128px}.show-icons.hide-text .component.link.size-128>i.fa{height:128px;line-height:128px}.hide-icons .component.link>i.fa,.hide-text .component.link>span.text{display:none} \ No newline at end of file +.baselistcomponent .items>article.item{margin-bottom:2rem}.baselistcomponent .items>article.item>div.image{position:relative;margin-bottom:1rem}.baselistcomponent .items>article.item>div.image a{display:block}.baselistcomponent .items>article.item>div.image div.image-overlay{top:0;left:0;right:0;bottom:0;width:100%;height:100%;opacity:0;position:absolute;transition:.5s ease;background-color:rgba(0,0,0,.5)}.baselistcomponent .items>article.item>div.image div.image-overlay>i{top:50%;left:50%;color:#fff;position:absolute;font-size:32px;transform:translate(-50%,-50%)}.baselistcomponent .items>article.item>div.image:hover div.image-overlay,.baselistcomponent .items>article.item>div.image a:focus div.image-overlay{opacity:1}.baselistcomponent .items>article.item>section.content header a{color:inherit}.baselistcomponent .items>article.item>section.content div.details{color:#868e96}.baselistcomponent .items>article.item>section.content div.details>span{margin-right:.5rem}.baselistcomponent .items>article.item>section.content div.details a{color:inherit}.baselistcomponent .items>article.item>section.content footer{margin-top:1rem}.baselistcomponent .items>article.item>section.content>div,.featurecomponent article.feature div.icon{margin-bottom:.5rem}.featurecomponent article.feature div.summary>p:last-child{margin-bottom:0}.featurecomponent article.feature footer{margin-top:1rem}.imagecomponent figure{width:100%;margin-bottom:0}.imagecomponent figure>figcaption>p:last-child{margin-bottom:0}.imagecomponent a.image{display:block}@media (min-width:768px){.listcomponent .items>article.item{display:block}.listcomponent .items.image-align-left>article.item,.listcomponent .items.image-align-right>article.item,.listcomponent .items.image-align-stagger>article.item{display:flex}.listcomponent .items.image-align-left>article.item>div.image,.listcomponent .items.image-align-right>article.item>div.image,.listcomponent .items.image-align-stagger>article.item>div.image{margin-bottom:0}.listcomponent .items.image-align-left>article.item.has-image>div.image,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(odd)>div.image{order:1}.listcomponent .items.image-align-left>article.item.has-image>section.content,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(odd)>section.content{flex:1;order:2;margin-left:1rem}.listcomponent .items.image-align-right>article.item.has-image>div.image,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(2n)>div.image,.listcomponent .items>div.image{order:2}.listcomponent .items.image-align-right>article.item.has-image>section.content,.listcomponent .items.image-align-stagger>article.item.has-image:nth-child(2n)>section.content,.listcomponent .items>section.content{flex:1;order:1;margin-right:1rem}}.mediacomponent figure{width:100%;margin-bottom:0}.mediacomponent figure>figcaption>p:last-child{margin-bottom:0}.mediacomponent a.text{display:block}.mediacomponent a.text:hover{text-decoration:none}.mediacomponent a.text:hover span{text-decoration:underline}.mediacomponent a.text>i.fa{color:#868e96}.mediacomponent a.image{display:block}.mediacomponent a.image+a.text{margin-top:.5rem}.mediacomponent .rich>iframe{margin:0!important}.mediacomponent .video{width:100%;height:0;display:block;position:relative}.mediacomponent .video.four-three{padding-bottom:75%}.mediacomponent .video.sixteen-nine{padding-bottom:56.25%}.mediacomponent .video>iframe{top:0;left:0;border:0;width:100%;height:100%;position:absolute}.pagecomponent.page-title-hidden .content-container>article>header{display:none}.pagecomponent .content-container>article>div{margin-bottom:1rem}.scrolltotopbutton{opacity:0;outline:0;right:1rem;bottom:1rem;width:4rem;height:4rem;z-index:1000;position:fixed;display:block;overflow:hidden;visibility:hidden;white-space:nowrap;text-align:center;font-size:16px;line-height:4rem;box-shadow:0 0 20px rgba(0,0,0,.2);transition:opacity .3s 0s,visibility 0s .3s,color .15s ease-in-out 0s,background-color .15s ease-in-out 0s}.scrolltotopbutton.is-visible{opacity:1;visibility:visible}.scrolltotopbutton.fade-out{opacity:.5}.scrolltotopbutton:hover{opacity:1}@media (min-width:768px){.scrolltotopbutton{width:5rem;height:5rem;right:2rem;bottom:2rem;line-height:5rem}}@media (min-width:992px){.scrolltotopbutton{width:6rem;height:6rem;font-size:20px;line-height:6rem}}.tilecomponent .items{display:flex;flex-flow:row wrap;align-items:stretch}.tilecomponent .items>article.item{display:flex;flex-direction:column;flex:1 100%;padding:2%}.tilecomponent .items>article.item>section.content{margin-top:auto}.tilecomponent .items>article.item>section.content header>*{font-size:1rem;line-height:1.2}.tilecomponent .items>article.item>section.content div.details>span{display:block;margin-right:0;margin-bottom:.5rem}@media (min-width:576px){.tilecomponent .items>article.item{flex:1 50%}}@media (min-width:768px){.tilecomponent .items>article.item{flex:1 33.3%}}@media (min-width:992px){.tilecomponent .items>article.item{flex:1 25%}}.component.link{text-decoration:none}.component.link,.component.link>i.fa{display:inline-block}.component.link:active,.component.link:focus,.component.link:hover{text-decoration:none}.show-icons.hide-text .component.link{overflow:hidden;text-align:center;transition:color .15s ease-in-out 0s,background-color .15s ease-in-out 0s}.show-icons.hide-text .component.link>i.fa{display:block}.show-icons.hide-text .component.link.size-16{width:16px;height:16px;font-size:8px;line-height:16px}.show-icons.hide-text .component.link.size-16>i.fa{height:16px;line-height:16px}.show-icons.hide-text .component.link.size-24{width:24px;height:24px;font-size:12px;line-height:24px}.show-icons.hide-text .component.link.size-24>i.fa{height:24px;line-height:24px}.show-icons.hide-text .component.link.size-32{width:32px;height:32px;font-size:16px;line-height:32px}.show-icons.hide-text .component.link.size-32>i.fa{height:32px;line-height:32px}.show-icons.hide-text .component.link.size-48{width:48px;height:48px;font-size:24px;line-height:48px}.show-icons.hide-text .component.link.size-48>i.fa{height:48px;line-height:48px}.show-icons.hide-text .component.link.size-64{width:64px;height:64px;font-size:32px;line-height:64px}.show-icons.hide-text .component.link.size-64>i.fa{height:64px;line-height:64px}.show-icons.hide-text .component.link.size-96{width:96px;height:96px;font-size:48px;line-height:96px}.show-icons.hide-text .component.link.size-96>i.fa{height:96px;line-height:96px}.show-icons.hide-text .component.link.size-128{width:128px;height:128px;font-size:64px;line-height:128px}.show-icons.hide-text .component.link.size-128>i.fa{height:128px;line-height:128px}.hide-icons .component.link>i.fa,.hide-text .component.link>span.text{display:none} \ No newline at end of file diff --git a/client/src/bundles/bundle.js b/client/src/bundles/bundle.js index 70cf9e8..ccd5625 100644 --- a/client/src/bundles/bundle.js +++ b/client/src/bundles/bundle.js @@ -9,6 +9,11 @@ require('styles/bundle.scss'); require('jquery/tagcanvas.js'); +// Load Form Scripts: + +require('forms/MessageHandler.js'); +require('forms/ToggleGroup.js'); + // Load Components: require('components/ScrollToTopButton.js'); diff --git a/client/src/components/TagCloudComponent.js b/client/src/components/TagCloudComponent.js index e1edfc3..31d2ceb 100644 --- a/client/src/components/TagCloudComponent.js +++ b/client/src/components/TagCloudComponent.js @@ -30,9 +30,7 @@ $(function() { }); - // Detect Browser Resize: - - var id = null; + // Define Resize Handler: var resizeTagCloud = function() { @@ -49,16 +47,19 @@ $(function() { }; + // Attach Resize Handler: + + var id = null; + $(window).resize(function() { - - if (id !== null) { - clearTimeout(id); - } - + if (id !== null) clearTimeout(id); id = setTimeout(resizeTagCloud, 500); - }); - resizeTagCloud(); + // Perform Initial Resize: + + $(window).on('load', function() { + resizeTagCloud(); + }); }); diff --git a/client/src/forms/MessageHandler.js b/client/src/forms/MessageHandler.js new file mode 100644 index 0000000..3bd6d80 --- /dev/null +++ b/client/src/forms/MessageHandler.js @@ -0,0 +1,136 @@ +/* Form Message Handler +===================================================================================================================== */ + +import jQuery from 'jquery'; + +(function($) { + + // Setup Message Handler Plugin: + + $.fn.handleMessages = function(options) { + + if (typeof options === 'object') { + + // Obtain Options: + + var opts = $.extend({}, $.fn.handleMessages.defaults, options); + + // Remove Existing Messages: + + this.find('.' + opts.messageClass).remove(); + + // Initialise Variables: + + var $item, $message = this.find(opts.messageSelector); + + // Record Success: + + var success = true; + + // Did We Find a Message Element? + + if ($message.length) { + + // Hide and Empty Message Element: + + $message.hide().empty(); + + // Iterate Messages: + + $.each(opts.messages, function(i, item) { + + // Record Failure: + + if (item.messageType != 'good') { + success = false; + } + + // Obtain Previous Element: + + var $prev = ($item !== undefined) ? $item : $message; + + // Create Message Item Element and Change ID: + + $item = $message.clone().prop('id', function(key, id) { + return id + '_' + (i + 1); + }); + + // Remove Existing Alert Classes: + + $item.removeClass(function(index, className) { + return (className.match(/alert-\S+/g) || []).join(' '); + }); + + // Render Message Icon (if enabled): + + if (opts.showIcons) { + var iconClass = opts.iconClasses[opts.defaultIcon]; + if (opts.iconClasses[item.messageType]) iconClass = opts.iconClasses[item.messageType]; + $item.append($('').addClass(opts.iconBase).addClass(iconClass)).append(' '); + } + + // Render Message Text: + + $item.append($('').html(item.message)); + + // Add Message Class: + + $item.addClass(opts.messageClass); + + // Add Alert Class: + + var alertClass = opts.alertClasses[opts.defaultAlert]; + if (opts.alertClasses[item.messageType]) alertClass = opts.alertClasses[item.messageType]; + $item.addClass(alertClass); + + // Add Message Item after Previous: + + $prev.after($item); + + // Fade In Message Item: + + $item.fadeIn(); + + }); + + } + + // Trigger Success / Failure Callbacks: + + if (success) { + opts.onSuccess.call(this); + } else { + opts.onFailure.call(this); + } + + } + + }; + + // Message Handler Default Options: + + $.fn.handleMessages.defaults = { + messages: [], + alertClasses: { + good: 'alert-success', + info: 'alert-info', + error: 'alert-danger', + warning: 'alert-warning' + }, + iconClasses: { + good: 'fa-check', + info: 'fa-info-circle', + error: 'fa-times', + warning: 'fa-warning' + }, + showIcons: true, + iconBase: 'fa fa-fw', + defaultIcon: 'warning', + defaultAlert: 'warning', + messageClass: 'js-message', + messageSelector: '.message', + onSuccess: function() {}, + onFailure: function() {} + }; + +}(jQuery)); diff --git a/client/src/forms/ToggleGroup.js b/client/src/forms/ToggleGroup.js new file mode 100644 index 0000000..dd469c3 --- /dev/null +++ b/client/src/forms/ToggleGroup.js @@ -0,0 +1,24 @@ +/* Toggle Group +===================================================================================================================== */ + +import $ from 'jquery'; + +$(function() { + + $('.field.togglegroup').each(function() { + + var $self = $(this); + var $mode = $self.find('.group-toggle').data('show-when-checked'); + + var $toggle = $self.find('.group-toggle input'); + var $fields = $self.find('.group-fields'); + + $fields.toggle($mode ? $toggle.is(':checked') : !$toggle.is(':checked')); + + $toggle.on('click', function() { + $fields.toggle($mode ? $(this).is(':checked') : !$(this).is(':checked')); + }); + + }); + +}); diff --git a/client/src/styles/_variables.scss b/client/src/styles/_variables.scss index 3c363a9..bc9316a 100644 --- a/client/src/styles/_variables.scss +++ b/client/src/styles/_variables.scss @@ -2,3 +2,4 @@ ===================================================================================================================== */ $icon-size-list: 16 24 32 48 64 96 128; +$icon-size-multiplier: 0.5; diff --git a/client/src/styles/components/BaseListComponent.scss b/client/src/styles/components/BaseListComponent.scss index fd4e7da..6dee026 100644 --- a/client/src/styles/components/BaseListComponent.scss +++ b/client/src/styles/components/BaseListComponent.scss @@ -11,10 +11,44 @@ > div.image { + position: relative; margin-bottom: $spacer; a { - display: inline-block; + display: block; + } + + div.image-overlay { + + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + opacity: 0; + position: absolute; + transition: .5s ease; + background-color: rgba(0, 0, 0, 0.5); + + > i { + top: 50%; + left: 50%; + color: $white; + position: absolute; + font-size: 32px; + transform: translate(-50%, -50%); + } + + } + + &:hover, + a:focus { + + div.image-overlay { + opacity: 1; + } + } } diff --git a/client/src/styles/mixins/_icon-size.scss b/client/src/styles/mixins/_icon-size.scss index 962ecb6..c9f1ecc 100644 --- a/client/src/styles/mixins/_icon-size.scss +++ b/client/src/styles/mixins/_icon-size.scss @@ -7,7 +7,7 @@ width: #{$size}px; height: #{$size}px; - font-size: #{$size * 0.66}px; + font-size: #{$size * $icon-size-multiplier}px; line-height: #{$size}px; > i.fa { diff --git a/composer.json b/composer.json index d3fa69a..05d421f 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "silverstripe/framework": "^4@dev", "silverware/colorpicker": "^1.0", "silverware/font-icons": "^1.0", + "silverware/select2": "^1.0", "silverware/theme": "^1.0" }, "autoload": { @@ -41,6 +42,7 @@ "SilverWare\\Lists\\": "src/Lists/", "SilverWare\\Model\\": "src/Model/", "SilverWare\\ORM\\": "src/ORM/", + "SilverWare\\Pages\\": "src/Pages/", "SilverWare\\Sections\\": "src/Sections/", "SilverWare\\Security\\": "src/Security/", "SilverWare\\Tags\\": "src/Sections/", diff --git a/src/Components/BaseComponent.php b/src/Components/BaseComponent.php index 97bd402..faddec4 100644 --- a/src/Components/BaseComponent.php +++ b/src/Components/BaseComponent.php @@ -176,6 +176,16 @@ public function fieldLabels($includerelations = true) return $labels; } + /** + * Answers null to avoid problems with '$Content' double-ups in the template. + * + * @return null + */ + public function getContent() + { + return null; + } + /** * Answers an array of content class names for the HTML template. * @@ -273,6 +283,8 @@ public function renderSelf($layout = null, $title = null) */ public function renderContent($layout = null, $title = null) { - return parent::renderSelf($layout, $title); + if ($this->getTemplate() != self::class) { + return parent::renderSelf($layout, $title); + } } } diff --git a/src/Components/BaseListComponent.php b/src/Components/BaseListComponent.php index 6ac9578..9cd2249 100644 --- a/src/Components/BaseListComponent.php +++ b/src/Components/BaseListComponent.php @@ -20,10 +20,12 @@ use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\TextField; +use SilverWare\Colorpicker\Forms\ColorField; use SilverWare\Extensions\Lists\ListSourceExtension; use SilverWare\Extensions\Model\ImageResizeExtension; use SilverWare\Extensions\Style\AlignmentStyle; use SilverWare\Extensions\Style\PaginationStyle; +use SilverWare\FontIcons\Forms\FontIconField; use SilverWare\Forms\FieldSection; /** @@ -82,6 +84,9 @@ class BaseListComponent extends BaseComponent 'HeadingLevel' => 'Varchar(2)', 'ImageLinksTo' => 'Varchar(8)', 'DateFormat' => 'Varchar(32)', + 'OverlayIcon' => 'FontIcon', + 'OverlayIconColor' => 'Color', + 'OverlayImages' => 'Boolean', 'LinkImages' => 'Boolean', 'LinkTitles' => 'Boolean' ]; @@ -100,6 +105,8 @@ class BaseListComponent extends BaseComponent 'ShowFooter' => 'all', 'ImageLinksTo' => 'item', 'DateFormat' => 'd MMMM Y', + 'OverlayIcon' => 'search', + 'OverlayImages' => 0, 'LinkImages' => 1, 'LinkTitles' => 1 ]; @@ -151,19 +158,29 @@ public function getCMSFields() // Create Style Fields: - $fields->addFieldToTab( + $fields->addFieldsToTab( 'Root.Style', - FieldSection::create( - 'ListStyle', - $this->fieldLabel('ListStyle'), - [ - DropdownField::create( - 'HeadingLevel', - $this->fieldLabel('HeadingLevel'), - $this->getTitleLevelOptions() - )->setEmptyString(' ')->setAttribute('data-placeholder', $placeholderDefault), - ] - ) + [ + FieldSection::create( + 'ListStyle', + $this->fieldLabel('ListStyle'), + [ + DropdownField::create( + 'HeadingLevel', + $this->fieldLabel('HeadingLevel'), + $this->getTitleLevelOptions() + )->setEmptyString(' ')->setAttribute('data-placeholder', $placeholderDefault), + FontIconField::create( + 'OverlayIcon', + $this->fieldLabel('OverlayIcon') + ), + ColorField::create( + 'OverlayIconColor', + $this->fieldLabel('OverlayIconColor') + ) + ] + ) + ] ); // Create Options Fields: @@ -228,6 +245,10 @@ public function getCMSFields() $this->fieldLabel('ImageLinksTo'), $this->getImageLinksToOptions() ), + CheckboxField::create( + 'OverlayImages', + $this->fieldLabel('OverlayImages') + ), CheckboxField::create( 'LinkImages', $this->fieldLabel('LinkImages') @@ -269,7 +290,10 @@ public function fieldLabels($includerelations = true) $labels['ButtonLabel'] = _t(__CLASS__ . '.BUTTONLABEL', 'Button label'); $labels['HeadingLevel'] = _t(__CLASS__ . '.HEADINGLEVEL', 'Heading level'); $labels['ImageLinksTo'] = _t(__CLASS__ . '.IMAGELINKSTO', 'Image links to'); + $labels['OverlayImages'] = _t(__CLASS__ . '.OVERLAYIMAGES', 'Overlay images'); $labels['ListImageOptions'] = _t(__CLASS__ . '.LISTIMAGES', 'List images'); + $labels['OverlayIcon'] = _t(__CLASS__ . '.OVERLAYICON', 'Overlay icon'); + $labels['OverlayIconColor'] = _t(__CLASS__ . '.OVERLAYICONCOLOR', 'Overlay icon color'); $labels['ListStyle'] = $labels['ListOptions'] = _t(__CLASS__ . '.LIST', 'List'); // Answer Field Labels: diff --git a/src/Components/ContentComponent.php b/src/Components/ContentComponent.php index bafdba7..b7ac6d4 100644 --- a/src/Components/ContentComponent.php +++ b/src/Components/ContentComponent.php @@ -115,15 +115,13 @@ public function getCMSFields() } /** - * Renders the content for the HTML template. + * Answers the HTML content of the receiver (overrides method in BaseComponent). * - * @param string $layout Page layout passed from template. - * @param string $title Page title passed from template. - * - * @return DBHTMLText|string + * @return DBHTMLText */ - public function renderContent($layout = null, $title = null) + public function getContent() { return $this->dbObject('Content'); } + } diff --git a/src/Extensions/Admin/LeftAndMainExtension.php b/src/Extensions/Admin/LeftAndMainExtension.php index 1a2cc6d..109b9c9 100644 --- a/src/Extensions/Admin/LeftAndMainExtension.php +++ b/src/Extensions/Admin/LeftAndMainExtension.php @@ -18,6 +18,9 @@ namespace SilverWare\Extensions\Admin; use SilverStripe\Admin\LeftAndMainExtension as BaseExtension; +use SilverStripe\Forms\HTMLEditor\TinyMCEConfig; +use SilverStripe\View\SSViewer; +use SilverStripe\View\ThemeResourceLoader; use SilverWare\Grid\Grid; /** @@ -41,5 +44,45 @@ public function init() // Initialise Grid Framework: Grid::framework()->doInit(); + + // Initialise Themed Editor CSS: + + $this->initThemedEditorCSS(); + } + + /** + * Merges configured editor CSS from the theme into HTML editor config. + * + * @return void + */ + protected function initThemedEditorCSS() + { + // Initialise: + + $paths = []; + + // Iterate Themed Editor CSS Files: + + foreach ($this->getThemedEditorCSS() as $name) { + + if ($path = ThemeResourceLoader::inst()->findThemedCSS($name, SSViewer::get_themes())) { + $paths[] = $path; + } + + } + + // Merge Themed Editor CSS Paths into HTML Editor Config: + + TinyMCEConfig::config()->merge('editor_css', $paths); + } + + /** + * Answers an array of the themed editor CSS required for the HTML editor. + * + * @return array + */ + protected function getThemedEditorCSS() + { + return (array) $this->owner->config()->themed_editor_css; } } diff --git a/src/Lists/ListItem.php b/src/Extensions/Lists/ListItemExtension.php similarity index 64% rename from src/Lists/ListItem.php rename to src/Extensions/Lists/ListItemExtension.php index 4ef436f..090a826 100644 --- a/src/Lists/ListItem.php +++ b/src/Extensions/Lists/ListItemExtension.php @@ -8,15 +8,16 @@ * For full copyright and license information, please view the * LICENSE.md file that was distributed with this source code. * - * @package SilverWare\Lists + * @package SilverWare\Extensions\Lists * @author Colin Tucker * @copyright 2017 Praxis Interactive * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause * @link https://github.com/praxisnetau/silverware */ -namespace SilverWare\Lists; +namespace SilverWare\Extensions\Lists; +use SilverStripe\Core\Extension; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; @@ -24,24 +25,27 @@ use SilverWare\Model\Component; use SilverWare\Tools\ViewTools; use SilverWare\View\GridAware; -use SilverWare\View\ViewClasses; /** - * Allows an object to become renderable within a list component. + * An extension class to add list item functionality to the extended object. * - * @package SilverWare\Lists + * @package SilverWare\Extensions\Lists * @author Colin Tucker * @copyright 2017 Praxis Interactive * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause * @link https://github.com/praxisnetau/silverware */ -trait ListItem +class ListItemExtension extends Extension { use GridAware; - use ViewClasses; /** - * The component instance responsible for rendering the list item. + * Define constants. + */ + const DEFAULT_LIST_ITEM_TEMPLATE = 'SilverWare\Lists\ListItem'; + + /** + * Holds the component instance responsible for rendering the extended object. * * @var Component */ @@ -78,8 +82,8 @@ public function getRenderer() */ public function getListComponent() { - if ($this->hasListComponent()) { - return $this->renderer; + if ($this->owner->hasListComponent()) { + return $this->owner->getRenderer(); } } @@ -90,7 +94,17 @@ public function getListComponent() */ public function hasListComponent() { - return ($this->renderer instanceof BaseListComponent); + return ($this->owner->getRenderer() instanceof BaseListComponent); + } + + /** + * Answers an string of list item class names for the HTML template. + * + * @return string + */ + public function getListItemClass() + { + return ViewTools::singleton()->array2att($this->owner->getListItemClassNames()); } /** @@ -100,17 +114,47 @@ public function hasListComponent() */ public function getListItemClassNames() { + // Initialise: + $classes = ['item']; - $classes = array_merge($classes, ViewTools::singleton()->getAncestorClassNames($this, self::class)); + // Merge Ancestor Class Names: + + $classes = array_merge( + $classes, + ViewTools::singleton()->getAncestorClassNames( + $this->owner, + $this->ownerBaseClass + ) + ); - if ($this->hasMethod('getMetaClassNames')) { - $classes = array_merge($classes, $this->getMetaClassNames()); + // Merge Meta Class Names: + + if ($this->owner->hasMethod('getMetaClassNames')) { + $classes = array_merge($classes, $this->owner->getMetaClassNames()); } + // Update Class Names via Renderer: + + if ($this->owner->getRenderer()->hasMethod('updateListItemClassNames')) { + $this->owner->getRenderer()->updateListItemClassNames($classes); + } + + // Answer Classes: + return $classes; } + /** + * Answers an string of list item image class names for the HTML template. + * + * @return string + */ + public function getListItemImageClass() + { + return ViewTools::singleton()->array2att($this->owner->getListItemImageClassNames()); + } + /** * Answers an array of list item image class names for the HTML template. * @@ -128,17 +172,35 @@ public function getListItemImageClassNames() */ public function getListItemTemplate() { - $template = sprintf('%s\ListItem', static::class); + // Define Template by Class: + + $template = sprintf('%s\ListItem', get_class($this->owner)); - if ($this->getRenderer()->hasMethod('getListItemTemplate')) { - $template = $this->getRenderer()->getListItemTemplate(static::class); + // Define Template via Renderer: + + if ($this->owner->getRenderer()->hasMethod('getListItemTemplate')) { + $template = $this->owner->getRenderer()->getListItemTemplate(get_class($this->owner)); } + // Verify Template Exists: + if (SSViewer::hasTemplate($template)) { return $template; } - return __TRAIT__; + // Answer Default Template: + + return $this->owner->getDefaultListItemTemplate(); + } + + /** + * Answers the name of the default list item template. + * + * @return string + */ + public function getDefaultListItemTemplate() + { + return self::DEFAULT_LIST_ITEM_TEMPLATE; } /** @@ -150,13 +212,13 @@ public function getListItemTemplate() * * @return DBHTMLText */ - public function renderListItem($isFirst = false, $isMiddle = false, $isLast = false) + public function renderListItem($isFirst = false, $isMiddle = false, $isLast = false, $wtf = false) { - return $this->customise([ + return $this->owner->customise([ 'isFirst' => $isFirst, 'isMiddle' => $isMiddle, 'isLast' => $isLast - ])->renderWith($this->getListItemTemplate()); + ])->renderWith($this->owner->getListItemTemplate()); } /** @@ -168,7 +230,7 @@ public function getListItemDetails() { $details = ArrayList::create(); - foreach ($this->getListItemDetailsConfig() as $name => $spec) { + foreach ($this->owner->getListItemDetailsConfig() as $name => $spec) { if ($spec) { @@ -209,13 +271,13 @@ public function getListItemDetailsConfig() { $config = []; - if (is_array($this->config()->default_list_item_details)) { - $config = $this->config()->default_list_item_details; + if (is_array($this->owner->config()->default_list_item_details)) { + $config = $this->owner->config()->default_list_item_details; } - if (is_array($this->config()->list_item_details)) { + if (is_array($this->owner->config()->list_item_details)) { - foreach ($this->config()->list_item_details as $name => $spec) { + foreach ($this->owner->config()->list_item_details as $name => $spec) { if (!$spec) { unset($config[$name]); @@ -223,7 +285,7 @@ public function getListItemDetailsConfig() } - $config = array_merge_recursive($config, $this->config()->list_item_details); + $config = array_merge_recursive($config, $this->owner->config()->list_item_details); } @@ -239,7 +301,7 @@ public function getListItemButtons() { $buttons = ArrayList::create(); - foreach ($this->getListItemButtonsConfig() as $name => $spec) { + foreach ($this->owner->getListItemButtonsConfig() as $name => $spec) { if ($spec) { @@ -288,13 +350,13 @@ public function getListItemButtonsConfig() { $config = []; - if (is_array($this->config()->default_list_item_buttons)) { - $config = $this->config()->default_list_item_buttons; + if (is_array($this->owner->config()->default_list_item_buttons)) { + $config = $this->owner->config()->default_list_item_buttons; } - if (is_array($this->config()->list_item_buttons)) { + if (is_array($this->owner->config()->list_item_buttons)) { - foreach ($this->config()->list_item_buttons as $name => $spec) { + foreach ($this->owner->config()->list_item_buttons as $name => $spec) { if (!$spec) { unset($config[$name]); @@ -302,7 +364,7 @@ public function getListItemButtonsConfig() } - $config = array_merge_recursive($config, $this->config()->list_item_buttons); + $config = array_merge_recursive($config, $this->owner->config()->list_item_buttons); } @@ -310,15 +372,15 @@ public function getListItemButtonsConfig() } /** - * Processes the given value which references methods / fields of the receiver and List Component. + * Processes the given value which references methods / fields of the receiver and renderer. * * @param string $value * @param array $args * * @return string */ - public function processListItemValue($value, $args = []) + protected function processListItemValue($value, $args = []) { - return ViewTools::singleton()->processAttribute($value, $this, $this->getRenderer(), $args); + return ViewTools::singleton()->processAttribute($value, $this->owner, $this->owner->getRenderer(), $args); } } diff --git a/src/Extensions/Model/MetaDataExtension.php b/src/Extensions/Model/MetaDataExtension.php index 210ede8..45646a8 100644 --- a/src/Extensions/Model/MetaDataExtension.php +++ b/src/Extensions/Model/MetaDataExtension.php @@ -476,7 +476,9 @@ public function getMetaDate() */ public function getMetaDateFormatted($format) { - return $this->owner->getMetaDate()->Format($format); + if ($this->owner->hasMetaDate()) { + return $this->owner->getMetaDate()->Format($format); + } } /** diff --git a/src/Extensions/Style/CornerStyle.php b/src/Extensions/Style/CornerStyle.php index 204bbf7..7d54556 100644 --- a/src/Extensions/Style/CornerStyle.php +++ b/src/Extensions/Style/CornerStyle.php @@ -19,7 +19,6 @@ use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; -use SilverWare\Colorpicker\Forms\ColorField; use SilverWare\Extensions\StyleExtension; use SilverWare\Forms\FieldSection; diff --git a/src/Forms/AutoCompleteField.php b/src/Forms/AutoCompleteField.php deleted file mode 100644 index 2331053..0000000 --- a/src/Forms/AutoCompleteField.php +++ /dev/null @@ -1,349 +0,0 @@ -=5.6.0 - * - * For full copyright and license information, please view the - * LICENSE.md file that was distributed with this source code. - * - * @package SilverWare\Forms - * @author Colin Tucker - * @copyright 2017 Praxis Interactive - * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @link https://github.com/praxisnetau/silverware - */ - -namespace SilverWare\Forms; - -use SilverStripe\Control\HTTPRequest; -use SilverStripe\Forms\TextField; -use SilverStripe\ORM\Map; -use SilverStripe\ORM\SS_List; -use ArrayAccess; - -/** - * An extension of the text field class for an auto-complete field. - * - * @package SilverWare\Forms - * @author Colin Tucker - * @copyright 2017 Praxis Interactive - * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause - * @link https://github.com/praxisnetau/silverware - */ -class AutoCompleteField extends TextField -{ - /** - * Defines the allowed actions for this field. - * - * @var array - * @config - */ - private static $allowed_actions = [ - 'suggest' - ]; - - /** - * Source options used to return suggestions to the field. - * - * @var array - */ - protected $source; - - /** - * The source URL used to return suggestions to the field. - * - * @var string - */ - protected $sourceURL; - - /** - * If true, free text entry is permitted in the text field. - * - * @var boolean - */ - protected $allowFreeText = false; - - /** - * The minimum length of the term which triggers the suggestions. - * - * @var integer - */ - protected $termMinLength = 2; - - /** - * The delay in milliseconds between when a key is pressed and suggestions are returned. - * - * @var integer - */ - protected $delay = 800; - - /** - * Constructs the object upon instantiation. - * - * @param string $name Name of field. - * @param string $title Title of field. - * @param array|ArrayAccess $source A map of options used as the data source. - * @param mixed $value Value of field. - */ - public function __construct($name, $title = null, $source = [], $value = null) - { - // Define Source: - - $this->setSource($source); - - // Define Empty Value: - - $this->setEmptyValue(_t(__CLASS__ . '.DEFAULTEMPTYVALUE', '(none)')); - - // Construct Parent: - - parent::__construct($name, $title, $value); - } - - /** - * Answers an array of HTML attributes for the field. - * - * @return array - */ - public function getAttributes() - { - $attributes = array_merge( - parent::getAttributes(), - [ - 'data-source-url' => $this->getSourceURL(), - 'data-min-length' => $this->getTermMinLength(), - 'data-free-text' => $this->getAllowFreeText(), - 'data-empty-value' => $this->getEmptyValue(), - 'data-delay' => $this->getDelay() - ] - ); - - $attributes['name'] = $this->getAutoCompleteName(); - $attributes['value'] = null; - - return $attributes; - } - - /** - * Answers the name for the auto-complete field. - * - * @return string - */ - public function getAutoCompleteName() - { - return sprintf('%s_autocomplete', $this->getName()); - } - - /** - * Defines the value of the source attribute. - * - * @param array $source - * - * @return $this - */ - public function setSource($source) - { - $this->source = $this->getSourceAsArray($source); - - return $this; - } - - /** - * Answers the value of the source attribute. - * - * @return array - */ - public function getSource() - { - return $this->source; - } - - /** - * Answers the source URL of the field. - * - * @return string - */ - public function getSourceURL() - { - return $this->hasSourceURL() ? $this->sourceURL : $this->Link('suggest'); - } - - /** - * Answers true if a source URL is defined. - * - * @return boolean - */ - public function hasSourceURL() - { - return (boolean) $this->sourceURL; - } - - /** - * Defines the value of the allowFreeText attribute. - * - * @param boolean $allowFreeText - * - * @return $this - */ - public function setAllowFreeText($allowFreeText) - { - $this->allowFreeText = (boolean) $allowFreeText; - - return $this; - } - - /** - * Answers the value of the allowFreeText attribute. - * - * @return boolean - */ - public function getAllowFreeText() - { - return $this->allowFreeText; - } - - /** - * Defines the value of the termMinLength attribute. - * - * @param integer $termMinLength - * - * @return $this - */ - public function setTermMinLength($termMinLength) - { - $this->termMinLength = (integer) $termMinLength; - - return $this; - } - - /** - * Answers the value of the termMinLength attribute. - * - * @return integer - */ - public function getTermMinLength() - { - return $this->termMinLength; - } - - /** - * Defines the value of the delay attribute. - * - * @param integer $delay - * - * @return $this - */ - public function setDelay($delay) - { - $this->delay = (integer) $delay; - - return $this; - } - - /** - * Answers the value of the delay attribute. - * - * @return integer - */ - public function getDelay() - { - return $this->delay; - } - - /** - * Defines the value of the emptyValue attribute. - * - * @param string $emptyValue - * - * @return $this - */ - public function setEmptyValue($emptyValue) - { - $this->emptyValue = (string) $emptyValue; - - return $this; - } - - /** - * Answers the value of the emptyValue attribute. - * - * @return string - */ - public function getEmptyValue() - { - return $this->emptyValue; - } - - /** - * Answers the field type for the template. - * - * @return string - */ - public function Type() - { - return 'autocomplete text'; - } - - /** - * Answers a string of JSON-encoded suggestions for the entered term. - * - * @param HTTPRequest $request - * - * @return string - */ - public function suggest(HTTPRequest $request) - { - $data = []; - - if ($request->isAjax()) { - - $term = $request->getVar('term'); - - foreach ($this->getMatches($term) as $key => $value) { - $data[] = [ - 'value' => $key, - 'label' => $value - ]; - } - - } - - return json_encode($data); - } - - /** - * Answers an array of source items matching the given term. - * - * @param string $term - * - * @return array - */ - public function getMatches($term) - { - return array_filter($this->getSource(), function ($item) use ($term) { - return ( strpos($item, $term) !== false ); - }); - } - - /** - * Converts the given source parameter to an array. - * - * @param array|ArrayAccess $source - * - * @return array - */ - protected function getSourceAsArray($source) - { - if (!is_array($source) && !($source instanceof ArrayAccess)) { - user_error('$source passed in as invalid type', E_USER_ERROR); - } - - if ($source instanceof SS_List || $source instanceof Map) { - $source = $source->toArray(); - } - - return $source; - } -} diff --git a/src/Forms/TagField.php b/src/Forms/TagField.php new file mode 100644 index 0000000..18e8142 --- /dev/null +++ b/src/Forms/TagField.php @@ -0,0 +1,257 @@ +=5.6.0 + * + * For full copyright and license information, please view the + * LICENSE.md file that was distributed with this source code. + * + * @package SilverWare\Forms + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ + +namespace SilverWare\Forms; + +use SilverStripe\Core\Injector\Injector; +use SilverStripe\ORM\DataObjectInterface; +use SilverStripe\ORM\Relation; +use SilverWare\Select2\Forms\Select2AjaxField; +use SilverWare\Tags\Tag; +use Exception; + +/** + * An extension of the Select2 Ajax field for a tag field. + * + * @package SilverWare\Forms + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ +class TagField extends Select2AjaxField +{ + /** + * An array which defines the default configuration for instances. + * + * @var array + * @config + */ + private static $default_config = [ + 'minimum-input-length' => 0 + ]; + + /** + * Defines whether Ajax is enabled or disabled for the field. + * + * @var boolean + */ + protected $ajaxEnabled = false; + + /** + * The tag class to search via Ajax. + * + * @var string + */ + protected $dataClass = Tag::class; + + /** + * The ID field for the tag class. + * + * @var string + */ + protected $idField = 'Title'; + + /** + * The title field for the tag class. + * + * @var string + */ + protected $titleField = 'Title'; + + /** + * Defines whether the field can create new tags. + * + * @var boolean + */ + protected $canCreate = true; + + /** + * Defines whether the field can handle multiple tags. + * + * @var boolean + */ + protected $multiple = true; + + /** + * Constructs the object upon instantiation. + * + * @param string $name + * @param string $title + * @param array|ArrayAccess $source + * @param mixed $value + */ + public function __construct($name, $title = null, $source = [], $value = null) + { + // Construct Parent: + + parent::__construct($name, $title, $source, $value); + + // Define Object: + + $this->setHasEmptyDefault(false); + } + + /** + * Answers the field type for the template. + * + * @return string + */ + public function Type() + { + return sprintf('tagfield %s', parent::Type()); + } + + /** + * Defines the value of the canCreate attribute. + * + * @param boolean $canCreate + * + * @return $this + */ + public function setCanCreate($canCreate) + { + $this->canCreate = (boolean) $canCreate; + + return $this; + } + + /** + * Answers the value of the canCreate attribute. + * + * @return boolean + */ + public function getCanCreate() + { + return $this->canCreate; + } + + /** + * Saves the value of the field into the given data object. + * + * @param DataObjectInterface $record + * + * @throws Exception + * + * @return void + */ + public function saveInto(DataObjectInterface $record) + { + // Initialise: + + $ids = []; + + // Obtain Field Name: + + $fieldName = $this->getName(); + + // Bail Early (if needed): + + if (empty($fieldName) || empty($record)) { + return; + } + + // Obtain Relation: + + if (!($relation = $this->getNamedRelation($record))) { + + throw new Exception( + sprintf( + '%s does not have a relation named "%s"', + get_class($record), + $this->Name + ) + ); + + } + + // Iterate Value Array: + + foreach ($this->getValueArray() as $title) { + + // Obtain or Create Tag: + + if ($tag = $this->findOrMakeTag($title, $relation)) { + $ids[] = $tag->ID; + } + + } + + // Update Relation: + + $relation->setByIDList($ids); + } + + /** + * Obtains or creates a tag object with the given title. + * + * @param string $title + * @param Relation $relation + * + * @return Tag + */ + protected function findOrMakeTag($title, $relation) + { + // Obtain Data List: + + $list = $this->getList(); + + // Obtain Field Name: + + $field = $this->getIDField(); + + // Obtain Existing Tag: + + if ($tag = $list->find($field, $title)) { + return $tag; + } + + // Create New Tag (if enabled): + + if ($this->getCanCreate()) { + $tag = Injector::inst()->create($this->getTagClass($relation)); + $tag->setField($field, $title)->write(); + return $tag; + } + } + + /** + * Answers the tag class used by the field (uses the relation to identify if no source list defined). + * + * @param Relation $relation + * + * @return string + */ + protected function getTagClass(Relation $relation) + { + return ($this->dataClass == Tag::class) ? $relation->dataClass() : $this->dataClass; + } + + /** + * Answers the field config for the receiver. + * + * @return array + */ + protected function getFieldConfig() + { + $config = parent::getFieldConfig(); + + $config['tags'] = (boolean) $this->getCanCreate(); + + return $config; + } +} diff --git a/src/Forms/ToggleGroup.php b/src/Forms/ToggleGroup.php new file mode 100644 index 0000000..1cc2d06 --- /dev/null +++ b/src/Forms/ToggleGroup.php @@ -0,0 +1,224 @@ +=5.6.0 + * + * For full copyright and license information, please view the + * LICENSE.md file that was distributed with this source code. + * + * @package SilverWare\Forms + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ + +namespace SilverWare\Forms; + +use SilverStripe\Forms\CheckboxField; +use SilverStripe\Forms\CompositeField; + +/** + * An extension of the composite field class for a toggleable group of fields. + * + * @package SilverWare\Forms + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ +class ToggleGroup extends CompositeField +{ + /** + * Maps field and method names to the class names of casting objects. + * + * @var array + * @config + */ + private static $casting = [ + 'ShowWhenChecked' => 'Boolean' + ]; + + /** + * The name of the toggle field. + * + * @var string + */ + protected $toggleName; + + /** + * The title of the toggle field. + * + * @var string + */ + protected $toggleTitle; + + /** + * The toggle field instance. + * + * @var CheckboxField + */ + protected $toggleField; + + /** + * Determines whether the fields are to be shown when the field is checked or unchecked. + * + * @var boolean + */ + protected $showWhenChecked = true; + + /** + * Constructs the object upon instantiation. + * + * @param string $name Name of field. + * @param string $title Title of field. + * @param array|FieldList $children Child fields. + */ + public function __construct($name, $title, $children) + { + // Construct Parent: + + parent::__construct($children); + + // Define Attributes: + + $this->setToggleName($name); + $this->setToggleTitle($title); + + // Create Toggle Field: + + $this->setToggleField( + CheckboxField::create( + $name, + $title + ) + ); + } + + /** + * Defines the value of the toggleName attribute. + * + * @param string $toggleName + * + * @return $this + */ + public function setToggleName($toggleName) + { + $this->toggleName = (string) $toggleName; + + return $this; + } + + /** + * Answers the value of the toggleName attribute. + * + * @return string + */ + public function getToggleName() + { + return $this->toggleName; + } + + /** + * Defines the value of the toggleTitle attribute. + * + * @param string $toggleTitle + * + * @return $this + */ + public function setToggleTitle($toggleTitle) + { + $this->toggleTitle = (string) $toggleTitle; + + return $this; + } + + /** + * Answers the value of the toggleTitle attribute. + * + * @return string + */ + public function getToggleTitle() + { + return $this->toggleTitle; + } + + /** + * Defines the value of the toggleField attribute. + * + * @param CheckboxField $toggleField + * + * @return $this + */ + public function setToggleField(CheckboxField $toggleField) + { + $this->toggleField = $toggleField; + + return $this; + } + + /** + * Answers the value of the toggleField attribute. + * + * @return CheckboxField + */ + public function getToggleField() + { + return $this->toggleField; + } + + /** + * Defines the container form instance for the receiver. + * + * @param Form $form + * + * @return $this + */ + public function setForm($form) + { + $this->toggleField->setForm($form); + + return parent::setForm($form); + } + + /** + * Defines the value of the showWhenChecked attribute. + * + * @param boolean $showWhenChecked + * + * @return $this + */ + public function setShowWhenChecked($showWhenChecked) + { + $this->showWhenChecked = (boolean) $showWhenChecked; + + return $this; + } + + /** + * Answers the value of the showWhenChecked attribute. + * + * @return boolean + */ + public function getShowWhenChecked() + { + return $this->showWhenChecked; + } + + /** + * Collates all data fields within the receiver into the given list. + * + * @param array $list + * @param boolean $saveableOnly + * + * @return void + */ + public function collateDataFields(&$list, $saveableOnly = false) + { + $list[$this->ToggleName] = $this->getToggleField(); + + parent::collateDataFields($list, $saveableOnly); + } +} diff --git a/src/Grid/Column.php b/src/Grid/Column.php index 2f79703..3125600 100644 --- a/src/Grid/Column.php +++ b/src/Grid/Column.php @@ -264,6 +264,6 @@ public function getTag() */ public function renderSelf($layout = null, $title = null) { - return $this->tag($this->renderChildren($layout, $title)); + return $this->renderTag($this->renderChildren($layout, $title)); } } diff --git a/src/Grid/Frameworks/Bootstrap/Row.php b/src/Grid/Frameworks/Bootstrap/Row.php index 423451d..6a024e9 100644 --- a/src/Grid/Frameworks/Bootstrap/Row.php +++ b/src/Grid/Frameworks/Bootstrap/Row.php @@ -30,4 +30,17 @@ */ class Row extends RowExtension { + /** + * Updates the given array of class names from the extended object. + * + * @param array $classes + * + * @return void + */ + public function updateClassNames(&$classes) + { + if ($this->owner->isNoGutters()) { + $classes[] = $this->style('row.no-gutters'); + } + } } diff --git a/src/Grid/Frameworks/Bootstrap/Section.php b/src/Grid/Frameworks/Bootstrap/Section.php index ab495e9..89bbf09 100644 --- a/src/Grid/Frameworks/Bootstrap/Section.php +++ b/src/Grid/Frameworks/Bootstrap/Section.php @@ -30,6 +30,20 @@ */ class Section extends SectionExtension { + /** + * Updates the given array of class names from the extended object. + * + * @param array $classes + * + * @return void + */ + public function updateClassNames(&$classes) + { + if ($position = $this->owner->Position) { + $classes[] = $this->style('position', $position); + } + } + /** * Answers the container class names for the extended object. * @@ -37,6 +51,12 @@ class Section extends SectionExtension */ public function getClassNamesForContainer() { - return [$this->owner->isFullWidth() ? 'container-fluid' : 'container']; + $classes = [$this->owner->isFullWidth() ? 'container-fluid' : 'container']; + + if ($this->owner->isEdgeToEdge()) { + $classes[] = $this->style('section.edge-to-edge'); + } + + return $classes; } } diff --git a/src/Grid/Row.php b/src/Grid/Row.php index 0a0eb17..f056160 100644 --- a/src/Grid/Row.php +++ b/src/Grid/Row.php @@ -17,6 +17,9 @@ namespace SilverWare\Grid; +use SilverStripe\Forms\CheckboxField; +use SilverWare\Forms\FieldSection; + /** * An extension of the grid class for a row. * @@ -76,6 +79,26 @@ class Row extends Grid */ private static $default_child = Column::class; + /** + * Maps field names to field types for this object. + * + * @var array + * @config + */ + private static $db = [ + 'NoGutters' => 'Boolean' + ]; + + /** + * Defines the default values for the fields of this object. + * + * @var array + * @config + */ + private static $defaults = [ + 'NoGutters' => 0 + ]; + /** * Defines the allowed children for this object. * @@ -86,6 +109,71 @@ class Row extends Grid Column::class ]; + /** + * Answers a list of field objects for the CMS interface. + * + * @return FieldList + */ + public function getCMSFields() + { + // Obtain Field Objects (from parent): + + $fields = parent::getCMSFields(); + + // Create Options Fields: + + $fields->addFieldToTab( + 'Root.Options', + FieldSection::create( + 'RowOptions', + $this->fieldLabel('RowOptions'), + [ + CheckboxField::create( + 'NoGutters', + $this->fieldLabel('NoGutters') + ) + ] + ) + ); + + // Answer Field Objects: + + return $fields; + } + + /** + * Answers the labels for the fields of the receiver. + * + * @param boolean $includerelations Include labels for relations. + * + * @return array + */ + public function fieldLabels($includerelations = true) + { + // Obtain Field Labels (from parent): + + $labels = parent::fieldLabels($includerelations); + + // Define Field Labels: + + $labels['NoGutters'] = _t(__CLASS__ . '.NOGUTTERS', 'No gutters'); + $labels['RowOptions'] = _t(__CLASS__ . '.ROW', 'Row'); + + // Answer Field Labels: + + return $labels; + } + + /** + * Answers true if the row does not use gutters. + * + * @return boolean + */ + public function isNoGutters() + { + return (boolean) $this->NoGutters; + } + /** * Renders the component for the HTML template. * @@ -96,6 +184,6 @@ class Row extends Grid */ public function renderSelf($layout = null, $title = null) { - return $this->tag($this->renderChildren($layout, $title)); + return $this->renderTag($this->renderChildren($layout, $title)); } } diff --git a/src/Grid/Section.php b/src/Grid/Section.php index 1997000..7be5cbc 100644 --- a/src/Grid/Section.php +++ b/src/Grid/Section.php @@ -18,6 +18,7 @@ namespace SilverWare\Grid; use SilverStripe\Forms\CheckboxField; +use SilverStripe\Forms\DropdownField; use SilverWare\Forms\FieldSection; /** @@ -31,6 +32,13 @@ */ class Section extends Grid { + /** + * Define position constants. + */ + const POSITION_FIXED_TOP = 'fixed-top'; + const POSITION_FIXED_BOTTOM = 'fixed-bottom'; + const POSITION_STICKY_TOP = 'sticky-top'; + /** * Human-readable singular name. * @@ -86,7 +94,9 @@ class Section extends Grid * @config */ private static $db = [ - 'FullWidth' => 'Boolean' + 'Position' => 'Varchar(16)', + 'FullWidth' => 'Boolean', + 'EdgeToEdge' => 'Boolean' ]; /** @@ -96,7 +106,8 @@ class Section extends Grid * @config */ private static $defaults = [ - 'FullWidth' => 0 + 'FullWidth' => 0, + 'EdgeToEdge' => 0 ]; /** @@ -120,6 +131,27 @@ public function getCMSFields() $fields = parent::getCMSFields(); + // Define Placeholder: + + $placeholder = _t(__CLASS__ . '.DROPDOWNDEFAULT', '(default)'); + + // Create Style Fields: + + $fields->addFieldToTab( + 'Root.Style', + FieldSection::create( + 'SectionStyle', + $this->fieldLabel('SectionStyle'), + [ + DropdownField::create( + 'Position', + $this->fieldLabel('Position'), + $this->getPositionOptions() + )->setEmptyString(' ')->setAttribute('data-placeholder', $placeholder) + ] + ) + ); + // Create Options Fields: $fields->addFieldToTab( @@ -131,6 +163,10 @@ public function getCMSFields() CheckboxField::create( 'FullWidth', $this->fieldLabel('FullWidth') + ), + CheckboxField::create( + 'EdgeToEdge', + $this->fieldLabel('EdgeToEdge') ) ] ) @@ -156,8 +192,10 @@ public function fieldLabels($includerelations = true) // Define Field Labels: + $labels['Position'] = _t(__CLASS__ . '.POSITION', 'Position'); $labels['FullWidth'] = _t(__CLASS__ . '.USEFULLWIDTHCONTAINER', 'Use full width container'); - $labels['SectionOptions'] = _t(__CLASS__ . '.SECTION', 'Section'); + $labels['EdgeToEdge'] = _t(__CLASS__ . '.EDGETOEDGE', 'Edge-to-edge (remove padding)'); + $labels['SectionStyle'] = $labels['SectionOptions'] = _t(__CLASS__ . '.SECTION', 'Section'); // Answer Field Labels: @@ -178,6 +216,16 @@ public function getContainerClassNames() return $classes; } + /** + * Answers true if the section uses an edge-to-edge container. + * + * @return boolean + */ + public function isEdgeToEdge() + { + return (boolean) $this->EdgeToEdge; + } + /** * Answers true if the section uses a full width container. * @@ -198,7 +246,7 @@ public function isFullWidth() */ public function renderSelf($layout = null, $title = null) { - return $this->tag($this->renderContainer($layout, $title)); + return $this->renderTag($this->renderContainer($layout, $title)); } /** @@ -217,4 +265,18 @@ public function renderContainer($layout = null, $title = null) $this->renderChildren($layout, $title) ); } + + /** + * Answers an array of options for the position field. + * + * @return array + */ + public function getPositionOptions() + { + return [ + self::POSITION_FIXED_TOP => _t(__CLASS__ . '.FIXEDTOP', 'Fixed Top'), + self::POSITION_FIXED_BOTTOM => _t(__CLASS__ . '.FIXEDBOTTOM', 'Fixed Bottom'), + self::POSITION_STICKY_TOP => _t(__CLASS__ . '.STICKYTOP', 'Sticky Top') + ]; + } } diff --git a/src/Lists/ListAlert.php b/src/Lists/ListAlert.php new file mode 100644 index 0000000..98ac18c --- /dev/null +++ b/src/Lists/ListAlert.php @@ -0,0 +1,110 @@ +=5.6.0 + * + * For full copyright and license information, please view the + * LICENSE.md file that was distributed with this source code. + * + * @package SilverWare\Lists + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ + +namespace SilverWare\Lists; + +use SilverStripe\ORM\ArrayList; +use SilverStripe\View\ArrayData; + +/** + * Allows an object to add alert messages to a list component. + * + * @package SilverWare\Lists + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ +trait ListAlert +{ + /** + * Defines the alerts to be added to the list source. + * + * @var array + */ + protected $listAlerts = []; + + /** + * Defines the value of the listAlerts attribute. + * + * @param array $listAlerts + * + * @return $this + */ + public function setListAlerts($listAlerts) + { + $this->listAlerts = (array) $listAlerts; + + return $this; + } + + /** + * Answers the value of the listAlerts attribute. + * + * @return array + */ + public function getListAlerts() + { + return $this->listAlerts; + } + + /** + * Answers an array list of alerts for the template. + * + * @return ArrayList + */ + public function getListAlertsData() + { + $alerts = ArrayList::create(); + + foreach ($this->getListAlerts() as $alert) { + $alerts->push(ArrayData::create($alert)); + } + + return $alerts; + } + + /** + * Adds an alert with the given details to the array of alerts. + * + * @param string $text + * @param string $type + * @param string $icon + * + * @return $this + */ + public function addListAlert($text, $type = 'primary', $icon = 'info-circle') + { + $this->listAlerts[] = [ + 'Text' => $text, + 'Type' => $type, + 'Icon' => $icon + ]; + + return $this; + } + + /** + * Answers true if the receiver has at least one list alert. + * + * @return boolean + */ + public function hasListAlerts() + { + return !empty($this->listAlerts); + } +} diff --git a/src/Lists/ListSourceSlide.php b/src/Lists/ListSourceSlide.php new file mode 100644 index 0000000..e0bc601 --- /dev/null +++ b/src/Lists/ListSourceSlide.php @@ -0,0 +1,178 @@ +=5.6.0 + * + * For full copyright and license information, please view the + * LICENSE.md file that was distributed with this source code. + * + * @package SilverWare\Lists + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ + +namespace SilverWare\Lists; + +use SilverStripe\Core\Injector\Injector; +use SilverStripe\ORM\ArrayList; +use SilverStripe\View\ViewableData; +use SilverWare\Extensions\Lists\ListSourceExtension; +use SilverWare\Extensions\Model\LinkToExtension; +use SilverWare\Model\Slide; + +/** + * An extension of the slide class which creates a series of slides from a list source. + * + * @package SilverWare\Lists + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ +class ListSourceSlide extends Slide +{ + /** + * Human-readable singular name. + * + * @var string + * @config + */ + private static $singular_name = 'List Source Slide'; + + /** + * Human-readable plural name. + * + * @var string + * @config + */ + private static $plural_name = 'List Source Slides'; + + /** + * Description of this object. + * + * @var string + * @config + */ + private static $description = 'Shows list items as a series of slides'; + + /** + * Icon file for this object. + * + * @var string + * @config + */ + private static $icon = 'silverware/admin/client/dist/images/icons/ListSourceSlide.png'; + + /** + * Defines the extension classes to apply to this object. + * + * @var array + * @config + */ + private static $extensions = [ + ListSourceExtension::class + ]; + + /** + * Answers a list of field objects for the CMS interface. + * + * @return FieldList + */ + public function getCMSFields() + { + // Obtain Field Objects (from parent): + + $fields = parent::getCMSFields(); + + // Remove Field Objects: + + $fields->removeFieldsFromTab('Root.Main', ['Image', 'Caption', 'LinkTo']); + + // Answer Field Objects: + + return $fields; + } + + /** + * Populates the default values for the fields of the receiver. + * + * @return void + */ + public function populateDefaults() + { + // Populate Defaults (from parent): + + parent::populateDefaults(); + + // Populate Defaults: + + $this->ImageItems = true; + } + + /** + * Answers a list of the enabled slides within the receiver. + * + * @return ArrayList + */ + public function getEnabledSlides() + { + $slides = ArrayList::create(); + + foreach ($this->getListItems() as $item) { + + if ($slide = $this->createSlide($item)) { + $slides->push($slide); + } + + } + + return $slides; + } + + /** + * Answers true if the slide is disabled within the template. + * + * @return boolean + */ + public function isDisabled() + { + return !$this->hasListItems(); + } + + /** + * Creates a slide for the given list item. + * + * @param ViewableData $item + * + * @return Slide + */ + protected function createSlide(ViewableData $item) + { + // Create Slide Object: + + $slide = Slide::create([ + 'Title' => $item->MetaTitle, + 'ImageID' => $item->MetaImageID, + 'Caption' => $item->MetaImageCaption, + 'ParentID' => $this->ParentID, + 'HideImage' => $this->HideImage, + 'HideTitle' => $this->HideTitle, + 'HideCaption' => $this->HideCaption + ]); + + // Define Slide Link: + + $slide->LinkTo = LinkToExtension::MODE_URL; + $slide->LinkURL = $item->MetaAbsoluteLink; + $slide->LinkDisabled = $this->LinkDisabled; + $slide->OpenLinkInNewTab = $this->OpenLinkInNewTab; + + // Answer Slide Object: + + return $slide; + } +} diff --git a/src/Model/Component.php b/src/Model/Component.php index 831f6a8..76e443e 100644 --- a/src/Model/Component.php +++ b/src/Model/Component.php @@ -159,6 +159,13 @@ class Component extends SiteTree implements Flushable, PermissionProvider */ protected $cacheEnabledComponents; + /** + * Holds the parent instance of the receiver. + * + * @var SiteTree + */ + protected $parentInstance; + /** * Clears the component render cache upon flush. * @@ -247,6 +254,36 @@ public function fieldLabels($includerelations = true) return $labels; } + /** + * Defines the parent of the receiver. + * + * @param SiteTree|int $item + * + * @return void + */ + public function setParent($item) + { + // Record Parent Instance: + + if ($item instanceof SiteTree) { + $this->parentInstance = $item; + } + + // Call Parent Method: + + return parent::setParent($item); + } + + /** + * Answers the parent instance of the receiver (if available). + * + * @return SiteTree + */ + public function getParentInstance() + { + return $this->parentInstance; + } + /** * Answers a string of CSS classes to apply to the receiver in the CMS tree. * @@ -763,7 +800,7 @@ public function getClosingTag() * * @return string */ - public function tag($content = null) + public function renderTag($content = null) { return $this->getOpeningTag() . $content . $this->getClosingTag(); } diff --git a/src/Model/ComponentController.php b/src/Model/ComponentController.php index 7159521..4cf1ab6 100644 --- a/src/Model/ComponentController.php +++ b/src/Model/ComponentController.php @@ -18,6 +18,7 @@ namespace SilverWare\Model; use SilverStripe\CMS\Controllers\ContentController; +use SilverStripe\Control\HTTPRequest; use SilverStripe\View\Requirements; use SilverStripe\View\SSViewer; use Page; @@ -34,6 +35,32 @@ */ class ComponentController extends ContentController { + /** + * Defines the allowed actions for this controller. + * + * @var array + * @config + */ + private static $allowed_actions = [ + 'index' + ]; + + /** + * Default action for a component controller. + * + * @param HTTPRequest $request + * + * @return HTTPResponse + */ + public function index(HTTPRequest $request) + { + if (!$this->isCMSPreview()) { + $this->httpError(404); + } + + return $this->render(); + } + /** * Answers a viewer object to render the template for the current page. * diff --git a/src/Model/Link.php b/src/Model/Link.php index 3dbde83..692a7a4 100644 --- a/src/Model/Link.php +++ b/src/Model/Link.php @@ -198,6 +198,7 @@ public function getCornerStyleClass() public function fromPage(Page $page, $nameField = 'MenuTitle') { $this->Title = $page->{$nameField}; + $this->LinkTo = LinkToExtension::MODE_PAGE; $this->LinkPageID = $page->ID; return $this; diff --git a/src/Model/Slide.php b/src/Model/Slide.php index 0b6d2e2..18f52da 100644 --- a/src/Model/Slide.php +++ b/src/Model/Slide.php @@ -22,14 +22,16 @@ use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\HTMLEditor\HTMLEditorField; use SilverStripe\Forms\TextField; +use SilverStripe\ORM\ArrayList; use SilverWare\Extensions\Model\LinkToExtension; use SilverWare\Forms\FieldSection; use SilverWare\Forms\PageDropdownField; +use SilverWare\Tools\ImageTools; use SilverWare\Tools\ViewTools; use Page; /** - * An extension of the link class for a slide. + * An extension of the component class for a slide. * * @package SilverWare\Model * @author Colin Tucker @@ -71,6 +73,22 @@ class Slide extends Component */ private static $icon = 'silverware/admin/client/dist/images/icons/Slide.png'; + /** + * Defines an ancestor class to hide from the admin interface. + * + * @var string + * @config + */ + private static $hide_ancestor = Component::class; + + /** + * Defines the allowed children for this object. + * + * @var array|string + * @config + */ + private static $allowed_children = 'none'; + /** * Maps field names to field types for this object. * @@ -79,6 +97,7 @@ class Slide extends Component */ private static $db = [ 'Caption' => 'HTMLText', + 'HideImage' => 'Boolean', 'HideTitle' => 'Boolean', 'HideCaption' => 'Boolean', 'LinkDisabled' => 'Boolean' @@ -104,6 +123,16 @@ class Slide extends Component 'Image' ]; + /** + * Maps field and method names to the class names of casting objects. + * + * @var array + * @config + */ + private static $casting = [ + 'getSlideAttributesHTML' => 'HTMLFragment' + ]; + /** * Defines the default values for the fields of this object. * @@ -111,6 +140,7 @@ class Slide extends Component * @config */ private static $defaults = [ + 'HideImage' => 0, 'HideTitle' => 1, 'HideCaption' => 0, 'LinkDisabled' => 0 @@ -142,6 +172,14 @@ class Slide extends Component */ private static $heading_level_default = 'h4'; + /** + * Tag name to use when rendering this object. + * + * @var string + * @config + */ + private static $tag = 'div'; + /** * Answers a list of field objects for the CMS interface. * @@ -177,6 +215,10 @@ public function getCMSFields() 'HideTitle', $this->fieldLabel('HideTitle') ), + CheckboxField::create( + 'HideImage', + $this->fieldLabel('HideImage') + ), CheckboxField::create( 'HideCaption', $this->fieldLabel('HideCaption') @@ -214,6 +256,7 @@ public function fieldLabels($includerelations = true) // Define Checkbox Field Labels: + $labels['HideImage'] = _t(__CLASS__ . '.HIDEIMAGE', 'Hide image'); $labels['HideTitle'] = _t(__CLASS__ . '.HIDETITLE', 'Hide title'); $labels['HideCaption'] = _t(__CLASS__ . '.HIDECAPTION', 'Hide caption'); $labels['LinkDisabled'] = _t(__CLASS__ . '.LINKDISABLED', 'Link disabled'); @@ -229,6 +272,20 @@ public function fieldLabels($includerelations = true) return $labels; } + /** + * Answers the tag for the receiver. + * + * @return string + */ + public function getTag() + { + if ($tag = $this->getParent()->SlideTag) { + return $tag; + } + + return parent::getTag(); + } + /** * Answers the heading tag for the receiver. * @@ -243,6 +300,52 @@ public function getHeadingTag() return $this->config()->heading_level_default; } + /** + * Answers an array of HTML tag attributes for the slide. + * + * @param boolean $isFirst Slide is first in the list. + * @param boolean $isMiddle Slide is in the middle of the list. + * @param boolean $isLast Slide is last in the list. + * + * @return array + */ + public function getSlideAttributes($isFirst = false, $isMiddle = false, $isLast = false) + { + $attributes = ['class' => $this->getSlideClass($isFirst, $isMiddle, $isLast)]; + + if ($this->getParent()->hasMethod('getSlideAttributes')) { + + $attributes = array_merge( + $attributes, + $this->getParent()->getSlideAttributes( + $this, + $isFirst, + $isMiddle, + $isLast + ) + ); + + } + + $this->extend('updateSlideAttributes', $attributes); + + return $attributes; + } + + /** + * Answers the HTML tag attributes for the slide as a string. + * + * @param boolean $isFirst Slide is first in the list. + * @param boolean $isMiddle Slide is in the middle of the list. + * @param boolean $isLast Slide is last in the list. + * + * @return string + */ + public function getSlideAttributesHTML($isFirst = false, $isMiddle = false, $isLast = false) + { + return $this->getAttributesHTML($this->getSlideAttributes($isFirst, $isMiddle, $isLast)); + } + /** * Answers a string of slide class names for the HTML template. * @@ -270,6 +373,22 @@ public function getSlideClassNames($isFirst = false, $isMiddle = false, $isLast { $classes = ViewTools::singleton()->getAncestorClassNames($this, self::class); + $classes[] = $this->ImageShown ? 'has-image' : 'no-image'; + + if ($this->getParent()->hasMethod('getSlideClassNames')) { + + $classes = array_merge( + $classes, + $this->getParent()->getSlideClassNames( + $this, + $isFirst, + $isMiddle, + $isLast + ) + ); + + } + $this->extend('updateSlideClassNames', $classes, $isFirst, $isMiddle, $isLast); return $classes; @@ -284,6 +403,10 @@ public function getImageClassNames() { $classes = ['slide-image']; + if ($this->getParent()->hasMethod('getImageClassNames')) { + $classes = array_merge($classes, $this->getParent()->getImageClassNames($this)); + } + $this->extend('updateImageClassNames', $classes); return $classes; @@ -298,6 +421,10 @@ public function getCaptionClassNames() { $classes = ['slide-caption']; + if ($this->getParent()->hasMethod('getCaptionClassNames')) { + $classes = array_merge($classes, $this->getParent()->getCaptionClassNames($this)); + } + $this->extend('updateCaptionClassNames', $classes); return $classes; @@ -310,6 +437,10 @@ public function getCaptionClassNames() */ public function getAssetFolder() { + if ($folder = $this->getParent()->AssetFolder) { + return $folder; + } + return $this->config()->asset_folder; } @@ -362,22 +493,44 @@ public function hasPageImage() */ public function getImageShown() { - return $this->hasImage(); + return ($this->hasImage() && !$this->HideImage); } /** - * Answers a resized image using the dimensions and resize method from the parent object. + * Answers the image for the slide. * * @return Image */ - public function getImageResized() + public function getSlideImage() { if ($this->hasImage()) { if ($this->Image()->exists()) { - $image = $this->Image(); + return $this->Image(); } elseif ($this->LinkPage()->hasMetaImage()) { - $image = $this->LinkPage()->getMetaImage(); + return $this->LinkPage()->getMetaImage(); + } + + } + } + + /** + * Answers a resized image using the dimensions and resize method from the parent object. + * + * @param integer $width + * @param integer $height + * @param string $method + * + * @return Image + */ + public function getImageResized($width = null, $height = null, $method = null) + { + if ($this->hasImage()) { + + $image = $this->getSlideImage(); + + if ($width || $height || $method) { + return ImageTools::singleton()->resize($image, $width, $height, $method); } if ($this->getParent()->hasMethod('performImageResize')) { @@ -430,17 +583,33 @@ public function getLinkShown() } /** - * Answers true if the slide is disabled within the template. + * Answers a list of the enabled slides within the receiver. * - * @return boolean + * @return ArrayList + */ + public function getEnabledSlides() + { + $slides = ArrayList::create(); + + if ($this->isEnabled()) { + $slides->push($this); + } + + return $slides; + } + + /** + * Answers the template used to render the receiver. + * + * @return string|array|SSViewer */ - public function isDisabled() + public function getTemplate() { - if (!$this->hasImage()) { - return true; + if ($template = $this->getParent()->SlideTemplate) { + return $template; } - return parent::isDisabled(); + return parent::getTemplate(); } /** diff --git a/src/Pages/ListPage.php b/src/Pages/ListPage.php new file mode 100644 index 0000000..0ef7aa9 --- /dev/null +++ b/src/Pages/ListPage.php @@ -0,0 +1,87 @@ +=5.6.0 + * + * For full copyright and license information, please view the + * LICENSE.md file that was distributed with this source code. + * + * @package SilverWare\Pages + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ + +namespace SilverWare\Pages; + +use SilverWare\Extensions\Lists\ListViewExtension; +use SilverWare\Extensions\Model\ImageDefaultsExtension; +use Page; + +/** + * An extension of the page class for a list page. + * + * @package SilverWare\Pages + * @author Colin Tucker + * @copyright 2017 Praxis Interactive + * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause + * @link https://github.com/praxisnetau/silverware + */ +class ListPage extends Page +{ + /** + * Human-readable singular name. + * + * @var string + * @config + */ + private static $singular_name = 'List Page'; + + /** + * Human-readable plural name. + * + * @var string + * @config + */ + private static $plural_name = 'List Pages'; + + /** + * Description of this object. + * + * @var string + * @config + */ + private static $description = 'Shows the children of this page as a list'; + + /** + * Icon file for this object. + * + * @var string + * @config + */ + private static $icon = 'silverware/admin/client/dist/images/icons/ListPage.png'; + + /** + * Defines the extension classes to apply to this object. + * + * @var array + * @config + */ + private static $extensions = [ + ListViewExtension::class, + ImageDefaultsExtension::class + ]; + + /** + * Answers the source for the list component. + * + * @return SS_List + */ + public function getListSource() + { + return $this->AllChildren(); + } +} diff --git a/src/Sections/LayoutSection.php b/src/Sections/LayoutSection.php index 2603d9f..c8a0dcd 100644 --- a/src/Sections/LayoutSection.php +++ b/src/Sections/LayoutSection.php @@ -141,6 +141,7 @@ public function getPageLayout() */ public function renderSelf($layout = null, $title = null) { - return $this->tag($this->getPageLayout()->render($layout, $title)); + return $this->renderTag($this->getPageLayout()->render($layout, $title)); } } + diff --git a/src/Tags/Tag.php b/src/Tags/Tag.php index d03e08b..06f6bb6 100644 --- a/src/Tags/Tag.php +++ b/src/Tags/Tag.php @@ -256,7 +256,7 @@ public function getTagged() { foreach ($this->manyMany() as $name => $class) { - if (self::getSchema()->manyManyComponent(static::class, $name)[1] === static::class) { + if (self::getSchema()->manyManyComponent(static::class, $name)['parentClass'] === static::class) { return $this->getManyManyComponents($name); } diff --git a/src/View/Renderable.php b/src/View/Renderable.php index 8a76ba5..7d41c85 100644 --- a/src/View/Renderable.php +++ b/src/View/Renderable.php @@ -397,10 +397,14 @@ public function getCustomCSS() // Merge Custom CSS from Template: - $template = $this->getCustomCSSTemplate(); - - if (SSViewer::hasTemplate($template)) { - $css = array_merge($css, preg_split('/\r\n|\n|\r/', $this->renderWith($template))); + foreach (ClassTools::singleton()->getObjectAncestry($this, self::class) as $class) { + + $template = $this->getCustomCSSTemplate($class); + + if (SSViewer::hasTemplate($template)) { + $css = array_merge($css, preg_split('/\r\n|\n|\r/', $this->renderWith($template))); + } + } // Update CSS via Extensions: @@ -419,11 +423,13 @@ public function getCustomCSS() /** * Answers the name of a template used to render custom CSS for the receiver. * + * @param string $class + * * @return string */ - public function getCustomCSSTemplate() + public function getCustomCSSTemplate($class = null) { - return sprintf('%s\CustomCSS', static::class); + return sprintf('%s\CustomCSS', $class ? $class : static::class); } /** diff --git a/templates/SilverWare/Components/BaseListComponent.ss b/templates/SilverWare/Components/BaseListComponent.ss index ca106d3..7d49a25 100644 --- a/templates/SilverWare/Components/BaseListComponent.ss +++ b/templates/SilverWare/Components/BaseListComponent.ss @@ -1,4 +1,5 @@ <% if $ListItems %> + <% include SilverWare\Components\BaseListComponent\Alerts %>
<% loop $ListItems %> $renderListItem($First, $Middle, $Last) diff --git a/templates/SilverWare/Components/BaseListComponent/CustomCSS.ss b/templates/SilverWare/Components/BaseListComponent/CustomCSS.ss new file mode 100644 index 0000000..56e1f9c --- /dev/null +++ b/templates/SilverWare/Components/BaseListComponent/CustomCSS.ss @@ -0,0 +1,7 @@ +<% if $OverlayIconColor %> + +{$CSSID} .image-overlay > i { + color: $OverlayIconColor; +} + +<% end_if %> diff --git a/templates/SilverWare/Components/BaseListComponent/Includes/Alerts.ss b/templates/SilverWare/Components/BaseListComponent/Includes/Alerts.ss new file mode 100644 index 0000000..97341f1 --- /dev/null +++ b/templates/SilverWare/Components/BaseListComponent/Includes/Alerts.ss @@ -0,0 +1,7 @@ +<% if $ParentInstance.HasListAlerts %> +
+ <% loop $ParentInstance.ListAlertsData %> + <% include Alert Type=$Type, Icon=$Icon, Text=$Text.RAW %> + <% end_loop %> +
+<% end_if %> diff --git a/templates/SilverWare/Forms/ToggleGroup.ss b/templates/SilverWare/Forms/ToggleGroup.ss new file mode 100644 index 0000000..da923f6 --- /dev/null +++ b/templates/SilverWare/Forms/ToggleGroup.ss @@ -0,0 +1,6 @@ +
+ $ToggleField.FieldHolder +
+
+ <% include SilverStripe\Forms\CompositeField %> +
diff --git a/templates/SilverWare/Lists/ListItem/Includes/Details.ss b/templates/SilverWare/Lists/ListItem/Includes/Details.ss index 3a164e2..597a506 100644 --- a/templates/SilverWare/Lists/ListItem/Includes/Details.ss +++ b/templates/SilverWare/Lists/ListItem/Includes/Details.ss @@ -1,7 +1,7 @@ <% if $Renderer.isDetailsShown($isFirst, $isMiddle, $isLast) %>
<% loop $ListItemDetails %> - <% include Icon Name=$Icon, FixedWidth=1 %> $Text.RAW + <% if $Text %><% include Icon Name=$Icon, FixedWidth=1 %> $Text.RAW<% end_if %> <% end_loop %>
<% end_if %> diff --git a/templates/SilverWare/Lists/ListItem/Includes/Image.ss b/templates/SilverWare/Lists/ListItem/Includes/Image.ss index 0f05ab7..3605f45 100644 --- a/templates/SilverWare/Lists/ListItem/Includes/Image.ss +++ b/templates/SilverWare/Lists/ListItem/Includes/Image.ss @@ -4,6 +4,9 @@ <% with $getMetaImageResized($Renderer.ImageResizeWidth, $Renderer.ImageResizeHeight, $Renderer.ImageResizeMethod) %> $Title <% end_with %> + <% if $Renderer.OverlayImages %> +
$Renderer.OverlayIcon.Tag
+ <% end_if %> <% if $Renderer.LinkImages %><% end_if %>
<% end_if %> diff --git a/templates/SilverWare/Model/Slide.ss b/templates/SilverWare/Model/Slide.ss index 6bb0311..6d134bf 100644 --- a/templates/SilverWare/Model/Slide.ss +++ b/templates/SilverWare/Model/Slide.ss @@ -1,4 +1,4 @@ -
+<$Tag $getSlideAttributesHTML($isFirst, $isMiddle, $isLast)> <% if $LinkShown %><% end_if %> <% if $ImageShown %> $Title @@ -14,4 +14,4 @@
<% end_if %> <% if $LinkShown %><% end_if %> - +