From 323cc9402c3f225d968a7cbf72d728656ca60068 Mon Sep 17 00:00:00 2001 From: Artem Mezin Date: Sun, 29 May 2016 21:12:56 +0300 Subject: [PATCH 1/7] import from plunkr --- Dropdown.js | 85 ------------------------------------------- form.js | 71 ++++++++++++++++++++++++++++++++++++ index.html | 71 ++++++++++++++++++++++++------------ libs/css/pure-min.css | 11 ++++++ main.js | 66 ++++++++++++++++++++++++++++++--- menu.js | 66 +++++++++++++++++++++++++++++++++ model.js | 77 +++++++++++++++++++++++++++++++++++++++ style.css | 63 ++++++++++++++------------------ 8 files changed, 360 insertions(+), 150 deletions(-) delete mode 100644 Dropdown.js create mode 100644 form.js create mode 100644 libs/css/pure-min.css create mode 100644 menu.js create mode 100644 model.js diff --git a/Dropdown.js b/Dropdown.js deleted file mode 100644 index 9f46766..0000000 --- a/Dropdown.js +++ /dev/null @@ -1,85 +0,0 @@ -(function () { - 'use strict'; - - class Dropdown { - constructor (options) { - this.el = options.el; - - this._itemSelectCallbacks = []; - this._initEvents(); - } - - /** - * Add classname dropdown_open to element - */ - open () { - this.el.classList.add('dropdown_open'); - } - - /** - * Remove classname dropdown_open to element - */ - close () { - this.el.classList.remove('dropdown_open'); - } - - /** - * Open or close? - */ - toggle () { - if (this.isOpen()) { - this.close(); - } else { - this.open(); - } - } - - /** - * Set callback on user select event - * @param {Function} callback - */ - onSelect (callback) { - this._itemSelectCallbacks.push(callback); - } - - isOpen () { - return this.el.classList.contains('dropdown_open'); - } - - _initEvents () { - this.el.addEventListener('click', this._onClick.bind(this)); - } - - _onClick (event) { - if (event.target.classList.contains('dropdown__item')) { - event.preventDefault(); - this._onItemClick(event); - } else { - this.toggle(); - } - } - - _onItemClick (event) { - var itemHtml = event.target.innerHTML; - this.el.querySelector('.js-title').innerHTML = itemHtml; - - this._itemSelectCallbacks.forEach(callback => { - callback({ - el: this.el, - item: this, - text: itemHtml - }); - }); - - this.close(); - } - - - - //TODO: method addItem - } - - //EXPORT - window.Dropdown = Dropdown; - -})(); \ No newline at end of file diff --git a/form.js b/form.js new file mode 100644 index 0000000..2bab171 --- /dev/null +++ b/form.js @@ -0,0 +1,71 @@ +'use strict'; + +class Form { + constructor(opts) { + this.__templateSrc = document.querySelector(opts.tmpl).innerHTML; + this._template = Handlebars.compile(this.__templateSrc); + + this.el = document.createElement('div'); + + this.setData(opts.data); + this._initEvents(); + } + + render() { + this.el.innerHTML = this._template(this.data); + + this.formEl = this.el.querySelector('.js-form'); + this.btnEl = this.el.querySelector('.js-button'); + } + + setData(data) { + this.data = data; + } + + toggle() { + this.formEl.classList.toggle('hidden'); + this.btnEl.classList.toggle('hidden'); + } + + getField(name) { + return this.el.querySelector(`[name="${name}"]`); + } + + trigger(name, data) { + let widgetEvent = new CustomEvent(name, { + bubbles: true, + detail: data + }); + + this.el.dispatchEvent(widgetEvent); + } + + _initEvents() { + this.el.addEventListener('click', this._onClick.bind(this)); + this.el.addEventListener('submit', this._onSubmit.bind(this)); + } + + _onClick(event) { + let item = event.target; + + switch (item.dataset.action) { + case 'show': + this.toggle(); + break; + } + } + + _onSubmit(event) { + event.preventDefault(); + + this.trigger('add', { + href: this.getField('href').value, + anchor: this.getField('anchor').value + }); + + this.toggle(); + event.target.reset(); + } + + +} diff --git a/index.html b/index.html index 2792f09..4f82ef6 100644 --- a/index.html +++ b/index.html @@ -1,24 +1,49 @@ - - - My first menu - - - - - - - - - - \ No newline at end of file + + + + + + + + + + +
+
+ + + + + + + + + + + + + + diff --git a/libs/css/pure-min.css b/libs/css/pure-min.css new file mode 100644 index 0000000..016c54b --- /dev/null +++ b/libs/css/pure-min.css @@ -0,0 +1,11 @@ +/*! +Pure v0.6.0 +Copyright 2014 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +https://github.com/yahoo/pure/blob/master/LICENSE.md +*/ +/*! +normalize.css v^3.0 | MIT License | git.io/normalize +Copyright (c) Nicolas Gallagher and Jonathan Neal +*/ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.hidden,[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap;-ms-align-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset;border-color:#000\9}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin solid #129FEA;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked input[type=file],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input,.pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus,.pure-form .pure-group textarea:focus{z-index:3}.pure-form .pure-group input:first-child,.pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}.pure-form .pure-group input:first-child:last-child,.pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}.pure-form .pure-group input:last-child,.pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-menu-fixed{position:fixed;left:0;top:0;z-index:3}.pure-menu-list,.pure-menu-item{position:relative}.pure-menu-list{list-style:none;margin:0;padding:0}.pure-menu-item{padding:0;margin:0;height:100%}.pure-menu-link,.pure-menu-heading{display:block;text-decoration:none;white-space:nowrap}.pure-menu-horizontal{width:100%;white-space:nowrap}.pure-menu-horizontal .pure-menu-list{display:inline-block}.pure-menu-horizontal .pure-menu-item,.pure-menu-horizontal .pure-menu-heading,.pure-menu-horizontal .pure-menu-separator{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-item .pure-menu-item{display:block}.pure-menu-children{display:none;position:absolute;left:100%;top:0;margin:0;padding:0;z-index:3}.pure-menu-horizontal .pure-menu-children{left:0;top:auto;width:inherit}.pure-menu-allow-hover:hover>.pure-menu-children,.pure-menu-active>.pure-menu-children{display:block;position:absolute}.pure-menu-has-children>.pure-menu-link:after{padding-left:.5em;content:"\25B8";font-size:small}.pure-menu-horizontal .pure-menu-has-children>.pure-menu-link:after{content:"\25BE"}.pure-menu-scrollable{overflow-y:scroll;overflow-x:hidden}.pure-menu-scrollable .pure-menu-list{display:block}.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list{display:inline-block}.pure-menu-horizontal.pure-menu-scrollable{white-space:nowrap;overflow-y:hidden;overflow-x:auto;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;padding:.5em 0}.pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar{display:none}.pure-menu-separator{background-color:#ccc;height:1px;margin:.3em 0}.pure-menu-horizontal .pure-menu-separator{width:1px;height:1.3em;margin:0 .3em}.pure-menu-heading{text-transform:uppercase;color:#565d64}.pure-menu-link{color:#777}.pure-menu-children{background-color:#fff}.pure-menu-link,.pure-menu-disabled,.pure-menu-heading{padding:.5em 1em}.pure-menu-disabled{opacity:.5}.pure-menu-disabled .pure-menu-link:hover{background-color:transparent}.pure-menu-active>.pure-menu-link,.pure-menu-link:hover,.pure-menu-link:focus{background-color:#eee}.pure-menu-selected .pure-menu-link,.pure-menu-selected .pure-menu-link:visited{color:#000}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background-color:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child>td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child>td{border-bottom-width:0} diff --git a/main.js b/main.js index 8f771c9..8450131 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,61 @@ -(function () { - //Use our component - window.menu = new Dropdown({ - el: document.querySelector('.js-dropdown') - }); +"use strict"; -})(); \ No newline at end of file +const APP_EL = document.querySelector('.app'), + DATA_KEY = '-KIIIl-A1w7peqCRVZ0R'; + +let menu = new Menu({ + tmpl: '#menu' +}); + +let form = new Form({ + tmpl: '#form' +}); + +let model = new Model({ + resource: 'menu', + key: DATA_KEY +}); + +form.render(); + +APP_EL.appendChild(menu.el); +APP_EL.appendChild(form.el); + +form.el.addEventListener('add', event => { + let data = model.getData(); + data.items.push(event.detail); + model.save(() => { + menu.setData(model.getData()); + menu.render(); + }); +}); + +menu.el.addEventListener('remove', event => { + //TODO: seems like part of model + let data = model.getData(); + data.items.splice(event.detail.index, 1); + model.setData(data); + + model.save(() => { + menu.setData(model.getData()); + menu.render(); + }); +}); + +//TODO: create smth smarter +menu.el.addEventListener('pick', event => { + let faviconer = document.querySelector('.faviconer'), + img = document.createElement('img'); + + img.onload = () => { + faviconer.appendChild(img); + } + img.src = `${event.detail.href}/favicon.ico`; +}); + + +// Load data +model.fetch(() => { + menu.setData(model.getData()); + menu.render(); +}); diff --git a/menu.js b/menu.js new file mode 100644 index 0000000..d2475ad --- /dev/null +++ b/menu.js @@ -0,0 +1,66 @@ +'use strict'; + +class Menu { + constructor(opts) { + this.__templateSrc = document.querySelector(opts.tmpl).innerHTML; + this._template = Handlebars.compile(this.__templateSrc); + + this.el = document.createElement('div'); + + this.setData(opts.data || {title: '', items: []}); + this._initEvents(); + } + + render() { + this.el.innerHTML = this._template(this.data); + } + + setData(data) { + this.data = data; + } + + removeItem(item) { + let index = parseInt(item.parentNode.dataset.index, 10); + + this.trigger('remove', { + index + }); + } + + pickItem(item) { + this.trigger('pick', { + href: item.getAttribute('href'), + anchor: item.textContent + }); + } + + trigger(name, data) { + let widgetEvent = new CustomEvent(name, { + bubbles: true, + detail: data + }); + + this.el.dispatchEvent(widgetEvent); + } + + _initEvents() { + this.el.addEventListener('click', this._onClick.bind(this)); + } + + _onClick(event) { + event.preventDefault(); + let item = event.target; + + switch (item.dataset.action) { + case 'remove': + this.removeItem(item); + break; + + case 'pick': + this.pickItem(item); + break; + } + } + + +} diff --git a/model.js b/model.js new file mode 100644 index 0000000..019c3b1 --- /dev/null +++ b/model.js @@ -0,0 +1,77 @@ +"use strict"; + +(function() { + const XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest; + const HOST = '//javascriptru.firebaseio.com'; + + class Model { + constructor(opts, data) { + this._resource = opts.resource; + this._key = opts.key; + + this.setData(data) + } + + setData(data) { + this.data = data; + } + + getData() { + return this.data; + } + + setKey(key) { + alert('New key set: ' + key); + this._key = key; + } + + fetch(done, fail) { + this._request('GET', null, (xhr) => { + this.setData(JSON.parse(xhr.responseText)); + done && done(this, xhr); + }, fail); + } + + save(done, fail) { + let method = this._key ? 'PUT' : 'POST'; + + this._request(method, this.data, (xhr) => { + if (method === 'POST') { + this.setKey(JSON.parse(xhr.responseText).name); + } else if (method === 'PUT') { + this.setData(JSON.parse(xhr.responseText)); + } + + done && done(this, xhr, method); + }, fail); + } + + _getUrl() { + let url = `${HOST}/${this._resource}`; + + if (this._key) { + url += `/${this._key}`; + } + + return `${url}.json`; + } + + _request(method, data, callback, errback) { + let xhr = new XHR(), + model = this; + + xhr.open(method, this._getUrl(), true); + xhr.onload = function (event) { + callback.call(this, this, event, model); + }; + xhr.onerror = function (event) { + //TODO: Do smth on errors + }; + + xhr.send(JSON.stringify(data || {})); + } + } + + //export + window.Model = Model; +})(); diff --git a/style.css b/style.css index bdf31fa..69005e4 100644 --- a/style.css +++ b/style.css @@ -1,45 +1,36 @@ -.dropdown { - --fz: 40px; - --width: 10em; -} +/* Styles go here */ -.dropdown, .dropdown__list { - margin: 0; /* resets the entire list's margin to 0 */ - padding: 0; /* resets the entire list's padding to 0 */ +.close { + position: absolute; + right: 32px; + top: 0; + width: 32px; + height: 32px; + opacity: 0.3; + cursor: pointer; } - -.dropdown__list { - display: none; /* hides the nested list by default */ - margin: 3px 0 -3px 0; /* repositions the nested list */ +.close:hover { + opacity: 1; } - -.dropdown_open .dropdown__list { - display: block; +.close:before, .close:after { + position: absolute; + left: 15px; + content: ' '; + height: 33px; + width: 2px; + background-color: #333; } - -.dropdown__title { - cursor: pointer; +.close:before { + transform: rotate(45deg); } - - -.dropdown { - border: 0.05em solid #d7d7d7; /* sets a border around the unordered list */ - width: var(--width); - font-size: var(--fz); +.close:after { + transform: rotate(-45deg); } - -ul.dropdown li{ - background-color: #e7e7e7; /* sets the list's default background color */ - list-style-type: none; /* removes the list's bullets */ - padding-bottom: 3px; /* expands all lists bottom area (padding) with 3 pixels */ +.pure-menu-item .close { + display: none; } -ul.dropdown li:hover { - background-color: #e1e1e1; /* sets the background color on hover */ -} -ul.dropdown li a { - color: #444; /* sets all links color */ - text-decoration: none; /* removes the link's default decoration (underline) */ - padding-left: 0.5em; /* adds padding to the left at all links */ - padding-bottom: 0.4em; /* adds padding to the bottom at all links */ + +.pure-menu-item:hover .close { + display: block; } From 53262cd4fc384e1c1f62eec4df67b15dafd051d6 Mon Sep 17 00:00:00 2001 From: Artem Mezin Date: Sun, 29 May 2016 21:51:20 +0300 Subject: [PATCH 2/7] Benchmark handlebars --- form.js | 2 ++ menu.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/form.js b/form.js index 2bab171..485b4da 100644 --- a/form.js +++ b/form.js @@ -3,7 +3,9 @@ class Form { constructor(opts) { this.__templateSrc = document.querySelector(opts.tmpl).innerHTML; + console.time('Handlebars compile form'); this._template = Handlebars.compile(this.__templateSrc); + console.timeEnd('Handlebars compile form'); this.el = document.createElement('div'); diff --git a/menu.js b/menu.js index d2475ad..b6af63e 100644 --- a/menu.js +++ b/menu.js @@ -3,7 +3,9 @@ class Menu { constructor(opts) { this.__templateSrc = document.querySelector(opts.tmpl).innerHTML; + console.time('Handlebars compile menu'); this._template = Handlebars.compile(this.__templateSrc); + console.timeEnd('Handlebars compile menu'); this.el = document.createElement('div'); From 3ecd6a4406fa31ce3aa10bef50616ab09630f748 Mon Sep 17 00:00:00 2001 From: Artem Mezin Date: Sun, 29 May 2016 23:32:08 +0300 Subject: [PATCH 3/7] webpack --- .gitignore | 1 + bundle.js | 812 ++++++++++++++++++++++++++++++++++++++++++++++ form.js | 2 +- index.html | 9 +- main.js | 7 + menu.js | 2 +- model.js | 7 +- package.json | 31 ++ webpack.config.js | 22 ++ 9 files changed, 881 insertions(+), 12 deletions(-) create mode 100644 .gitignore create mode 100644 bundle.js create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/bundle.js b/bundle.js new file mode 100644 index 0000000..3179ba6 --- /dev/null +++ b/bundle.js @@ -0,0 +1,812 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + __webpack_require__(1); + + __webpack_require__(5); + + var _model = __webpack_require__(7); + + var _model2 = _interopRequireDefault(_model); + + var _form = __webpack_require__(8); + + var _form2 = _interopRequireDefault(_form); + + var _menu = __webpack_require__(9); + + var _menu2 = _interopRequireDefault(_menu); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var APP_EL = document.querySelector('.app'), + DATA_KEY = '-KIIIl-A1w7peqCRVZ0R'; + + var menu = new _menu2.default({ + tmpl: '#menu' + }); + + var form = new _form2.default({ + tmpl: '#form' + }); + + var model = new _model2.default({ + resource: 'menu', + key: DATA_KEY + }); + + form.render(); + + APP_EL.appendChild(menu.el); + APP_EL.appendChild(form.el); + + form.el.addEventListener('add', function (event) { + var data = model.getData(); + data.items.push(event.detail); + model.save(function () { + menu.setData(model.getData()); + menu.render(); + }); + }); + + menu.el.addEventListener('remove', function (event) { + //TODO: seems like part of model + var data = model.getData(); + data.items.splice(event.detail.index, 1); + model.setData(data); + + model.save(function () { + menu.setData(model.getData()); + menu.render(); + }); + }); + + //TODO: create smth smarter + menu.el.addEventListener('pick', function (event) { + var faviconer = document.querySelector('.faviconer'), + img = document.createElement('img'); + + img.onload = function () { + faviconer.appendChild(img); + }; + img.src = event.detail.href + '/favicon.ico'; + }); + + // Load data + model.fetch(function () { + menu.setData(model.getData()); + menu.render(); + }); + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + // style-loader: Adds some css to the DOM by adding a