From d42c8b528eb595101954f478e0024e3f079f6fbf Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 22 Mar 2017 19:19:26 +0100 Subject: first implementation of fun stats site --- .../assets/bootstrap-material-design/.bower.json | 40 +++ .../assets/bootstrap-material-design/.travis.yml | 29 ++ .../assets/bootstrap-material-design/LICENSE.md | 30 ++ .../assets/bootstrap-material-design/README.md | 6 + .../assets/bootstrap-material-design/bower.json | 29 ++ .../bootstrap-material-design/js/autofill.js | 109 +++++++ .../assets/bootstrap-material-design/js/base.js | 88 +++++ .../js/baseFormControl.js | 36 +++ .../bootstrap-material-design/js/baseInput.js | 321 +++++++++++++++++++ .../bootstrap-material-design/js/baseLayout.js | 122 +++++++ .../bootstrap-material-design/js/baseSelection.js | 93 ++++++ .../js/bootstrapMaterialDesign.js | 205 ++++++++++++ .../bootstrap-material-design/js/checkbox.js | 94 ++++++ .../bootstrap-material-design/js/checkboxInline.js | 89 ++++++ .../bootstrap-material-design/js/collapseInline.js | 113 +++++++ .../assets/bootstrap-material-design/js/drawer.js | 170 ++++++++++ .../assets/bootstrap-material-design/js/file.js | 139 ++++++++ .../assets/bootstrap-material-design/js/index.js | 32 ++ .../assets/bootstrap-material-design/js/radio.js | 95 ++++++ .../bootstrap-material-design/js/radioInline.js | 77 +++++ .../assets/bootstrap-material-design/js/ripples.js | 311 ++++++++++++++++++ .../assets/bootstrap-material-design/js/select.js | 94 ++++++ .../assets/bootstrap-material-design/js/switch.js | 72 +++++ .../assets/bootstrap-material-design/js/text.js | 89 ++++++ .../bootstrap-material-design/js/textarea.js | 89 ++++++ .../assets/bootstrap-material-design/js/util.js | 105 ++++++ .../assets/bootstrap-material-design/package.json | 60 ++++ .../bootstrap-material-design/scss/_alerts.scss | 4 + .../bootstrap-material-design/scss/_buttons.scss | 233 ++++++++++++++ .../bootstrap-material-design/scss/_cards.scss | 58 ++++ .../scss/_checkboxes.scss | 256 +++++++++++++++ .../scss/_core-bootstrap.scss | 68 ++++ .../bootstrap-material-design/scss/_core.scss | 33 ++ .../scss/_custom-forms.scss | 10 + .../bootstrap-material-design/scss/_drawer.scss | 122 +++++++ .../bootstrap-material-design/scss/_dropdown.scss | 126 ++++++++ .../scss/_extensions.scss | 3 + .../bootstrap-material-design/scss/_forms.scss | 221 +++++++++++++ .../scss/_input-group.scss | 39 +++ .../bootstrap-material-design/scss/_layout.scss | 80 +++++ .../scss/_list-group.scss | 100 ++++++ .../bootstrap-material-design/scss/_mixins.scss | 10 + .../bootstrap-material-design/scss/_modal.scss | 26 ++ .../bootstrap-material-design/scss/_nav.scss | 54 ++++ .../bootstrap-material-design/scss/_navbar.scss | 31 ++ .../scss/_pagination.scss | 52 +++ .../bootstrap-material-design/scss/_popover.scss | 19 ++ .../bootstrap-material-design/scss/_progress.scss | 11 + .../bootstrap-material-design/scss/_radios.scss | 119 +++++++ .../bootstrap-material-design/scss/_reboot.scss | 25 ++ .../bootstrap-material-design/scss/_ripples.scss | 40 +++ .../bootstrap-material-design/scss/_switches.scss | 83 +++++ .../bootstrap-material-design/scss/_tables.scss | 26 ++ .../bootstrap-material-design/scss/_themes.scss | 6 + .../bootstrap-material-design/scss/_type.scss | 6 + .../bootstrap-material-design/scss/_variables.scss | 139 ++++++++ .../scss/bootstrap-material-design.scss | 3 + .../scss/extensions/_selectize.scss | 91 ++++++ .../scss/extensions/_snackbarjs.scss | 27 ++ .../scss/mixins/_animations.scss | 21 ++ .../scss/mixins/_breakpoints.scss | 34 ++ .../scss/mixins/_buttons.scss | 218 +++++++++++++ .../scss/mixins/_drawer.scss | 237 ++++++++++++++ .../scss/mixins/_forms.scss | 283 ++++++++++++++++ .../scss/mixins/_hover.scss | 9 + .../scss/mixins/_layout.scss | 17 + .../scss/mixins/_navs.scss | 23 ++ .../scss/mixins/_type.scss | 11 + .../scss/mixins/_utilities.scss | 35 ++ .../scss/variables/_colors-map.scss | 311 ++++++++++++++++++ .../scss/variables/_colors.scss | 356 +++++++++++++++++++++ .../scss/variables/_drawer.scss | 5 + .../scss/variables/_layout.scss | 1 + .../scss/variables/_menu.scss | 18 ++ .../scss/variables/_shadow.scss | 35 ++ .../scss/variables/bootstrap/_body.scss | 6 + .../scss/variables/bootstrap/_brand.scss | 6 + .../scss/variables/bootstrap/_buttons.scss | 77 +++++ .../scss/variables/bootstrap/_card.scss | 13 + .../scss/variables/bootstrap/_code.scss | 12 + .../scss/variables/bootstrap/_components.scss | 16 + .../scss/variables/bootstrap/_custom-forms.scss | 5 + .../scss/variables/bootstrap/_dropdown.scss | 20 ++ .../scss/variables/bootstrap/_forms.scss | 47 +++ .../scss/variables/bootstrap/_list-group.scss | 21 ++ .../scss/variables/bootstrap/_modals.scss | 20 ++ .../scss/variables/bootstrap/_nav.scss | 62 ++++ .../scss/variables/bootstrap/_pagination.scss | 6 + .../scss/variables/bootstrap/_spacing.scss | 26 ++ .../scss/variables/bootstrap/_state.scss | 15 + .../scss/variables/bootstrap/_type.scss | 66 ++++ 91 files changed, 6890 insertions(+) create mode 100644 templates/assets/bootstrap-material-design/.bower.json create mode 100644 templates/assets/bootstrap-material-design/.travis.yml create mode 100644 templates/assets/bootstrap-material-design/LICENSE.md create mode 100644 templates/assets/bootstrap-material-design/README.md create mode 100644 templates/assets/bootstrap-material-design/bower.json create mode 100644 templates/assets/bootstrap-material-design/js/autofill.js create mode 100644 templates/assets/bootstrap-material-design/js/base.js create mode 100644 templates/assets/bootstrap-material-design/js/baseFormControl.js create mode 100644 templates/assets/bootstrap-material-design/js/baseInput.js create mode 100644 templates/assets/bootstrap-material-design/js/baseLayout.js create mode 100644 templates/assets/bootstrap-material-design/js/baseSelection.js create mode 100644 templates/assets/bootstrap-material-design/js/bootstrapMaterialDesign.js create mode 100644 templates/assets/bootstrap-material-design/js/checkbox.js create mode 100644 templates/assets/bootstrap-material-design/js/checkboxInline.js create mode 100644 templates/assets/bootstrap-material-design/js/collapseInline.js create mode 100644 templates/assets/bootstrap-material-design/js/drawer.js create mode 100644 templates/assets/bootstrap-material-design/js/file.js create mode 100644 templates/assets/bootstrap-material-design/js/index.js create mode 100644 templates/assets/bootstrap-material-design/js/radio.js create mode 100644 templates/assets/bootstrap-material-design/js/radioInline.js create mode 100644 templates/assets/bootstrap-material-design/js/ripples.js create mode 100644 templates/assets/bootstrap-material-design/js/select.js create mode 100644 templates/assets/bootstrap-material-design/js/switch.js create mode 100644 templates/assets/bootstrap-material-design/js/text.js create mode 100644 templates/assets/bootstrap-material-design/js/textarea.js create mode 100644 templates/assets/bootstrap-material-design/js/util.js create mode 100644 templates/assets/bootstrap-material-design/package.json create mode 100644 templates/assets/bootstrap-material-design/scss/_alerts.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_buttons.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_cards.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_checkboxes.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_core-bootstrap.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_core.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_custom-forms.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_drawer.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_dropdown.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_extensions.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_forms.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_input-group.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_layout.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_list-group.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_mixins.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_modal.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_nav.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_navbar.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_pagination.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_popover.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_progress.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_radios.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_reboot.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_ripples.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_switches.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_tables.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_themes.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_type.scss create mode 100644 templates/assets/bootstrap-material-design/scss/_variables.scss create mode 100644 templates/assets/bootstrap-material-design/scss/bootstrap-material-design.scss create mode 100644 templates/assets/bootstrap-material-design/scss/extensions/_selectize.scss create mode 100644 templates/assets/bootstrap-material-design/scss/extensions/_snackbarjs.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_animations.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_breakpoints.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_buttons.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_drawer.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_forms.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_hover.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_layout.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_navs.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_type.scss create mode 100644 templates/assets/bootstrap-material-design/scss/mixins/_utilities.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_colors-map.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_colors.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_drawer.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_layout.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_menu.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/_shadow.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_body.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_brand.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_buttons.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_card.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_code.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_components.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_custom-forms.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_dropdown.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_forms.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_list-group.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_modals.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_nav.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_pagination.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_spacing.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_state.scss create mode 100644 templates/assets/bootstrap-material-design/scss/variables/bootstrap/_type.scss (limited to 'templates/assets/bootstrap-material-design') diff --git a/templates/assets/bootstrap-material-design/.bower.json b/templates/assets/bootstrap-material-design/.bower.json new file mode 100644 index 0000000..cc4d06b --- /dev/null +++ b/templates/assets/bootstrap-material-design/.bower.json @@ -0,0 +1,40 @@ +{ + "name": "bootstrap-material-design", + "description": "Bootstrap Material Design 4", + "keywords": [ + "material", + "design", + "bootstrap", + "css", + "js", + "sass", + "mobile-first", + "responsive", + "front-end", + "framework", + "web" + ], + "homepage": "http://fezvrasta.github.io/bootstrap-material-design", + "license": "MIT", + "moduleType": "globals", + "main": [ + "scss/_core.scss", + "dist/bootstrap-material-design.iife.js" + ], + "dependencies": { + "jquery": "^2.2", + "tether": "^1.2", + "bootstrap": "v4-dev" + }, + "version": "4.0.2", + "_release": "4.0.2", + "_resolution": { + "type": "version", + "tag": "v4.0.2", + "commit": "ec3a7ffc23d1f18ac822442fe06d3688d29cbbea" + }, + "_source": "https://github.com/FezVrasta/bootstrap-material-design.git", + "_target": "v4.0.2", + "_originalSource": "bootstrap-material-design", + "_direct": true +} \ No newline at end of file diff --git a/templates/assets/bootstrap-material-design/.travis.yml b/templates/assets/bootstrap-material-design/.travis.yml new file mode 100644 index 0000000..34b0d78 --- /dev/null +++ b/templates/assets/bootstrap-material-design/.travis.yml @@ -0,0 +1,29 @@ +sudo: false +git: + depth: 10 + +# remove the dist branch and dist tags from travis builds +branches: + except: + - dist + - /^v(\d+\.)?(\d+\.)?(\*|\d+)$/ + +language: node_js +node_js: + - "5" # "node" (v6.x) yielded v8::ObjectTemplate::Set() with non-primitive values is deprecated + +# enable this once we have reliable builds +cache: + directories: + - node_modules + - vendor/bundle + +before_install: + - rvm install 2.2 + - rvm use 2.2 --fuzzy + - gem install scss-lint + +before_script: + - npm install -g gulp-cli + +script: gulp all diff --git a/templates/assets/bootstrap-material-design/LICENSE.md b/templates/assets/bootstrap-material-design/LICENSE.md new file mode 100644 index 0000000..4199bf6 --- /dev/null +++ b/templates/assets/bootstrap-material-design/LICENSE.md @@ -0,0 +1,30 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016, Federico Zivolo and contributors - https://github.com/FezVrasta/bootstrap-material-design + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## Acknowledgements: + +- Some original Bootstrap code and documentation http://getbootstrap.com +`Copyright (c) 2011-2015 Twitter, Inc` + +- Some original MDL code http://www.getmdl.io/ +`Copyright 2015 Google Inc. All Rights Reserved.` diff --git a/templates/assets/bootstrap-material-design/README.md b/templates/assets/bootstrap-material-design/README.md new file mode 100644 index 0000000..9fe60b2 --- /dev/null +++ b/templates/assets/bootstrap-material-design/README.md @@ -0,0 +1,6 @@ +# bootstrap-material-design + +[`v4.0.2`](../../releases/tag/v4.0.2) built from commit [`f2ac8b1`](../../commit/f2ac8b142aba7e0cda5c945b04649269d1ff3d5a) on branch `v4-dev`. See the [README](../..) for more details + +--- +Built and published by [gulp-pipeline](https://github.com/alienfast/gulp-pipeline) using [build-control](https://github.com/alienfast/build-control) diff --git a/templates/assets/bootstrap-material-design/bower.json b/templates/assets/bootstrap-material-design/bower.json new file mode 100644 index 0000000..a312e33 --- /dev/null +++ b/templates/assets/bootstrap-material-design/bower.json @@ -0,0 +1,29 @@ +{ + "name": "bootstrap-material-design", + "description": "Bootstrap Material Design 4", + "keywords": [ + "material", + "design", + "bootstrap", + "css", + "js", + "sass", + "mobile-first", + "responsive", + "front-end", + "framework", + "web" + ], + "homepage": "http://fezvrasta.github.io/bootstrap-material-design", + "license": "MIT", + "moduleType": "globals", + "main": [ + "scss/_core.scss", + "dist/bootstrap-material-design.iife.js" + ], + "dependencies": { + "jquery": "^2.2", + "tether": "^1.2", + "bootstrap": "v4-dev" + } +} diff --git a/templates/assets/bootstrap-material-design/js/autofill.js b/templates/assets/bootstrap-material-design/js/autofill.js new file mode 100644 index 0000000..2ada9ec --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/autofill.js @@ -0,0 +1,109 @@ +import Base from './base' + +const Autofill = (($) => { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + const NAME = 'autofill' + const DATA_KEY = `bmd.${NAME}` + const JQUERY_NAME = `bmd${NAME.charAt(0).toUpperCase() + NAME.slice(1)}` + const JQUERY_NO_CONFLICT = $.fn[JQUERY_NAME] + + const Default = {} + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class Autofill extends Base { + + constructor($element, config) { + super($element, $.extend(true, {}, Default, config)) + + this._watchLoading() + this._attachEventHandlers() + } + + dispose() { + super.dispose(DATA_KEY) + } + + // ------------------------------------------------------------------------ + // private + + _watchLoading() { + // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them + setTimeout(() => { + clearInterval(this._onLoading) + }, 10000) + } + + // This part of code will detect autofill when the page is loading (username and password inputs for example) + _onLoading() { + setInterval(() => { + $('input[type!=checkbox]').each((index, element) => { + let $element = $(element) + if ($element.val() && $element.val() !== $element.attr('value')) { + $element.trigger('change') + } + }) + }, 100) + } + + _attachEventHandlers() { + // Listen on inputs of the focused form + // (because user can select from the autofill dropdown only when the input has focus) + let focused = null + $(document) + .on('focus', 'input', (event) => { + let $inputs = $(event.currentTarget).closest('form').find('input').not('[type=file]') + focused = setInterval(() => { + $inputs.each((index, element) => { + let $element = $(element) + if ($element.val() !== $element.attr('value')) { + $element.trigger('change') + } + }) + }, 100) + }) + .on('blur', '.form-group input', () => { + clearInterval(focused) + }) + } + + // ------------------------------------------------------------------------ + // static + static _jQueryInterface(config) { + return this.each(function () { + let $element = $(this) + let data = $element.data(DATA_KEY) + + if (!data) { + data = new Autofill($element, config) + $element.data(DATA_KEY, data) + } + }) + } + } + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + $.fn[JQUERY_NAME] = Autofill._jQueryInterface + $.fn[JQUERY_NAME].Constructor = Autofill + $.fn[JQUERY_NAME].noConflict = () => { + $.fn[JQUERY_NAME] = JQUERY_NO_CONFLICT + return Autofill._jQueryInterface + } + + return Autofill + +})(jQuery) + +export default Autofill diff --git a/templates/assets/bootstrap-material-design/js/base.js b/templates/assets/bootstrap-material-design/js/base.js new file mode 100644 index 0000000..283b976 --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/base.js @@ -0,0 +1,88 @@ +import Util from './util' + +const Base = (($) => { + + const ClassName = { + BMD_FORM_GROUP: 'bmd-form-group', + IS_FILLED: 'is-filled', + IS_FOCUSED: 'is-focused' + } + + const Selector = { + BMD_FORM_GROUP: `.${ClassName.BMD_FORM_GROUP}` + } + + const Default = {} + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class Base { + + /** + * + * @param element + * @param config + * @param properties - anything that needs to be set as this[key] = value. Works around the need to call `super` before using `this` + */ + constructor($element, config, properties = {}) { + this.$element = $element + this.config = $.extend(true, {}, Default, config) + + // set properties for use in the constructor initialization + for (let key in properties) { + this[key] = properties[key] + } + } + + dispose(dataKey) { + this.$element.data(dataKey, null) + this.$element = null + this.config = null + } + + // ------------------------------------------------------------------------ + // protected + + addFormGroupFocus() { + if (!this.$element.prop('disabled')) { + this.$bmdFormGroup.addClass(ClassName.IS_FOCUSED) + } + } + + removeFormGroupFocus() { + this.$bmdFormGroup.removeClass(ClassName.IS_FOCUSED) + } + + removeIsFilled() { + this.$bmdFormGroup.removeClass(ClassName.IS_FILLED) + } + + addIsFilled() { + this.$bmdFormGroup.addClass(ClassName.IS_FILLED) + } + + // Find bmd-form-group + findMdbFormGroup(raiseError = true) { + let mfg = this.$element.closest(Selector.BMD_FORM_GROUP) + if (mfg.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.BMD_FORM_GROUP} for ${Util.describe(this.$element)}`) + } + return mfg + } + + // ------------------------------------------------------------------------ + // private + + // ------------------------------------------------------------------------ + // static + + } + + return Base + +})(jQuery) + +export default Base diff --git a/templates/assets/bootstrap-material-design/js/baseFormControl.js b/templates/assets/bootstrap-material-design/js/baseFormControl.js new file mode 100644 index 0000000..8481070 --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/baseFormControl.js @@ -0,0 +1,36 @@ +import BaseInput from './baseInput' + +const BaseFormControl = (($) => { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + const Default = { + requiredClasses: ['form-control'] + } + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class BaseFormControl extends BaseInput { + + constructor($element, config) { + super($element, $.extend(true, Default, config)) + + // Initially mark as empty + if (this.isEmpty()) { + this.removeIsFilled() + } + } + } + + + return BaseFormControl + +})(jQuery) + +export default BaseFormControl diff --git a/templates/assets/bootstrap-material-design/js/baseInput.js b/templates/assets/bootstrap-material-design/js/baseInput.js new file mode 100644 index 0000000..5396ccb --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/baseInput.js @@ -0,0 +1,321 @@ +import Base from './base' +import Util from './util' + +const BaseInput = (($) => { + + const ClassName = { + FORM_GROUP: 'form-group', + BMD_FORM_GROUP: 'bmd-form-group', + BMD_LABEL: 'bmd-label', + BMD_LABEL_STATIC: 'bmd-label-static', + BMD_LABEL_PLACEHOLDER: 'bmd-label-placeholder', + BMD_LABEL_FLOATING: 'bmd-label-floating', + HAS_DANGER: 'has-danger', + IS_FILLED: 'is-filled', + IS_FOCUSED: 'is-focused', + INPUT_GROUP: 'input-group' + } + + const Selector = { + FORM_GROUP: `.${ClassName.FORM_GROUP}`, + BMD_FORM_GROUP: `.${ClassName.BMD_FORM_GROUP}`, + BMD_LABEL_WILDCARD: `label[class^='${ClassName.BMD_LABEL}'], label[class*=' ${ClassName.BMD_LABEL}']` // match any label variant if specified + } + + const Default = { + validate: false, + formGroup: { + required: false + }, + bmdFormGroup: { + template: ``, + create: true, // create a wrapper if form-group not found + required: true // not recommended to turn this off, only used for inline components + }, + label: { + required: false, + + // Prioritized find order for resolving the label to be used as an bmd-label if not specified in the markup + // - a function(thisComponent); or + // - a string selector used like $bmdFormGroup.find(selector) + // + // Note this only runs if $bmdFormGroup.find(Selector.BMD_LABEL_WILDCARD) fails to find a label (as authored in the markup) + // + selectors: [ + `.form-control-label`, // in the case of horizontal or inline forms, this will be marked + `> label` // usual case for text inputs, first child. Deeper would find toggle labels so don't do that. + ], + className: ClassName.BMD_LABEL_STATIC + }, + requiredClasses: [], + invalidComponentMatches: [], + convertInputSizeVariations: true + } + + const FormControlSizeMarkers = { + 'form-control-lg': 'bmd-form-group-lg', + 'form-control-sm': 'bmd-form-group-sm' + } + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class BaseInput extends Base { + + /** + * + * @param element + * @param config + * @param properties - anything that needs to be set as this[key] = value. Works around the need to call `super` before using `this` + */ + constructor($element, config, properties = {}) { + super($element, $.extend(true, {}, Default, config), properties) + + // Enforce no overlap between components to prevent side effects + this._rejectInvalidComponentMatches() + + // Enforce expected structure (if any) + this.rejectWithoutRequiredStructure() + + // Enforce required classes for a consistent rendering + this._rejectWithoutRequiredClasses() + + // Resolve the form-group first, it will be used for bmd-form-group if possible + // note: different components have different rules + this.$formGroup = this.findFormGroup(this.config.formGroup.required) + + // Will add bmd-form-group to form-group or create an bmd-form-group + // Performance Note: for those forms that are really performance driven, create the markup with the .bmd-form-group to avoid + // rendering changes once added. + this.$bmdFormGroup = this.resolveMdbFormGroup() + + // Resolve and mark the bmdLabel if necessary as defined by the config + this.$bmdLabel = this.resolveMdbLabel() + + // Signal to the bmd-form-group that a form-control-* variation is being used + this.resolveMdbFormGroupSizing() + + this.addFocusListener() + this.addChangeListener() + + if(this.$element.val() != ''){ + this.addIsFilled() + } + } + + dispose(dataKey) { + super.dispose(dataKey) + this.$bmdFormGroup = null + this.$formGroup = null + } + + // ------------------------------------------------------------------------ + // protected + + rejectWithoutRequiredStructure() { + // implement + } + + addFocusListener() { + this.$element + .on('focus', () => { + this.addFormGroupFocus() + }) + .on('blur', () => { + this.removeFormGroupFocus() + }) + } + + addChangeListener() { + this.$element + .on('keydown paste', (event) => { + if (Util.isChar(event)) { + this.addIsFilled() + } + }) + .on('keyup change', () => { + + // make sure empty is added back when there is a programmatic value change. + // NOTE: programmatic changing of value using $.val() must trigger the change event i.e. $.val('x').trigger('change') + if (this.isEmpty()) { + this.removeIsFilled() + } else { + this.addIsFilled() + } + + if (this.config.validate) { + // Validation events do not bubble, so they must be attached directly to the text: http://jsfiddle.net/PEpRM/1/ + // Further, even the bind method is being caught, but since we are already calling #checkValidity here, just alter + // the form-group on change. + // + // NOTE: I'm not sure we should be intervening regarding validation, this seems better as a README and snippet of code. + // BUT, I've left it here for backwards compatibility. + let isValid = (typeof this.$element[0].checkValidity === 'undefined' || this.$element[0].checkValidity()) + if (isValid) { + this.removeHasDanger() + } else { + this.addHasDanger() + } + } + }) + } + + addHasDanger() { + this.$bmdFormGroup.addClass(ClassName.HAS_DANGER) + } + + removeHasDanger() { + this.$bmdFormGroup.removeClass(ClassName.HAS_DANGER) + } + + isEmpty() { + return (this.$element.val() === null || this.$element.val() === undefined || this.$element.val() === '') + } + + // Will add bmd-form-group to form-group or create a bmd-form-group if necessary + resolveMdbFormGroup() { + let mfg = this.findMdbFormGroup(false) + if (mfg === undefined || mfg.length === 0) { + if (this.config.bmdFormGroup.create && (this.$formGroup === undefined || this.$formGroup.length === 0)) { + // If a form-group doesn't exist (not recommended), take a guess and wrap the element (assuming no label). + // note: it's possible to make this smarter, but I need to see valid cases before adding any complexity. + + // this may be an input-group, wrap that instead + if(this.outerElement().parent().hasClass(ClassName.INPUT_GROUP)){ + this.outerElement().parent().wrap(this.config.bmdFormGroup.template) + } + else{ + this.outerElement().wrap(this.config.bmdFormGroup.template) + } + } else { + // a form-group does exist, add our marker class to it + this.$formGroup.addClass(ClassName.BMD_FORM_GROUP) + + // OLD: may want to implement this after all, see how the styling turns out, but using an existing form-group is less manipulation of the dom and therefore preferable + // A form-group does exist, so add an bmd-form-group wrapping it's internal contents + //fg.wrapInner(this.config.bmdFormGroup.template) + } + + mfg = this.findMdbFormGroup(this.config.bmdFormGroup.required) + } + + return mfg + } + + // Demarcation element (e.g. first child of a form-group) + // Subclasses such as file inputs may have different structures + outerElement() { + return this.$element + } + + // Will add bmd-label to bmd-form-group if not already specified + resolveMdbLabel() { + + let label = this.$bmdFormGroup.find(Selector.BMD_LABEL_WILDCARD) + if (label === undefined || label.length === 0) { + // we need to find it based on the configured selectors + label = this.findMdbLabel(this.config.label.required) + + if (label === undefined || label.length === 0) { + // no label found, and finder did not require one + } else { + // a candidate label was found, add the configured default class name + label.addClass(this.config.label.className) + } + } + + return label + } + + // Find bmd-label variant based on the config selectors + findMdbLabel(raiseError = true) { + let label = null + + // use the specified selector order + for (let selector of this.config.label.selectors) { + if ($.isFunction(selector)) { + label = selector(this) + } else { + label = this.$bmdFormGroup.find(selector) + } + + if (label !== undefined && label.length > 0) { + break + } + } + + if (label.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.BMD_LABEL_WILDCARD} within form-group for ${Util.describe(this.$element)}`) + } + return label + } + + // Find bmd-form-group + findFormGroup(raiseError = true) { + let fg = this.$element.closest(Selector.FORM_GROUP) + if (fg.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.FORM_GROUP} for ${Util.describe(this.$element)}`) + } + return fg + } + + // Due to the interconnected nature of labels/inputs/help-blocks, signal the bmd-form-group-* size variation based on + // a found form-control-* size + resolveMdbFormGroupSizing() { + if (!this.config.convertInputSizeVariations) { + return + } + + // Modification - Change text-sm/lg to form-group-sm/lg instead (preferred standard and simpler css/less variants) + for (let inputSize in FormControlSizeMarkers) { + if (this.$element.hasClass(inputSize)) { + //this.$element.removeClass(inputSize) + this.$bmdFormGroup.addClass(FormControlSizeMarkers[inputSize]) + } + } + } + + // ------------------------------------------------------------------------ + // private + _rejectInvalidComponentMatches() { + for (let otherComponent of this.config.invalidComponentMatches) { + otherComponent.rejectMatch(this.constructor.name, this.$element) + } + } + + _rejectWithoutRequiredClasses() { + for (let requiredClass of this.config.requiredClasses) { + + let found = false + // allow one of several classes to be passed in x||y + if (requiredClass.indexOf('||') !== -1) { + let oneOf = requiredClass.split('||') + for (let requiredClass of oneOf) { + if (this.$element.hasClass(requiredClass)) { + found = true + break + } + } + } else if (this.$element.hasClass(requiredClass)) { + found = true + } + + // error if not found + if (!found) { + $.error(`${this.constructor.name} element: ${Util.describe(this.$element)} requires class: ${requiredClass}`) + } + } + } + + // ------------------------------------------------------------------------ + // static + + } + + return BaseInput + +})(jQuery) + +export default BaseInput diff --git a/templates/assets/bootstrap-material-design/js/baseLayout.js b/templates/assets/bootstrap-material-design/js/baseLayout.js new file mode 100644 index 0000000..8dc87ed --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/baseLayout.js @@ -0,0 +1,122 @@ +import Base from './base' +import Util from './util' + +const BaseLayout = (($) => { + + const ClassName = { + CANVAS: 'bmd-layout-canvas', + CONTAINER: 'bmd-layout-container', + BACKDROP: `bmd-layout-backdrop` + } + + const Selector = { + CANVAS: `.${ClassName.CANVAS}`, + CONTAINER: `.${ClassName.CONTAINER}`, + BACKDROP: `.${ClassName.BACKDROP}` + } + + const Default = { + canvas: { + create: true, + required: true, + template: `
` + }, + backdrop: { + create: true, + required: true, + template: `
` + } + } + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class BaseLayout extends Base { + + constructor($element, config, properties = {}) { + super($element, $.extend(true, {}, Default, config), properties) + + this.$container = this.findContainer(true) + this.$backdrop = this.resolveBackdrop() + this.resolveCanvas(); + } + + dispose(dataKey) { + super.dispose(dataKey) + this.$container = null + this.$backdrop = null + } + + // ------------------------------------------------------------------------ + // protected + + // Will wrap container in bmd-layout-canvas if necessary + resolveCanvas() { + let bd = this.findCanvas(false) + if (bd === undefined || bd.length === 0) { + if (this.config.canvas.create) { + this.$container.wrap(this.config.canvas.template) + } + + bd = this.findCanvas(this.config.canvas.required) + } + + return bd + } + + // Find closest bmd-layout-container based on the given context + findCanvas(raiseError = true, context = this.$container) { + let canvas = context.closest(Selector.CANVAS) + if (canvas.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.CANVAS} for ${Util.describe(context)}`) + } + return canvas + } + + // Will add bmd-layout-backdrop to bmd-layout-container if necessary + resolveBackdrop() { + let bd = this.findBackdrop(false) + if (bd === undefined || bd.length === 0) { + if (this.config.backdrop.create) { + this.$container.append(this.config.backdrop.template) + } + + bd = this.findBackdrop(this.config.backdrop.required) + } + + return bd + } + + // Find closest bmd-layout-container based on the given context + findBackdrop(raiseError = true, context = this.$container) { + let backdrop = context.find(`> ${Selector.BACKDROP}`) + if (backdrop.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.BACKDROP} for ${Util.describe(context)}`) + } + return backdrop + } + + // Find closest bmd-layout-container based on the given context + findContainer(raiseError = true, context = this.$element) { + let container = context.closest(Selector.CONTAINER) + if (container.length === 0 && raiseError) { + $.error(`Failed to find ${Selector.CONTAINER} for ${Util.describe(context)}`) + } + return container + } + + // ------------------------------------------------------------------------ + // private + + // ------------------------------------------------------------------------ + // static + + } + + return BaseLayout + +})(jQuery) + +export default BaseLayout diff --git a/templates/assets/bootstrap-material-design/js/baseSelection.js b/templates/assets/bootstrap-material-design/js/baseSelection.js new file mode 100644 index 0000000..765d1c3 --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/baseSelection.js @@ -0,0 +1,93 @@ +import BaseInput from './baseInput' +import Util from './util' + +const BaseSelection = (($) => { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + const Default = { + label: { + required: false + + // Prioritized find order for resolving the label to be used as an bmd-label if not specified in the markup + // - a function(thisComponent); or + // - a string selector used like $bmdFormGroup.find(selector) + // + // Note this only runs if $bmdFormGroup.find(Selector.BMD_LABEL_WILDCARD) fails to find a label (as authored in the markup) + // + //selectors: [ + // `.form-control-label`, // in the case of horizontal or inline forms, this will be marked + // `> label` // usual case for text inputs + //] + } + } + + const Selector = { + LABEL: 'label' + } + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class BaseSelection extends BaseInput { + + constructor($element, config, properties) { + // properties = {inputType: checkbox, outerClass: checkbox-inline} + // '.checkbox|switch|radio > label > input[type=checkbox|radio]' + // '.${this.outerClass} > label > input[type=${this.inputType}]' + + super($element, $.extend(true, {}, Default, config), properties) + this.decorateMarkup() + } + + // ------------------------------------------------------------------------ + // protected + + decorateMarkup() { + this.$element.after(this.config.template) + } + + // Demarcation element (e.g. first child of a form-group) + outerElement() { + // .checkbox|switch|radio > label > input[type=checkbox|radio] + // label.checkbox-inline > input[type=checkbox|radio] + // .${this.outerClass} > label > input[type=${this.inputType}] + return this.$element.parent().closest(`.${this.outerClass}`) + } + + rejectWithoutRequiredStructure() { + // '.checkbox|switch|radio > label > input[type=checkbox|radio]' + // '.${this.outerClass} > label > input[type=${this.inputType}]' + Util.assert(this.$element, !this.$element.parent().prop('tagName') === 'label', `${this.constructor.name}'s ${Util.describe(this.$element)} parent element should be