From 6e8c6079c4891ae9ed56e9a9f4ad223665148088 Mon Sep 17 00:00:00 2001 From: Asaf Shakarchi Date: Sun, 3 Aug 2014 17:15:40 +0300 Subject: [PATCH] Version 0.2.0 release. --- bower.json | 2 +- dist/amd/accordion/accordion-item.js | 6 +- dist/amd/list/list.js | 44 +- dist/amd/main.js | 78 +- dist/amd/tree/node.js | 26 +- dist/amd/tree/tree-branch-tmpl.js | 2 +- dist/amd/tree/tree-branch.js | 13 +- dist/amd/tree/tree-node-tmpl.js | 2 +- dist/amd/tree/tree-node.js | 81 +- dist/cjs/accordion/accordion-item.js | 6 +- dist/cjs/list/list.js | 44 +- dist/cjs/main.js | 58 +- dist/cjs/tree/node.js | 28 +- dist/cjs/tree/tree-branch-tmpl.js | 2 +- dist/cjs/tree/tree-branch.js | 13 +- dist/cjs/tree/tree-node-tmpl.js | 2 +- dist/cjs/tree/tree-node.js | 81 +- dist/globals/main.js | 1458 +++++++++++++++++++++---- dist/named-amd/main.js | 1480 ++++++++++++++++++++++---- package.json | 2 +- 20 files changed, 2834 insertions(+), 594 deletions(-) diff --git a/bower.json b/bower.json index e0c6f04..84400d7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ember-components", - "version": "0.1.0", + "version": "0.2.0", "description": "A suite of components for Ember.js", "homepage": "http://ember-addons.github.io/ember-components", "authors": [ diff --git a/dist/amd/accordion/accordion-item.js b/dist/amd/accordion/accordion-item.js index 322f5f7..86ed0a5 100644 --- a/dist/amd/accordion/accordion-item.js +++ b/dist/amd/accordion/accordion-item.js @@ -133,14 +133,12 @@ define( hide: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.removeClass('in'); - return $accordionBody.height($accordionBody.height())[0].offsetHeight; + return $accordionBody.removeClass('in'); }, show: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.addClass('in'); - return $accordionBody.height($accordionBody[0]['scrollHeight']); + return $accordionBody.addClass('in'); } }); diff --git a/dist/amd/list/list.js b/dist/amd/list/list.js index 74dc09c..4afef1e 100644 --- a/dist/amd/list/list.js +++ b/dist/amd/list/list.js @@ -22,6 +22,7 @@ define( List = Component.extend(WithConfigMixin, { tagName: 'ul', + attributeBindings: ['style'], classNameBindings: ['styleClasses'], styleClasses: (function() { var _ref; @@ -36,6 +37,11 @@ define( */ selected: void 0, + /** + * True if this list supports selection + */ + selection: true, + /** * List can be bound to models, models can be a property or an object that the list is bound to. * When model changes, the list will give an opportunity to every item within the list to react upon the model change, @@ -97,24 +103,28 @@ define( */ select: function(item) { var _ref; - if (!item || this.get('selected') === item) { - return; - } - Em.debug("Selecting tab: " + (item.get('index'))); - if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { - this.get('selected').sendAction('on-deselect', this.get('selected')); + if (!this.get('selection')) { + return item.sendAction('on-click', item); + } else { + if (!item || this.get('selected') === item) { + return; + } + Em.debug("Selecting tab: " + (item.get('index'))); + if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { + this.get('selected').sendAction('on-deselect', this.get('selected')); + } + this.set('selected', item); + this.get('selected').sendAction('on-select', this.get('selected')); + this.set('selected-idx', item.get('index')); + return this.get('items').forEach((function(_this) { + return function(i) { + if (_this.get('selected') === i) { + return; + } + return i.sendAction('on-selection-change', i, _this.get('selected')); + }; + })(this)); } - this.set('selected', item); - this.get('selected').sendAction('on-select', this.get('selected')); - this.set('selected-idx', item.get('index')); - return this.get('items').forEach((function(_this) { - return function(i) { - if (_this.get('selected') === i) { - return; - } - return i.sendAction('on-selection-change', i, _this.get('selected')); - }; - })(this)); }, notifyModelsChange: (function() { return run.next(this, function() { diff --git a/dist/amd/main.js b/dist/amd/main.js index 3b8afa1..eb5bda4 100644 --- a/dist/amd/main.js +++ b/dist/amd/main.js @@ -1,6 +1,6 @@ define( - ["./tabs/tabs","./tabs/tabs-css","./tabs/tab-list","./tabs/tab","./tabs/tab-panel","./wysiwyg/wysiwyg","./wysiwyg/toolbar","./wysiwyg/action-group","./wysiwyg/action","./wysiwyg/actiontmpl","./wysiwyg/editor","./accordion/accordion","./accordion/accordion-item","./accordion/accordion-item-tmpl","./tree/node","./tree/tree-node","./tree/tree-node-tmpl","./tree/tree-branch","./tree/tree-branch-tmpl","./tree/tree-branch-css","./list/list","./list/list-item","ember","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __exports__) { + ["./tabs/tabs","./tabs/tabs-css","./tabs/tab-list","./tabs/tab","./tabs/tab-panel","./wysiwyg/wysiwyg","./wysiwyg/toolbar","./wysiwyg/action-group","./wysiwyg/action","./wysiwyg/actiontmpl","./wysiwyg/editor","./accordion/accordion","./accordion/accordion-item","./accordion/accordion-item-tmpl","./tree/tree","./tree/tree-tmpl","./tree/tree-css","./tree/node","./tree/tree-node","./tree/tree-node-tmpl","./tree/tree-node-icon-action","./tree/tree-branch","./tree/tree-branch-tmpl","./list/list","./list/list-item","./modal/modal","./modal/modal-css","./modal/modal-form","./modal/modal-emform","./modal/modal-title","./modal/modal-body","./modal/modal-footer","./modal/modal-toggler","./modal/modal-tmpl","./modal/modal-confirm","./modal/modal-confirm-tmpl","./button/button","./button/button-tmpl","ember","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __dependency34__, __dependency35__, __dependency36__, __dependency37__, __dependency38__, __dependency39__, __exports__) { "use strict"; var TabsComponent = __dependency1__["default"] || __dependency1__; @@ -30,16 +30,32 @@ define( var AccordionItemTmpl = __dependency14__["default"] || __dependency14__; - var TreeNode = __dependency15__["default"] || __dependency15__; - var TreeNodeComponent = __dependency16__["default"] || __dependency16__; - var TreeNodeTmpl = __dependency17__["default"] || __dependency17__; - var TreeBranchComponent = __dependency18__["default"] || __dependency18__; - var TreeBranchTmpl = __dependency19__["default"] || __dependency19__; - var TreeBranchStyle = __dependency20__["default"] || __dependency20__; - var ListComponent = __dependency21__["default"] || __dependency21__; - var ListItemComponent = __dependency22__["default"] || __dependency22__; - var Application = __dependency23__.Application; - var Namespace = __dependency23__.Namespace; + var TreeComponent = __dependency15__["default"] || __dependency15__; + var TreeTmpl = __dependency16__["default"] || __dependency16__; + var TreeStyle = __dependency17__["default"] || __dependency17__; + var TreeNode = __dependency18__["default"] || __dependency18__; + var TreeNodeComponent = __dependency19__["default"] || __dependency19__; + var TreeNodeTmpl = __dependency20__["default"] || __dependency20__; + var TreeNodeIconAction = __dependency21__["default"] || __dependency21__; + var TreeBranchComponent = __dependency22__["default"] || __dependency22__; + var TreeBranchTmpl = __dependency23__["default"] || __dependency23__; + var ListComponent = __dependency24__["default"] || __dependency24__; + var ListItemComponent = __dependency25__["default"] || __dependency25__; + var ModalComponent = __dependency26__["default"] || __dependency26__; + var ModalCss = __dependency27__["default"] || __dependency27__; + var ModalFormComponent = __dependency28__["default"] || __dependency28__; + var ModalEmFormComponent = __dependency29__["default"] || __dependency29__; + var ModalTitleComponent = __dependency30__["default"] || __dependency30__; + var ModalBodyComponent = __dependency31__["default"] || __dependency31__; + var ModalFooterComponent = __dependency32__["default"] || __dependency32__; + var ModalTogglerComponent = __dependency33__["default"] || __dependency33__; + var ModalTmpl = __dependency34__["default"] || __dependency34__; + var ModalConfirmComponent = __dependency35__["default"] || __dependency35__; + var ModalConfirmTmpl = __dependency36__["default"] || __dependency36__; + var ButtonComponent = __dependency37__["default"] || __dependency37__; + var ButtonTmplComponent = __dependency38__["default"] || __dependency38__; + var Application = __dependency39__.Application; + var Namespace = __dependency39__.Namespace; Application.initializer({ name: 'em-components', @@ -56,6 +72,7 @@ define( tabListTag: ['ul'] }, tree: { + classes: ['em-tree-branch', 'em-tree', 'fa-ul'], branchClasses: ['em-tree-branch', 'fa-ul'], nodeClasses: ['em-tree-node'], nodeOpenClasses: [], @@ -97,6 +114,12 @@ define( panelTogglerClasses: ['accordion-toggle'], panelBodyContainerClasses: ['panel-collapse', 'collapse'], panelBodyClasses: ['panel-body'] + }, + modal: { + classes: ['em-modal', 'modal', 'fade'], + bodyClasses: ['modal-body'], + titleClasses: ['modal-header'], + footerClasses: ['modal-footer'] } }); Config.addConfig('foundation', { @@ -122,13 +145,29 @@ define( c.register('component:em-accordion', AccordionComponent); c.register('component:em-accordion-item', AccordionItemComponent); c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); + c.register('component:em-tree', TreeComponent); + c.register('template:em-tree', TreeTmpl); c.register('component:em-tree-node', TreeNodeComponent); c.register('template:em-tree-node', TreeNodeTmpl); + c.register('component:em-tree-node-icon-action', TreeNodeIconAction); c.register('component:em-tree-branch', TreeBranchComponent); c.register('template:em-tree-branch', TreeBranchTmpl); - c.register('template:components/em-tree-branch-css', TreeBranchStyle); + c.register('template:components/em-tree-css', TreeStyle); c.register('component:em-list', ListComponent); - return c.register('component:em-list-item', ListItemComponent); + c.register('component:em-list-item', ListItemComponent); + c.register('component:em-modal', ModalComponent); + c.register('template:components/em-modal-css', ModalCss); + c.register('component:em-modal-form', ModalFormComponent); + c.register('component:em-modal-emform', ModalEmFormComponent); + c.register('component:em-modal-title', ModalTitleComponent); + c.register('component:em-modal-body', ModalBodyComponent); + c.register('component:em-modal-footer', ModalFooterComponent); + c.register('component:em-modal-toggler', ModalTogglerComponent); + c.register('template:em-modal', ModalTmpl); + c.register('component:em-modal-confirm', ModalConfirmComponent); + c.register('template:em-modal-confirm', ModalConfirmTmpl); + c.register('component:em-button', ButtonComponent); + return c.register('template:em-button', ButtonTmplComponent); } }); @@ -143,9 +182,20 @@ define( __exports__.WysiwygEditorComponent = WysiwygEditorComponent; __exports__.AccordionComponent = AccordionComponent; __exports__.AccordionItemComponent = AccordionItemComponent; + __exports__.TreeComponent = TreeComponent; __exports__.TreeNodeComponent = TreeNodeComponent; __exports__.TreeBranchComponent = TreeBranchComponent; __exports__.TreeNode = TreeNode; + __exports__.TreeNodeIconAction = TreeNodeIconAction; __exports__.ListComponent = ListComponent; __exports__.ListItemComponent = ListItemComponent; + __exports__.ModalComponent = ModalComponent; + __exports__.ModalTitleComponent = ModalTitleComponent; + __exports__.ModalBodyComponent = ModalBodyComponent; + __exports__.ModalFooterComponent = ModalFooterComponent; + __exports__.ModalTogglerComponent = ModalTogglerComponent; + __exports__.ModalConfirmComponent = ModalConfirmComponent; + __exports__.ModalFormComponent = ModalFormComponent; + __exports__.ModalEmFormComponent = ModalEmFormComponent; + __exports__.ButtonComponent = ButtonComponent; }); \ No newline at end of file diff --git a/dist/amd/tree/node.js b/dist/amd/tree/node.js index 4844dc1..3a82645 100644 --- a/dist/amd/tree/node.js +++ b/dist/amd/tree/node.js @@ -3,7 +3,7 @@ define( function(__dependency1__, __exports__) { "use strict"; var Ember = __dependency1__["default"] || __dependency1__; - var Node; + var Node, findChildrenOfNodeBy; Node = Ember.Object.extend({ children: void 0, @@ -64,8 +64,30 @@ define( }).property('children.length'), isLevel1: (function() { return this.get('level') === 0; - }).property('children.length') + }).property('children.length'), + findChildBy: function(key, name) { + return findChildrenOfNodeBy(this, key, name); + } }); __exports__["default"] = Node; + + findChildrenOfNodeBy = function(currChild, key, value) { + var c, _i, _len, _ref, _ref1; + if (currChild.get(key) === value) { + return currChild; + } else if (((_ref = currChild.get('children')) != null ? _ref.length : void 0) > 0) { + _ref1 = currChild.get('children'); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + c = _ref1[_i]; + if (c.get(key) === value) { + return c; + } else { + findChildrenOfNodeBy(c, key, value); + } + } + return null; + } + return null; + }; }); \ No newline at end of file diff --git a/dist/amd/tree/tree-branch-tmpl.js b/dist/amd/tree/tree-branch-tmpl.js index 5a7fddc..99f7349 100644 --- a/dist/amd/tree/tree-branch-tmpl.js +++ b/dist/amd/tree/tree-branch-tmpl.js @@ -2,5 +2,5 @@ define( ["exports"], function(__exports__) { "use strict"; - __exports__["default"] = Ember.Handlebars.compile("{{#each nodes}}\n {{em-tree-node node=this async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); + __exports__["default"] = Ember.Handlebars.compile("{{#each children}}\n {{em-tree-node model=this tree=view.tree async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); }); \ No newline at end of file diff --git a/dist/amd/tree/tree-branch.js b/dist/amd/tree/tree-branch.js index 50a043e..d651e42 100644 --- a/dist/amd/tree/tree-branch.js +++ b/dist/amd/tree/tree-branch.js @@ -20,20 +20,15 @@ define( TreeBranch = Component.extend(WithConfigMixin, { /** - * The node to render its children within this branch - * this property is expected to be defined by the user + * The model to render its children within this branch + * this property is set during component markup creation */ - node: void 0, - - /** - * The root node of the tree - */ - rootNode: computed.alias('node.root'), + model: void 0, /** * A list of {{#crossLink "TreeNode"}}nodes{{/crossLink}} instances. */ - nodes: computed.alias('node.children'), + children: computed.alias('model.children'), /** * True if node's children should be loaded asynchronously diff --git a/dist/amd/tree/tree-node-tmpl.js b/dist/amd/tree/tree-node-tmpl.js index 0f158a5..02686dc 100644 --- a/dist/amd/tree/tree-node-tmpl.js +++ b/dist/amd/tree/tree-node-tmpl.js @@ -2,5 +2,5 @@ define( ["exports"], function(__exports__) { "use strict"; - __exports__["default"] = Ember.Handlebars.compile("{{#if hasIcon}}\n \n{{else}}\n *\n{{/if}}\n\n{{node.title}}\n\n{{#if expanded}}\n {{em-tree-branch node=node async=async targetObject=targetObject}}\n{{/if}}"); + __exports__["default"] = Ember.Handlebars.compile("\n{{else}}\n *\n{{/if}}\n\n\n{{#if tree.in-multi-selection}}\n \n {{#if multi-selected}}\n \n {{else}}\n \n {{/if}}\n \n{{/if}}\n\n\n{{model.title}}\n{{#if tree.hovered-actions}}\n \n {{#each tree.hovered-actions}}\n {{em-tree-node-icon-action meta=this model=controller.model}}\n {{/each}}\n \n{{/if}}\n\n\n{{#if expanded}}\n {{em-tree-branch model=model tree=tree async=async targetObject=targetObject}}\n{{/if}}"); }); \ No newline at end of file diff --git a/dist/amd/tree/tree-node.js b/dist/amd/tree/tree-node.js index eb939da..573d850 100644 --- a/dist/amd/tree/tree-node.js +++ b/dist/amd/tree/tree-node.js @@ -18,49 +18,50 @@ define( */ TreeNode = Component.extend(WithConfigMixin, { + attributeBindings: ['multi-selected'], /** - * The node model the tree node view is bound to + * The model the tree node view is bound to */ - node: void 0, + model: void 0, /** - * true if the node of this view is a root node + * A reference to the tree view, this property is auto set during component instantiation */ - isRootNode: computed.not('node.hasParent'), + tree: void 0, /** - * The root node model + * A reference to the root model */ - root: computed.alias('node.root'), + rootModel: computed.alias('tree.model'), /** * True if the node is currently expanded, meaning its children are visible. */ - expanded: false, + expanded: computed.alias('model.expanded'), /** - * True if this node is currently checked - * This is only relevant if the tree configured to support selection + * True if this node view is currently checked + * This is only relevant if the tree configured to support multi selection */ - checked: false, + 'multi-selected': computed.alias('model.selected'), /** - * True if should render an icon tag for this node + * True if should render an icon tag for this node view */ hasIcon: true, /** - * True if nodes can be selected + * True if this node can be single selected */ selectable: true, /** - * True if this node is currently selected + * True if this node is currently single selected */ isSelected: (function() { - return this.get('rootBranchView.selected') === this.get('node'); - }).property('rootBranchView.selected'), + return this.get('tree.selected') === this.get('model'); + }).property('tree.selected'), /** * True if this node is currently loading, @@ -75,31 +76,11 @@ define( async: computed.alias('parentView.async'), /** - * Get the view of the root node + * true if this is a leaf node, meaning it has no children */ - rootNodeView: (function() { - var view; - if (this.get('isRootNode')) { - return this; - } - view = this.get('parentView'); - while (view) { - if (view.get('isRootNode')) { - return view; - } - view = view.get('parentView'); - } - }).property('node'), - - /** - * The root branch view - */ - rootBranchView: (function() { - return this.get('rootNodeView.parentView'); - }).property('rootNodeView'), leaf: (function() { - return this.get('node.children.length') === 0; - }).property('node.children.length'), + return !this.get('model.children') || this.get('model.children.length') === 0; + }).property('model.children.length'), tagName: 'li', layoutName: 'em-tree-node', classNameBindings: ['styleClasses', 'expandedClasses', 'leafClasses'], @@ -123,16 +104,23 @@ define( return null; } }).property('isSelected'), + addMultiSelectionToTreeSelection: (function() { + if (this.get('multi-selected')) { + return this.get('tree.multi-selection').pushObject(this.get('model')); + } else { + return this.get('tree.multi-selection').removeObject(this.get('model')); + } + }).observes('multi-selected').on('init'), iconClass: (function() { var icons; icons = []; if (this.get('async')) { if (this.get('loading')) { icons = icons.concat(this.get('config.tree.nodeLoadingIconClasses')); - } else if (!this.get('node.children')) { + } else if (!this.get('model.children')) { icons = icons.concat(this.get('config.tree.nodeCloseIconClasses')); } else { - if (this.get('node.children.length') === 0) { + if (this.get('model.children.length') === 0) { icons = icons.concat(this.get('config.tree.nodeLeafIconClasses')); } else { icons = this.get('expanded') ? icons.concat(this.get('config.tree.nodeOpenIconClasses')) : icons.concat(this.get('config.tree.nodeCloseIconClasses')); @@ -155,9 +143,9 @@ define( }).property('leaf'), actions: { toggle: function() { - if (this.get('async') && !this.get('expanded') && !this.get('node.children')) { + if (this.get('async') && !this.get('expanded') && !this.get('model.children')) { this.set('loading', true); - return this.sendAction('children', this.get('node'), this); + return this.sendAction('children', this.get('model'), this); } else { return this.toggleProperty('expanded'); } @@ -166,7 +154,14 @@ define( if (!this.get('selectable')) { return; } - return this.set('rootBranchView.selected', this.get('node')); + return this.set('tree.selected', this.get('model')); + }, + toggleSelection: function() { + if (this.get('multi-selected')) { + return this.set('multi-selected', ''); + } else { + return this.set('multi-selected', 'true'); + } } }, children: 'getChildren', diff --git a/dist/cjs/accordion/accordion-item.js b/dist/cjs/accordion/accordion-item.js index ccf4358..cb4a44f 100644 --- a/dist/cjs/accordion/accordion-item.js +++ b/dist/cjs/accordion/accordion-item.js @@ -130,14 +130,12 @@ AccordionItem = Component.extend(WithConfigMixin, { hide: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.removeClass('in'); - return $accordionBody.height($accordionBody.height())[0].offsetHeight; + return $accordionBody.removeClass('in'); }, show: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.addClass('in'); - return $accordionBody.height($accordionBody[0]['scrollHeight']); + return $accordionBody.addClass('in'); } }); diff --git a/dist/cjs/list/list.js b/dist/cjs/list/list.js index 640cf0f..c2257b8 100644 --- a/dist/cjs/list/list.js +++ b/dist/cjs/list/list.js @@ -19,6 +19,7 @@ WithConfigMixin = Em.Eu.WithConfigMixin; List = Component.extend(WithConfigMixin, { tagName: 'ul', + attributeBindings: ['style'], classNameBindings: ['styleClasses'], styleClasses: (function() { var _ref; @@ -33,6 +34,11 @@ List = Component.extend(WithConfigMixin, { */ selected: void 0, + /** + * True if this list supports selection + */ + selection: true, + /** * List can be bound to models, models can be a property or an object that the list is bound to. * When model changes, the list will give an opportunity to every item within the list to react upon the model change, @@ -94,24 +100,28 @@ List = Component.extend(WithConfigMixin, { */ select: function(item) { var _ref; - if (!item || this.get('selected') === item) { - return; - } - Em.debug("Selecting tab: " + (item.get('index'))); - if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { - this.get('selected').sendAction('on-deselect', this.get('selected')); + if (!this.get('selection')) { + return item.sendAction('on-click', item); + } else { + if (!item || this.get('selected') === item) { + return; + } + Em.debug("Selecting tab: " + (item.get('index'))); + if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { + this.get('selected').sendAction('on-deselect', this.get('selected')); + } + this.set('selected', item); + this.get('selected').sendAction('on-select', this.get('selected')); + this.set('selected-idx', item.get('index')); + return this.get('items').forEach((function(_this) { + return function(i) { + if (_this.get('selected') === i) { + return; + } + return i.sendAction('on-selection-change', i, _this.get('selected')); + }; + })(this)); } - this.set('selected', item); - this.get('selected').sendAction('on-select', this.get('selected')); - this.set('selected-idx', item.get('index')); - return this.get('items').forEach((function(_this) { - return function(i) { - if (_this.get('selected') === i) { - return; - } - return i.sendAction('on-selection-change', i, _this.get('selected')); - }; - })(this)); }, notifyModelsChange: (function() { return run.next(this, function() { diff --git a/dist/cjs/main.js b/dist/cjs/main.js index 842ba06..ac79358 100644 --- a/dist/cjs/main.js +++ b/dist/cjs/main.js @@ -27,14 +27,30 @@ var AccordionItemComponent = require("./accordion/accordion-item")["default"] || var AccordionItemTmpl = require("./accordion/accordion-item-tmpl")["default"] || require("./accordion/accordion-item-tmpl"); +var TreeComponent = require("./tree/tree")["default"] || require("./tree/tree"); +var TreeTmpl = require("./tree/tree-tmpl")["default"] || require("./tree/tree-tmpl"); +var TreeStyle = require("./tree/tree-css")["default"] || require("./tree/tree-css"); var TreeNode = require("./tree/node")["default"] || require("./tree/node"); var TreeNodeComponent = require("./tree/tree-node")["default"] || require("./tree/tree-node"); var TreeNodeTmpl = require("./tree/tree-node-tmpl")["default"] || require("./tree/tree-node-tmpl"); +var TreeNodeIconAction = require("./tree/tree-node-icon-action")["default"] || require("./tree/tree-node-icon-action"); var TreeBranchComponent = require("./tree/tree-branch")["default"] || require("./tree/tree-branch"); var TreeBranchTmpl = require("./tree/tree-branch-tmpl")["default"] || require("./tree/tree-branch-tmpl"); -var TreeBranchStyle = require("./tree/tree-branch-css")["default"] || require("./tree/tree-branch-css"); var ListComponent = require("./list/list")["default"] || require("./list/list"); var ListItemComponent = require("./list/list-item")["default"] || require("./list/list-item"); +var ModalComponent = require("./modal/modal")["default"] || require("./modal/modal"); +var ModalCss = require("./modal/modal-css")["default"] || require("./modal/modal-css"); +var ModalFormComponent = require("./modal/modal-form")["default"] || require("./modal/modal-form"); +var ModalEmFormComponent = require("./modal/modal-emform")["default"] || require("./modal/modal-emform"); +var ModalTitleComponent = require("./modal/modal-title")["default"] || require("./modal/modal-title"); +var ModalBodyComponent = require("./modal/modal-body")["default"] || require("./modal/modal-body"); +var ModalFooterComponent = require("./modal/modal-footer")["default"] || require("./modal/modal-footer"); +var ModalTogglerComponent = require("./modal/modal-toggler")["default"] || require("./modal/modal-toggler"); +var ModalTmpl = require("./modal/modal-tmpl")["default"] || require("./modal/modal-tmpl"); +var ModalConfirmComponent = require("./modal/modal-confirm")["default"] || require("./modal/modal-confirm"); +var ModalConfirmTmpl = require("./modal/modal-confirm-tmpl")["default"] || require("./modal/modal-confirm-tmpl"); +var ButtonComponent = require("./button/button")["default"] || require("./button/button"); +var ButtonTmplComponent = require("./button/button-tmpl")["default"] || require("./button/button-tmpl"); var Application = require("ember").Application; var Namespace = require("ember").Namespace; @@ -53,6 +69,7 @@ Application.initializer({ tabListTag: ['ul'] }, tree: { + classes: ['em-tree-branch', 'em-tree', 'fa-ul'], branchClasses: ['em-tree-branch', 'fa-ul'], nodeClasses: ['em-tree-node'], nodeOpenClasses: [], @@ -94,6 +111,12 @@ Application.initializer({ panelTogglerClasses: ['accordion-toggle'], panelBodyContainerClasses: ['panel-collapse', 'collapse'], panelBodyClasses: ['panel-body'] + }, + modal: { + classes: ['em-modal', 'modal', 'fade'], + bodyClasses: ['modal-body'], + titleClasses: ['modal-header'], + footerClasses: ['modal-footer'] } }); Config.addConfig('foundation', { @@ -119,13 +142,29 @@ Application.initializer({ c.register('component:em-accordion', AccordionComponent); c.register('component:em-accordion-item', AccordionItemComponent); c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); + c.register('component:em-tree', TreeComponent); + c.register('template:em-tree', TreeTmpl); c.register('component:em-tree-node', TreeNodeComponent); c.register('template:em-tree-node', TreeNodeTmpl); + c.register('component:em-tree-node-icon-action', TreeNodeIconAction); c.register('component:em-tree-branch', TreeBranchComponent); c.register('template:em-tree-branch', TreeBranchTmpl); - c.register('template:components/em-tree-branch-css', TreeBranchStyle); + c.register('template:components/em-tree-css', TreeStyle); c.register('component:em-list', ListComponent); - return c.register('component:em-list-item', ListItemComponent); + c.register('component:em-list-item', ListItemComponent); + c.register('component:em-modal', ModalComponent); + c.register('template:components/em-modal-css', ModalCss); + c.register('component:em-modal-form', ModalFormComponent); + c.register('component:em-modal-emform', ModalEmFormComponent); + c.register('component:em-modal-title', ModalTitleComponent); + c.register('component:em-modal-body', ModalBodyComponent); + c.register('component:em-modal-footer', ModalFooterComponent); + c.register('component:em-modal-toggler', ModalTogglerComponent); + c.register('template:em-modal', ModalTmpl); + c.register('component:em-modal-confirm', ModalConfirmComponent); + c.register('template:em-modal-confirm', ModalConfirmTmpl); + c.register('component:em-button', ButtonComponent); + return c.register('template:em-button', ButtonTmplComponent); } }); @@ -140,8 +179,19 @@ exports.WysiwygActionComponent = WysiwygActionComponent; exports.WysiwygEditorComponent = WysiwygEditorComponent; exports.AccordionComponent = AccordionComponent; exports.AccordionItemComponent = AccordionItemComponent; +exports.TreeComponent = TreeComponent; exports.TreeNodeComponent = TreeNodeComponent; exports.TreeBranchComponent = TreeBranchComponent; exports.TreeNode = TreeNode; +exports.TreeNodeIconAction = TreeNodeIconAction; exports.ListComponent = ListComponent; -exports.ListItemComponent = ListItemComponent; \ No newline at end of file +exports.ListItemComponent = ListItemComponent; +exports.ModalComponent = ModalComponent; +exports.ModalTitleComponent = ModalTitleComponent; +exports.ModalBodyComponent = ModalBodyComponent; +exports.ModalFooterComponent = ModalFooterComponent; +exports.ModalTogglerComponent = ModalTogglerComponent; +exports.ModalConfirmComponent = ModalConfirmComponent; +exports.ModalFormComponent = ModalFormComponent; +exports.ModalEmFormComponent = ModalEmFormComponent; +exports.ButtonComponent = ButtonComponent; \ No newline at end of file diff --git a/dist/cjs/tree/node.js b/dist/cjs/tree/node.js index b6532f5..126beb5 100644 --- a/dist/cjs/tree/node.js +++ b/dist/cjs/tree/node.js @@ -1,6 +1,6 @@ "use strict"; var Ember = require("ember")["default"] || require("ember"); -var Node; +var Node, findChildrenOfNodeBy; Node = Ember.Object.extend({ children: void 0, @@ -61,7 +61,29 @@ Node = Ember.Object.extend({ }).property('children.length'), isLevel1: (function() { return this.get('level') === 0; - }).property('children.length') + }).property('children.length'), + findChildBy: function(key, name) { + return findChildrenOfNodeBy(this, key, name); + } }); -exports["default"] = Node; \ No newline at end of file +exports["default"] = Node; + +findChildrenOfNodeBy = function(currChild, key, value) { + var c, _i, _len, _ref, _ref1; + if (currChild.get(key) === value) { + return currChild; + } else if (((_ref = currChild.get('children')) != null ? _ref.length : void 0) > 0) { + _ref1 = currChild.get('children'); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + c = _ref1[_i]; + if (c.get(key) === value) { + return c; + } else { + findChildrenOfNodeBy(c, key, value); + } + } + return null; + } + return null; +}; \ No newline at end of file diff --git a/dist/cjs/tree/tree-branch-tmpl.js b/dist/cjs/tree/tree-branch-tmpl.js index df9349c..7c1c2f7 100644 --- a/dist/cjs/tree/tree-branch-tmpl.js +++ b/dist/cjs/tree/tree-branch-tmpl.js @@ -1,2 +1,2 @@ "use strict"; -exports["default"] = Ember.Handlebars.compile("{{#each nodes}}\n {{em-tree-node node=this async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); \ No newline at end of file +exports["default"] = Ember.Handlebars.compile("{{#each children}}\n {{em-tree-node model=this tree=view.tree async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); \ No newline at end of file diff --git a/dist/cjs/tree/tree-branch.js b/dist/cjs/tree/tree-branch.js index 138de2a..52c9736 100644 --- a/dist/cjs/tree/tree-branch.js +++ b/dist/cjs/tree/tree-branch.js @@ -17,20 +17,15 @@ WithConfigMixin = Em.Eu.WithConfigMixin; TreeBranch = Component.extend(WithConfigMixin, { /** - * The node to render its children within this branch - * this property is expected to be defined by the user + * The model to render its children within this branch + * this property is set during component markup creation */ - node: void 0, - - /** - * The root node of the tree - */ - rootNode: computed.alias('node.root'), + model: void 0, /** * A list of {{#crossLink "TreeNode"}}nodes{{/crossLink}} instances. */ - nodes: computed.alias('node.children'), + children: computed.alias('model.children'), /** * True if node's children should be loaded asynchronously diff --git a/dist/cjs/tree/tree-node-tmpl.js b/dist/cjs/tree/tree-node-tmpl.js index f82118e..c8cb70d 100644 --- a/dist/cjs/tree/tree-node-tmpl.js +++ b/dist/cjs/tree/tree-node-tmpl.js @@ -1,2 +1,2 @@ "use strict"; -exports["default"] = Ember.Handlebars.compile("{{#if hasIcon}}\n \n{{else}}\n *\n{{/if}}\n\n{{node.title}}\n\n{{#if expanded}}\n {{em-tree-branch node=node async=async targetObject=targetObject}}\n{{/if}}"); \ No newline at end of file +exports["default"] = Ember.Handlebars.compile("\n{{else}}\n *\n{{/if}}\n\n\n{{#if tree.in-multi-selection}}\n \n {{#if multi-selected}}\n \n {{else}}\n \n {{/if}}\n \n{{/if}}\n\n\n{{model.title}}\n{{#if tree.hovered-actions}}\n \n {{#each tree.hovered-actions}}\n {{em-tree-node-icon-action meta=this model=controller.model}}\n {{/each}}\n \n{{/if}}\n\n\n{{#if expanded}}\n {{em-tree-branch model=model tree=tree async=async targetObject=targetObject}}\n{{/if}}"); \ No newline at end of file diff --git a/dist/cjs/tree/tree-node.js b/dist/cjs/tree/tree-node.js index 2e62325..f9cc1eb 100644 --- a/dist/cjs/tree/tree-node.js +++ b/dist/cjs/tree/tree-node.js @@ -15,49 +15,50 @@ WithConfigMixin = Em.Eu.WithConfigMixin; */ TreeNode = Component.extend(WithConfigMixin, { + attributeBindings: ['multi-selected'], /** - * The node model the tree node view is bound to + * The model the tree node view is bound to */ - node: void 0, + model: void 0, /** - * true if the node of this view is a root node + * A reference to the tree view, this property is auto set during component instantiation */ - isRootNode: computed.not('node.hasParent'), + tree: void 0, /** - * The root node model + * A reference to the root model */ - root: computed.alias('node.root'), + rootModel: computed.alias('tree.model'), /** * True if the node is currently expanded, meaning its children are visible. */ - expanded: false, + expanded: computed.alias('model.expanded'), /** - * True if this node is currently checked - * This is only relevant if the tree configured to support selection + * True if this node view is currently checked + * This is only relevant if the tree configured to support multi selection */ - checked: false, + 'multi-selected': computed.alias('model.selected'), /** - * True if should render an icon tag for this node + * True if should render an icon tag for this node view */ hasIcon: true, /** - * True if nodes can be selected + * True if this node can be single selected */ selectable: true, /** - * True if this node is currently selected + * True if this node is currently single selected */ isSelected: (function() { - return this.get('rootBranchView.selected') === this.get('node'); - }).property('rootBranchView.selected'), + return this.get('tree.selected') === this.get('model'); + }).property('tree.selected'), /** * True if this node is currently loading, @@ -72,31 +73,11 @@ TreeNode = Component.extend(WithConfigMixin, { async: computed.alias('parentView.async'), /** - * Get the view of the root node + * true if this is a leaf node, meaning it has no children */ - rootNodeView: (function() { - var view; - if (this.get('isRootNode')) { - return this; - } - view = this.get('parentView'); - while (view) { - if (view.get('isRootNode')) { - return view; - } - view = view.get('parentView'); - } - }).property('node'), - - /** - * The root branch view - */ - rootBranchView: (function() { - return this.get('rootNodeView.parentView'); - }).property('rootNodeView'), leaf: (function() { - return this.get('node.children.length') === 0; - }).property('node.children.length'), + return !this.get('model.children') || this.get('model.children.length') === 0; + }).property('model.children.length'), tagName: 'li', layoutName: 'em-tree-node', classNameBindings: ['styleClasses', 'expandedClasses', 'leafClasses'], @@ -120,16 +101,23 @@ TreeNode = Component.extend(WithConfigMixin, { return null; } }).property('isSelected'), + addMultiSelectionToTreeSelection: (function() { + if (this.get('multi-selected')) { + return this.get('tree.multi-selection').pushObject(this.get('model')); + } else { + return this.get('tree.multi-selection').removeObject(this.get('model')); + } + }).observes('multi-selected').on('init'), iconClass: (function() { var icons; icons = []; if (this.get('async')) { if (this.get('loading')) { icons = icons.concat(this.get('config.tree.nodeLoadingIconClasses')); - } else if (!this.get('node.children')) { + } else if (!this.get('model.children')) { icons = icons.concat(this.get('config.tree.nodeCloseIconClasses')); } else { - if (this.get('node.children.length') === 0) { + if (this.get('model.children.length') === 0) { icons = icons.concat(this.get('config.tree.nodeLeafIconClasses')); } else { icons = this.get('expanded') ? icons.concat(this.get('config.tree.nodeOpenIconClasses')) : icons.concat(this.get('config.tree.nodeCloseIconClasses')); @@ -152,9 +140,9 @@ TreeNode = Component.extend(WithConfigMixin, { }).property('leaf'), actions: { toggle: function() { - if (this.get('async') && !this.get('expanded') && !this.get('node.children')) { + if (this.get('async') && !this.get('expanded') && !this.get('model.children')) { this.set('loading', true); - return this.sendAction('children', this.get('node'), this); + return this.sendAction('children', this.get('model'), this); } else { return this.toggleProperty('expanded'); } @@ -163,7 +151,14 @@ TreeNode = Component.extend(WithConfigMixin, { if (!this.get('selectable')) { return; } - return this.set('rootBranchView.selected', this.get('node')); + return this.set('tree.selected', this.get('model')); + }, + toggleSelection: function() { + if (this.get('multi-selected')) { + return this.set('multi-selected', ''); + } else { + return this.set('multi-selected', 'true'); + } } }, children: 'getChildren', diff --git a/dist/globals/main.js b/dist/globals/main.js index c0ebfc5..cc58087 100644 --- a/dist/globals/main.js +++ b/dist/globals/main.js @@ -134,14 +134,12 @@ AccordionItem = Component.extend(WithConfigMixin, { hide: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.removeClass('in'); - return $accordionBody.height($accordionBody.height())[0].offsetHeight; + return $accordionBody.removeClass('in'); }, show: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.addClass('in'); - return $accordionBody.height($accordionBody[0]['scrollHeight']); + return $accordionBody.addClass('in'); } }); @@ -214,6 +212,157 @@ Accordion = Component.extend(WithConfigMixin, { exports["default"] = Accordion;; },{}],4:[function(_dereq_,module,exports){ "use strict"; +exports["default"] = Ember.Handlebars.compile("{{#if icon-classes}}\n \n{{/if}}\n{{label}}"); +},{}],5:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var computed = window.Ember.computed; + +var Button, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + + +/** + * Button component + * + * Styled button with async support. + * + * @class Button + */ + +Button = Component.extend(WithConfigMixin, { + + /** + * The tag name the component is rendered as. + * This theoretically can be a div or anything else. + * @property tagName + * @private + */ + tagName: 'button', + + /** + * The template of the component + * @property layoutName + * @private + */ + layoutName: 'em-button', + + /** + * Bind the specified properties as DOM attributes. + * @property attributeBindings + * @private + */ + attributeBindings: ['disabled', 'state'], + + /** + * Bind the specified properties as the classes of the DOM element. + */ + classNameBindings: ['class'], + + /** + * True if the button is disabled and cannot be clicked. + * @property disabled + * @public + */ + disabled: computed.equal('state', 'executing'), + + /** + * The state of the button, can be one of the following: + * default - The button is enabled and ready to be clicked. + * executing - The promise bound to the button was sent and the promise is still executing + * resolved - The promise was resolved properly. + * rejected - The promise bound to the button was finished as rejected. + * + * The state is also bound to the DOM as `state` property, this allows to easily change styles for every + * state by using `.em-button[state=resolved]` syntax. + * + * The label of the button will change to the value of the component properties that correspond to the + * states mentioned above. + * + * @property state + * @private + */ + state: 'default', + + /** + * The action name to invoke on the controller when the button is clicked. + * @property on-click + * @public + */ + 'on-click': void 0, + + /** + * If set, an icon tag will be added as apart of the button and the given value here will be set + * as the icon's `class` attribute. + * @property icon-classes + * @public + */ + 'icon-classes': (function() { + var propName; + propName = "icon-" + this.state; + return this.getWithDefault(propName, this.get('icon-default')); + }).property('state', 'icon-default', 'icon-executing', 'icon-resolved', 'icon-rejected'), + + /* + * The label of the button, calculated according to the state of the button + * See the `state` property documentation for more info. + * @property label + * @private + */ + label: (function() { + return this.getWithDefault(this.state, this.get('default')); + }).property('state', 'default', 'executing', 'resolved', 'rejected'), + + /** + * Set by the `onClick` callback, if set, the promise will be observed and the button's state will be + * changed accordingly. + * @property promise + * @private + */ + promise: void 0, + + /** + * Triggered when the button is clicked + * Invoke the action name on the controller defined in the `action` property, default is `onClick`. + * The action on the controller recieves a property that should be set to the promise being invoked (if there is one) + * If a promise was set, the button will move to 'executing' state until the promise will be resolved + * @method onClick + * @private + */ + onClick: (function() { + this.sendAction('on-click', (function(_this) { + return function(promise) { + _this.set('promise', promise); + return _this.set('state', 'executing'); + }; + })(this)); + return false; + }).on('click'), + + /* + * Observes the promise property + * @property changeStateByPromise + * @private + */ + changeStateByPromise: (function() { + return this.get('promise').then((function(_this) { + return function() { + return _this.set('state', 'resolved'); + }; + })(this), (function(_this) { + return function(err) { + _this.set('state', 'rejected'); + return _this.set('error', err); + }; + })(this)); + }).observes('promise') +}); + +exports["default"] = Button; +},{}],6:[function(_dereq_,module,exports){ +"use strict"; var Mixin = window.Ember.Mixin; var computed = window.Ember.computed; @@ -321,7 +470,7 @@ AsItem = Mixin.create({ }); exports["default"] = AsItem; -},{}],5:[function(_dereq_,module,exports){ +},{}],7:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -358,7 +507,7 @@ ListItem = Component.extend(WithConfigMixin, AsListMixin, { }); exports["default"] = ListItem;; -},{"./as-item":4}],6:[function(_dereq_,module,exports){ +},{"./as-item":6}],8:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -380,6 +529,7 @@ WithConfigMixin = Em.Eu.WithConfigMixin; List = Component.extend(WithConfigMixin, { tagName: 'ul', + attributeBindings: ['style'], classNameBindings: ['styleClasses'], styleClasses: (function() { var _ref; @@ -394,6 +544,11 @@ List = Component.extend(WithConfigMixin, { */ selected: void 0, + /** + * True if this list supports selection + */ + selection: true, + /** * List can be bound to models, models can be a property or an object that the list is bound to. * When model changes, the list will give an opportunity to every item within the list to react upon the model change, @@ -455,24 +610,28 @@ List = Component.extend(WithConfigMixin, { */ select: function(item) { var _ref; - if (!item || this.get('selected') === item) { - return; - } - Em.debug("Selecting tab: " + (item.get('index'))); - if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { - this.get('selected').sendAction('on-deselect', this.get('selected')); + if (!this.get('selection')) { + return item.sendAction('on-click', item); + } else { + if (!item || this.get('selected') === item) { + return; + } + Em.debug("Selecting tab: " + (item.get('index'))); + if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { + this.get('selected').sendAction('on-deselect', this.get('selected')); + } + this.set('selected', item); + this.get('selected').sendAction('on-select', this.get('selected')); + this.set('selected-idx', item.get('index')); + return this.get('items').forEach((function(_this) { + return function(i) { + if (_this.get('selected') === i) { + return; + } + return i.sendAction('on-selection-change', i, _this.get('selected')); + }; + })(this)); } - this.set('selected', item); - this.get('selected').sendAction('on-select', this.get('selected')); - this.set('selected-idx', item.get('index')); - return this.get('items').forEach((function(_this) { - return function(i) { - if (_this.get('selected') === i) { - return; - } - return i.sendAction('on-selection-change', i, _this.get('selected')); - }; - })(this)); }, notifyModelsChange: (function() { return run.next(this, function() { @@ -493,7 +652,7 @@ List = Component.extend(WithConfigMixin, { }); exports["default"] = List; -},{}],7:[function(_dereq_,module,exports){ +},{}],9:[function(_dereq_,module,exports){ "use strict"; var TabsComponent = _dereq_("./tabs/tabs")["default"] || _dereq_("./tabs/tabs"); @@ -523,125 +682,794 @@ var AccordionItemComponent = _dereq_("./accordion/accordion-item")["default"] || var AccordionItemTmpl = _dereq_("./accordion/accordion-item-tmpl")["default"] || _dereq_("./accordion/accordion-item-tmpl"); -var TreeNode = _dereq_("./tree/node")["default"] || _dereq_("./tree/node"); -var TreeNodeComponent = _dereq_("./tree/tree-node")["default"] || _dereq_("./tree/tree-node"); -var TreeNodeTmpl = _dereq_("./tree/tree-node-tmpl")["default"] || _dereq_("./tree/tree-node-tmpl"); -var TreeBranchComponent = _dereq_("./tree/tree-branch")["default"] || _dereq_("./tree/tree-branch"); -var TreeBranchTmpl = _dereq_("./tree/tree-branch-tmpl")["default"] || _dereq_("./tree/tree-branch-tmpl"); -var TreeBranchStyle = _dereq_("./tree/tree-branch-css")["default"] || _dereq_("./tree/tree-branch-css"); -var ListComponent = _dereq_("./list/list")["default"] || _dereq_("./list/list"); -var ListItemComponent = _dereq_("./list/list-item")["default"] || _dereq_("./list/list-item"); -var Application = window.Ember.Application; -var Namespace = window.Ember.Namespace; +var TreeComponent = _dereq_("./tree/tree")["default"] || _dereq_("./tree/tree"); +var TreeTmpl = _dereq_("./tree/tree-tmpl")["default"] || _dereq_("./tree/tree-tmpl"); +var TreeStyle = _dereq_("./tree/tree-css")["default"] || _dereq_("./tree/tree-css"); +var TreeNode = _dereq_("./tree/node")["default"] || _dereq_("./tree/node"); +var TreeNodeComponent = _dereq_("./tree/tree-node")["default"] || _dereq_("./tree/tree-node"); +var TreeNodeTmpl = _dereq_("./tree/tree-node-tmpl")["default"] || _dereq_("./tree/tree-node-tmpl"); +var TreeNodeIconAction = _dereq_("./tree/tree-node-icon-action")["default"] || _dereq_("./tree/tree-node-icon-action"); +var TreeBranchComponent = _dereq_("./tree/tree-branch")["default"] || _dereq_("./tree/tree-branch"); +var TreeBranchTmpl = _dereq_("./tree/tree-branch-tmpl")["default"] || _dereq_("./tree/tree-branch-tmpl"); +var ListComponent = _dereq_("./list/list")["default"] || _dereq_("./list/list"); +var ListItemComponent = _dereq_("./list/list-item")["default"] || _dereq_("./list/list-item"); +var ModalComponent = _dereq_("./modal/modal")["default"] || _dereq_("./modal/modal"); +var ModalCss = _dereq_("./modal/modal-css")["default"] || _dereq_("./modal/modal-css"); +var ModalFormComponent = _dereq_("./modal/modal-form")["default"] || _dereq_("./modal/modal-form"); +var ModalEmFormComponent = _dereq_("./modal/modal-emform")["default"] || _dereq_("./modal/modal-emform"); +var ModalTitleComponent = _dereq_("./modal/modal-title")["default"] || _dereq_("./modal/modal-title"); +var ModalBodyComponent = _dereq_("./modal/modal-body")["default"] || _dereq_("./modal/modal-body"); +var ModalFooterComponent = _dereq_("./modal/modal-footer")["default"] || _dereq_("./modal/modal-footer"); +var ModalTogglerComponent = _dereq_("./modal/modal-toggler")["default"] || _dereq_("./modal/modal-toggler"); +var ModalTmpl = _dereq_("./modal/modal-tmpl")["default"] || _dereq_("./modal/modal-tmpl"); +var ModalConfirmComponent = _dereq_("./modal/modal-confirm")["default"] || _dereq_("./modal/modal-confirm"); +var ModalConfirmTmpl = _dereq_("./modal/modal-confirm-tmpl")["default"] || _dereq_("./modal/modal-confirm-tmpl"); +var ButtonComponent = _dereq_("./button/button")["default"] || _dereq_("./button/button"); +var ButtonTmplComponent = _dereq_("./button/button-tmpl")["default"] || _dereq_("./button/button-tmpl"); +var Application = window.Ember.Application; +var Namespace = window.Ember.Namespace; + +Application.initializer({ + name: 'em-components', + initialize: function(c) { + var Config; + Em.EmberComponents = Namespace.create({ + VERSION: '0.0.1' + }); + Em.Config = Config = Em.Eu.Config.create(); + Config.addConfig('default', { + tabs: { + tabsTag: ['div'], + tabTag: ['li'], + tabListTag: ['ul'] + }, + tree: { + classes: ['em-tree-branch', 'em-tree', 'fa-ul'], + branchClasses: ['em-tree-branch', 'fa-ul'], + nodeClasses: ['em-tree-node'], + nodeOpenClasses: [], + nodeCloseClasses: [], + nodeOpenIconClasses: ['fa-li', 'fa', 'fa-minus-square-o'], + nodeCloseIconClasses: ['fa-li', 'fa', 'fa-plus-square-o'], + nodeLeafClasses: ['leaf'], + nodeLeafIconClasses: ['fa-li', 'fa', 'fa-square-o'], + nodeLoadingIconClasses: ['fa-li', 'fa', 'fa-spinner', 'fa-spin'], + nodeSelectedClasses: ['em-tree-node-active'] + } + }); + Config.addConfig('classic', { + tabs: { + tabsClasses: ['em-tabs'], + tabClasses: ['em-tab'], + tabListClasses: ['em-tab-list'], + tabPanelClasses: ['em-tab-panel'] + } + }); + Config.addConfig('bs', { + tabs: { + tabListClasses: ['nav', 'nav-tabs'], + tabSelectedClasses: ['active'] + }, + wysiwyg: { + classes: ['well'], + toolbarClasses: ['btn-toolbar'], + actionGroupClasses: ['btn-group'], + actionClasses: ['btn btn-default'], + actionActiveClasses: ['active'] + }, + accordion: { + classes: ['panel-group'], + itemClasses: ['panel', 'panel-default'], + itemSelectedClasses: ['active'], + panelHeaderClasses: ['panel-heading'], + panelTitleClasses: ['panel-title'], + panelTogglerClasses: ['accordion-toggle'], + panelBodyContainerClasses: ['panel-collapse', 'collapse'], + panelBodyClasses: ['panel-body'] + }, + modal: { + classes: ['em-modal', 'modal', 'fade'], + bodyClasses: ['modal-body'], + titleClasses: ['modal-header'], + footerClasses: ['modal-footer'] + } + }); + Config.addConfig('foundation', { + tabs: { + tabListClasses: ['tabs'], + tabSelectedClasses: ['active'], + tabClasses: ['tab-title'], + tabPanelClasses: ['content'] + } + }); + Em.EmberComponents.Config = Em.Config = Config; + c.register('component:em-tabs', TabsComponent); + c.register('template:components/em-tabs-css', TabsStyle); + c.register('component:em-tab-list', TabListComponent); + c.register('component:em-tab', TabComponent); + c.register('component:em-tab-panel', TabPanelComponent); + c.register('component:em-wysiwyg', WysiwygComponent); + c.register('component:em-wysiwyg-toolbar', WysiwygToolbarComponent); + c.register('component:em-wysiwyg-action-group', WysiwygActionGroupComponent); + c.register('component:em-wysiwyg-action', WysiwygActionComponent); + c.register('template:em-wysiwyg-action', WysiwygActionTmpl); + c.register('component:em-wysiwyg-editor', WysiwygEditorComponent); + c.register('component:em-accordion', AccordionComponent); + c.register('component:em-accordion-item', AccordionItemComponent); + c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); + c.register('component:em-tree', TreeComponent); + c.register('template:em-tree', TreeTmpl); + c.register('component:em-tree-node', TreeNodeComponent); + c.register('template:em-tree-node', TreeNodeTmpl); + c.register('component:em-tree-node-icon-action', TreeNodeIconAction); + c.register('component:em-tree-branch', TreeBranchComponent); + c.register('template:em-tree-branch', TreeBranchTmpl); + c.register('template:components/em-tree-css', TreeStyle); + c.register('component:em-list', ListComponent); + c.register('component:em-list-item', ListItemComponent); + c.register('component:em-modal', ModalComponent); + c.register('template:components/em-modal-css', ModalCss); + c.register('component:em-modal-form', ModalFormComponent); + c.register('component:em-modal-emform', ModalEmFormComponent); + c.register('component:em-modal-title', ModalTitleComponent); + c.register('component:em-modal-body', ModalBodyComponent); + c.register('component:em-modal-footer', ModalFooterComponent); + c.register('component:em-modal-toggler', ModalTogglerComponent); + c.register('template:em-modal', ModalTmpl); + c.register('component:em-modal-confirm', ModalConfirmComponent); + c.register('template:em-modal-confirm', ModalConfirmTmpl); + c.register('component:em-button', ButtonComponent); + return c.register('template:em-button', ButtonTmplComponent); + } +}); + +exports.TabsComponent = TabsComponent; +exports.TabListComponent = TabListComponent; +exports.TabComponent = TabComponent; +exports.TabPanelComponent = TabPanelComponent; +exports.WysiwygComponent = WysiwygComponent; +exports.WysiwygToolbarComponent = WysiwygToolbarComponent; +exports.WysiwygActionGroupComponent = WysiwygActionGroupComponent; +exports.WysiwygActionComponent = WysiwygActionComponent; +exports.WysiwygEditorComponent = WysiwygEditorComponent; +exports.AccordionComponent = AccordionComponent; +exports.AccordionItemComponent = AccordionItemComponent; +exports.TreeComponent = TreeComponent; +exports.TreeNodeComponent = TreeNodeComponent; +exports.TreeBranchComponent = TreeBranchComponent; +exports.TreeNode = TreeNode; +exports.TreeNodeIconAction = TreeNodeIconAction; +exports.ListComponent = ListComponent; +exports.ListItemComponent = ListItemComponent; +exports.ModalComponent = ModalComponent; +exports.ModalTitleComponent = ModalTitleComponent; +exports.ModalBodyComponent = ModalBodyComponent; +exports.ModalFooterComponent = ModalFooterComponent; +exports.ModalTogglerComponent = ModalTogglerComponent; +exports.ModalConfirmComponent = ModalConfirmComponent; +exports.ModalFormComponent = ModalFormComponent; +exports.ModalEmFormComponent = ModalEmFormComponent; +exports.ButtonComponent = ButtonComponent; +},{"./accordion/accordion":3,"./accordion/accordion-item":2,"./accordion/accordion-item-tmpl":1,"./button/button":5,"./button/button-tmpl":4,"./list/list":8,"./list/list-item":7,"./modal/modal":20,"./modal/modal-body":10,"./modal/modal-confirm":12,"./modal/modal-confirm-tmpl":11,"./modal/modal-css":13,"./modal/modal-emform":14,"./modal/modal-footer":15,"./modal/modal-form":16,"./modal/modal-title":17,"./modal/modal-tmpl":18,"./modal/modal-toggler":19,"./tabs/tab":23,"./tabs/tab-list":21,"./tabs/tab-panel":22,"./tabs/tabs":25,"./tabs/tabs-css":24,"./tree/node":26,"./tree/tree":34,"./tree/tree-branch":28,"./tree/tree-branch-tmpl":27,"./tree/tree-css":29,"./tree/tree-node":32,"./tree/tree-node-icon-action":30,"./tree/tree-node-tmpl":31,"./tree/tree-tmpl":33,"./wysiwyg/action":36,"./wysiwyg/action-group":35,"./wysiwyg/actiontmpl":37,"./wysiwyg/editor":38,"./wysiwyg/toolbar":39,"./wysiwyg/wysiwyg":40}],10:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var ModalBody, StyleBindingsMixin, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * `{{em-modal-body}}` component. + * + * The body of the modal + * + * @class ModalBody + * @public + */ + +ModalBody = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.bodyClasses')) != null ? _ref.join(" ") : void 0; + }).property() +}); + +exports["default"] = ModalBody; +},{}],11:[function(_dereq_,module,exports){ +"use strict"; +exports["default"] = Ember.Handlebars.compile("{{#em-modal id=confirm-id configName=configName model-id=model-id open-if=open-if close-if=close-if}}\n {{#em-modal-title}}\n {{#em-modal-toggler class=\"close\"}}×Close{{/em-modal-toggler}}\n

{{title}}

\n {{/em-modal-title}}\n {{#em-modal-body}}\n {{message}}\n {{/em-modal-body}}\n {{#em-modal-footer}}\n \n {{#em-modal-toggler class=\"btn btn-default\"}}No{{/em-modal-toggler}}\n {{/em-modal-footer}}\n{{/em-modal}}"); +},{}],12:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + + +/** + * A confirmation modal with 'Yes' & 'No' buttons + * When 'no' is pressed the modal is just closed. + * When 'yes' is pressed an action bound to the action on the controller set in the `confirm` property is invoked, + * giving the controller a chance to decide whether to close the modal or not. + * + * @class ModalConfirm + */ +var ModalConfirm; + +ModalConfirm = Component.extend({ + layoutName: 'em-modal-confirm', + + /** + * Bound to the action on the controller to be invoked when the 'yes' button is pressed. + * @property confirm + * @public + */ + confirm: "confirm", + + /** + * The default title of the modal if not set otherwise. + * + * @property title + * @public + */ + title: 'Please confirm', + + /** + * The default message of the modal if not set otherwise. + * + * @property message + * @public + */ + message: 'Please press Yes to confirm the operation.', + actions: { + + /** + * Invoked when the user clicks the "Yes" button, triggers an action on the controller. + * + * @method confirmPressed + * @private + */ + confirmPressed: function() { + return this.sendAction('confirm'); + } + } +}); + +exports["default"] = ModalConfirm; +},{}],13:[function(_dereq_,module,exports){ +"use strict"; +exports["default"] = Ember.Handlebars.compile(".em-modal {\n background-color: hsla(0, 0%, 100%, .85);\n}"); +},{}],14:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var FormModal = _dereq_("./modal-form")["default"] || _dereq_("./modal-form"); +var EmModalForm; + +EmModalForm = FormModal.extend({ + classNameBindings: ['form'], + attributeBindings: ['role'], + role: 'form', + model: void 0, + submit_button: false +}); + +exports["default"] = EmModalForm; +},{"./modal-form":16}],15:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var ModalFooter, StyleBindingsMixin, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * `{{em-modal-footer}}` component. + * + * The footer of the modal + * + * @class ModalFooter + * @public + */ + +ModalFooter = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.footerClasses')) != null ? _ref.join(" ") : void 0; + }).property() +}); + +exports["default"] = ModalFooter; +},{}],16:[function(_dereq_,module,exports){ +"use strict"; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var Modal = _dereq_("./modal")["default"] || _dereq_("./modal"); + +/** + * A flavour of a {{#crossLink "Modal}}Modal{{/crossLink}} that handles form submission right. + * @class ModalForm + */ +var ModalForm; + +ModalForm = Modal.extend({ + tagName: 'form', + attributeBindings: ['in-async'], + 'in-async': null, + 'close-if-error': false, + submitted: false, + error: null, + + /** + * Handle form submit event. + * Submit the form, if the event returns a promise, then wait for the promise to be fulfilled first before + * closing the modal, if the promise returned an error, then the `error` property will be set with the given error object of the + * promise, when error occurs, the modal will only get closed if the `close-if-error` property isn't set to false + * + * @method submitForm + * @private + */ + submitForm: (function(e) { + e.preventDefault(); + this.sendAction('on-submit', this, e); + this.set('submitted', true); + if (e.promise && "function" === typeof e.promise.then) { + this.set('in-async', 'true'); + return e.promise.then((function(_this) { + return function(r) { + _this.set('in-async', null); + return _this.close(); + }; + })(this), (function(_this) { + return function(err) { + _this.set('in-async', null); + _this.set('error', err); + if (_this.get('close-if-error')) { + return _this.close(); + } + }; + })(this)); + } else { + return this.close(); + } + }).on('submit'), + close: function() { + this.set('error', null); + if (!this.get('submitted')) { + this.sendAction('on-cancel', this); + } + return this._super.apply(this, arguments); + } +}); + +exports["default"] = ModalForm; +},{"./modal":20}],17:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var ModalTitle, StyleBindingsMixin, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * `{{em-modal-title}}` component. + * + * The title of the modal + * + * @class ModalTitle + * @public + */ + +ModalTitle = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.titleClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * Register the title within the modal + * Note: Expects this title to be the direct descendant of the modal component + * + * @method registerInModal + * @private + */ + registerInModal: function() { + return (this.get('parentView').setTitle(this)).on('init'); + } +}); + +exports["default"] = ModalTitle; +},{}],18:[function(_dereq_,module,exports){ +"use strict"; +exports["default"] = Ember.Handlebars.compile("{{#if is-open}}\n
\n
\n {{yield}}\n
\n
\n{{/if}}"); +},{}],19:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; +var View = window.Ember.View; +var Modal = _dereq_("./modal")["default"] || _dereq_("./modal"); +var ModalToggler, StyleBindingsMixin, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * `{{em-modal-toggler}}` component. + * + * A component to toggle the visibility of a modal + * + * @class ModalToggler + * @event on-toggle triggered when the toggler is clicked before changing the visibility of the modal + * @param toggler Toggler - This instance of the toggler + * @public + */ + +ModalToggler = Component.extend(WithConfigMixin, StyleBindingsMixin, { + tagName: 'button', + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.togglerClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * Toggle the visibility of the modal that this toggler controls. + * + * @method toggleVisibility + * @private + */ + toggleVisibility: (function() { + this.sendAction('on-toggle', this); + return this.get('modal').toggleVisibility(); + }).on('click'), + + /** + * Find the modal view and set it as a `modal` property + * A toggler can live as a descendant (not neccessarily a direct one) of a modal or outside of the modal chain + * TODO: Assert modal existance + * @method modalAsProperty + */ + modalAsProperty: (function() { + var modalAsAncestor; + modalAsAncestor = this.nearestOfType(Modal); + if (modalAsAncestor) { + return this.set('modal', modalAsAncestor); + } else { + return run.schedule('afterRender', this, function() { + return this.set('modal', View.views[this.get('modal-id')]); + }); + } + }).on('willInsertElement') +}); + +exports["default"] = ModalToggler; +},{"./modal":20}],20:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var run = window.Ember.run; + +var ModalComponent, StyleBindingsMixin, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * `{{em-modal}}` component. + * + * Define a modal component that can be opened and closed, the modal visibility is controlled by the + * {{#crossLink "ModalToggler"}}ModalToggler{{/crossLink}} component. + * + * ```handlebars + * {{#em-modal id="modal1"}} + * {{#em-modal-title}} + * {{#em-modal-toggler}}×{{/em-modal-toggler}} + * + * {{/em-modal-title}} + * {{#em-modal-body}} + * One fine body… + * {{/em-modal-body}} + * {{#em-modal-footer}} + * {{#em-modal-toggler}}Close{{/em-modal-toggler}} + * {{/em-modal-footer}} + * {{/em-modal}} + * {{#em-modal-toggler modal-id="modal1"}}Click me!{{/em-modal-toggler}} + * ``` + * + * @class Modal + * @event will-open + * @event did-open + * @event will-close + * @public + */ + +ModalComponent = Component.extend(WithConfigMixin, StyleBindingsMixin, { + layoutName: 'em-modal', + + /** + * Properties bound as attributes the DOM element. + * see documentation per property. + * @property panels + * @private + * @type Array + */ + attributeBindings: ['is-open', 'did-open', 'tabindex'], + classNameBindings: ['styleClasses', 'styleOpenningClasses'], + styleBindings: ['display'], + + /** + * Define the tabindex DOM property. + * Required otherwise no keyDown events + * @property tabindex + */ + tabindex: 0, + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.classes')) != null ? _ref.join(" ") : void 0; + }).property('config.modal.classes'), + + /** + * The class name that will be set when the modal gets opened + * @property styleOpenningClasses + * @public + */ + styleOpenningClasses: (function() { + if (this.get('did-open')) { + return "in"; + } else { + return ""; + } + }).property('did-open'), + + /* + * The CSS `display` property state. + * @property display + * @public + */ + display: (function() { + if (this.get('did-open')) { + return 'block'; + } else { + return 'none'; + } + }).property('did-open'), + + /** + * `show` property is bound to the DOM element as an attribute. + * This property is set to true immediately when the `toggleVisibility` method is invoked. + * + * This property can be used to start a transitioning effect, for example: + * ```css + * em-modal[show] { + * opacity: 0; + * transition: opacity 100ms ease; + * } + * ``` + * + * The transition effect should be ended when the modal is gets visible, see the property `shown` for more info. + * @property opened + * @see 'did-open' + * @private + */ + 'is-open': false, + + /** + * A property bound to the DOM element that indicates that the modal has been made visible to the user. + * (after the DOM element was set with `display: block;`) + * + * This proeprty can be used by CSS to end a transitioning effect by setting the CSS `opacity` to a higher number, for example: + * + * ```css + * em-modal[shown] { + * opacity: 1; + * } + } + * ``` + * @property did-open + * @private + */ + 'did-open': false, + + /** + * Open modal and make it visible. + * @method open + * @public + */ + open: function() { + this.trigger('show'); + this.sendAction('show', this); + this.set('is-open', 'true'); + return run.schedule('afterRender', this, function() { + this.set('did-open', 'true'); + return this.trigger('shown'); + }); + }, + + /** + * Close the modal by making it invisible. + * @method close + * @public + */ + close: function() { + this.trigger('hide'); + this.sendAction('hide', this); + this.set('is-open', void 0); + return this.set('did-open', void 0); + }, + + /** + * Toggle the visibility of the modal based on its current state. + * @method toggleVisibility + * @public + */ + toggleVisibility: function() { + if (this.get('is-open')) { + return this.close(); + } else { + return this.open(); + } + }, + + /** + * Set the title of the modal. + * @method setTitle + * @private + * @type ModalTitle + */ + setTitle: function(title) { + return this.set('title', title); + }, + + /** + * Set the toggler of the modal + * @method setToggler + * @private + * @type ModalToggler + */ + setToggler: function(toggler) { + return this.set('toggler', toggler); + }, + + /** + * Close the modal if the user clicks outside of the modal space. + * @method closeIfClickedOutside + * @private + */ + closeIfClickedOutside: (function(e) { + if (e.target !== this.get('element')) { + return; + } + return this.close(); + }).on('click'), + + /** + * Handle keyboard events + * @method handleKeyboard + * @private + */ + handleKeyboard: (function(e) { + switch (e.keyCode) { + case 27: + return this.close(); + } + }).on('keyDown'), + + /** + * Consumer can bind this property for a more fine grained control over when the modal is opened, + * This is good for situations where openning the modal via the `toggler` is not enough. + * + * @property open-if + * @public + */ + 'open-if': false, + + /** + * observers the `open-if` property, if set to true, then open the modal. + * @method openIf + * @private + */ + openIf: (function() { + if (!this.get('open-if')) { + return; + } + this.open(); + return this.set('open-if', false); + }).observes('open-if'), + + /** + * Consumer can bind this property for a more fine grained control over when the modal is closed, + * This is good for situations where closing the modal via the `toggler` is not enough. + * + * @property close-if + * @public + */ + 'close-if': false, -Application.initializer({ - name: 'em-components', - initialize: function(c) { - var Config; - Em.EmberComponents = Namespace.create({ - VERSION: '0.0.1' - }); - Em.Config = Config = Em.Eu.Config.create(); - Config.addConfig('default', { - tabs: { - tabsTag: ['div'], - tabTag: ['li'], - tabListTag: ['ul'] - }, - tree: { - branchClasses: ['em-tree-branch', 'fa-ul'], - nodeClasses: ['em-tree-node'], - nodeOpenClasses: [], - nodeCloseClasses: [], - nodeOpenIconClasses: ['fa-li', 'fa', 'fa-minus-square-o'], - nodeCloseIconClasses: ['fa-li', 'fa', 'fa-plus-square-o'], - nodeLeafClasses: ['leaf'], - nodeLeafIconClasses: ['fa-li', 'fa', 'fa-square-o'], - nodeLoadingIconClasses: ['fa-li', 'fa', 'fa-spinner', 'fa-spin'], - nodeSelectedClasses: ['em-tree-node-active'] - } - }); - Config.addConfig('classic', { - tabs: { - tabsClasses: ['em-tabs'], - tabClasses: ['em-tab'], - tabListClasses: ['em-tab-list'], - tabPanelClasses: ['em-tab-panel'] - } - }); - Config.addConfig('bs', { - tabs: { - tabListClasses: ['nav', 'nav-tabs'], - tabSelectedClasses: ['active'] - }, - wysiwyg: { - classes: ['well'], - toolbarClasses: ['btn-toolbar'], - actionGroupClasses: ['btn-group'], - actionClasses: ['btn btn-default'], - actionActiveClasses: ['active'] - }, - accordion: { - classes: ['panel-group'], - itemClasses: ['panel', 'panel-default'], - itemSelectedClasses: ['active'], - panelHeaderClasses: ['panel-heading'], - panelTitleClasses: ['panel-title'], - panelTogglerClasses: ['accordion-toggle'], - panelBodyContainerClasses: ['panel-collapse', 'collapse'], - panelBodyClasses: ['panel-body'] - } - }); - Config.addConfig('foundation', { - tabs: { - tabListClasses: ['tabs'], - tabSelectedClasses: ['active'], - tabClasses: ['tab-title'], - tabPanelClasses: ['content'] - } - }); - Em.EmberComponents.Config = Em.Config = Config; - c.register('component:em-tabs', TabsComponent); - c.register('template:components/em-tabs-css', TabsStyle); - c.register('component:em-tab-list', TabListComponent); - c.register('component:em-tab', TabComponent); - c.register('component:em-tab-panel', TabPanelComponent); - c.register('component:em-wysiwyg', WysiwygComponent); - c.register('component:em-wysiwyg-toolbar', WysiwygToolbarComponent); - c.register('component:em-wysiwyg-action-group', WysiwygActionGroupComponent); - c.register('component:em-wysiwyg-action', WysiwygActionComponent); - c.register('template:em-wysiwyg-action', WysiwygActionTmpl); - c.register('component:em-wysiwyg-editor', WysiwygEditorComponent); - c.register('component:em-accordion', AccordionComponent); - c.register('component:em-accordion-item', AccordionItemComponent); - c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); - c.register('component:em-tree-node', TreeNodeComponent); - c.register('template:em-tree-node', TreeNodeTmpl); - c.register('component:em-tree-branch', TreeBranchComponent); - c.register('template:em-tree-branch', TreeBranchTmpl); - c.register('template:components/em-tree-branch-css', TreeBranchStyle); - c.register('component:em-list', ListComponent); - return c.register('component:em-list-item', ListItemComponent); - } + /** + * observers the `close-if` property, if set to true, then close the modal. + * @method closeIf + * @private + */ + closeIf: (function() { + if (!this.get('close-if')) { + return; + } + this.close(); + return this.set('close-if', false); + }).observes('close-if') }); -exports.TabsComponent = TabsComponent; -exports.TabListComponent = TabListComponent; -exports.TabComponent = TabComponent; -exports.TabPanelComponent = TabPanelComponent; -exports.WysiwygComponent = WysiwygComponent; -exports.WysiwygToolbarComponent = WysiwygToolbarComponent; -exports.WysiwygActionGroupComponent = WysiwygActionGroupComponent; -exports.WysiwygActionComponent = WysiwygActionComponent; -exports.WysiwygEditorComponent = WysiwygEditorComponent; -exports.AccordionComponent = AccordionComponent; -exports.AccordionItemComponent = AccordionItemComponent; -exports.TreeNodeComponent = TreeNodeComponent; -exports.TreeBranchComponent = TreeBranchComponent; -exports.TreeNode = TreeNode; -exports.ListComponent = ListComponent; -exports.ListItemComponent = ListItemComponent; -},{"./accordion/accordion":3,"./accordion/accordion-item":2,"./accordion/accordion-item-tmpl":1,"./list/list":6,"./list/list-item":5,"./tabs/tab":10,"./tabs/tab-list":8,"./tabs/tab-panel":9,"./tabs/tabs":12,"./tabs/tabs-css":11,"./tree/node":13,"./tree/tree-branch":16,"./tree/tree-branch-css":14,"./tree/tree-branch-tmpl":15,"./tree/tree-node":18,"./tree/tree-node-tmpl":17,"./wysiwyg/action":20,"./wysiwyg/action-group":19,"./wysiwyg/actiontmpl":21,"./wysiwyg/editor":22,"./wysiwyg/toolbar":23,"./wysiwyg/wysiwyg":24}],8:[function(_dereq_,module,exports){ +exports["default"] = ModalComponent; +},{}],21:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -758,7 +1586,7 @@ TabList = Component.extend(WithConfigMixin, { }); exports["default"] = TabList;; -},{}],9:[function(_dereq_,module,exports){ +},{}],22:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -828,7 +1656,7 @@ TabPanel = Component.extend(WithConfigMixin, StyleBindingsMixin, { }); exports["default"] = TabPanel;; -},{}],10:[function(_dereq_,module,exports){ +},{}],23:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -958,10 +1786,10 @@ Tab = Component.extend(WithConfigMixin, { }); exports["default"] = Tab;; -},{}],11:[function(_dereq_,module,exports){ +},{}],24:[function(_dereq_,module,exports){ "use strict"; exports["default"] = Ember.Handlebars.compile(".em-tabs, .em-tab-list, .em-tab-panel {\n display: block;\n}\n\n.em-tab-list {\n border-bottom: 1px solid #eee;\n}\n\n.em-tab {\n display: inline-block;\n padding: 6px 12px;\n border: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n cursor: pointer;\n margin-bottom: -1px;\n position: relative;\n}\n\n.em-tab[active=true] {\n border-color: #eee;\n border-bottom-color: #fff;\n}"); -},{}],12:[function(_dereq_,module,exports){ +},{}],25:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -1098,10 +1926,10 @@ Tabs = Component.extend(WithConfigMixin, StyleBindingsMixin, { }); exports["default"] = Tabs;; -},{}],13:[function(_dereq_,module,exports){ +},{}],26:[function(_dereq_,module,exports){ "use strict"; var Ember = window.Ember["default"] || window.Ember; -var Node; +var Node, findChildrenOfNodeBy; Node = Ember.Object.extend({ children: void 0, @@ -1162,17 +1990,36 @@ Node = Ember.Object.extend({ }).property('children.length'), isLevel1: (function() { return this.get('level') === 0; - }).property('children.length') + }).property('children.length'), + findChildBy: function(key, name) { + return findChildrenOfNodeBy(this, key, name); + } }); exports["default"] = Node; -},{}],14:[function(_dereq_,module,exports){ -"use strict"; -exports["default"] = Ember.Handlebars.compile(".em-tree-node {\n cursor: pointer;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.em-tree-node-active {\n background: #e7e7e7;\n}"); -},{}],15:[function(_dereq_,module,exports){ + +findChildrenOfNodeBy = function(currChild, key, value) { + var c, _i, _len, _ref, _ref1; + if (currChild.get(key) === value) { + return currChild; + } else if (((_ref = currChild.get('children')) != null ? _ref.length : void 0) > 0) { + _ref1 = currChild.get('children'); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + c = _ref1[_i]; + if (c.get(key) === value) { + return c; + } else { + findChildrenOfNodeBy(c, key, value); + } + } + return null; + } + return null; +}; +},{}],27:[function(_dereq_,module,exports){ "use strict"; -exports["default"] = Ember.Handlebars.compile("{{#each nodes}}\n {{em-tree-node node=this async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); -},{}],16:[function(_dereq_,module,exports){ +exports["default"] = Ember.Handlebars.compile("{{#each children}}\n {{em-tree-node model=this tree=view.tree async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); +},{}],28:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -1192,20 +2039,15 @@ WithConfigMixin = Em.Eu.WithConfigMixin; TreeBranch = Component.extend(WithConfigMixin, { /** - * The node to render its children within this branch - * this property is expected to be defined by the user - */ - node: void 0, - - /** - * The root node of the tree + * The model to render its children within this branch + * this property is set during component markup creation */ - rootNode: computed.alias('node.root'), + model: void 0, /** * A list of {{#crossLink "TreeNode"}}nodes{{/crossLink}} instances. */ - nodes: computed.alias('node.children'), + children: computed.alias('model.children'), /** * True if node's children should be loaded asynchronously @@ -1223,10 +2065,111 @@ TreeBranch = Component.extend(WithConfigMixin, { }); exports["default"] = TreeBranch;; -},{}],17:[function(_dereq_,module,exports){ +},{}],29:[function(_dereq_,module,exports){ "use strict"; -exports["default"] = Ember.Handlebars.compile("{{#if hasIcon}}\n \n{{else}}\n *\n{{/if}}\n\n{{node.title}}\n\n{{#if expanded}}\n {{em-tree-branch node=node async=async targetObject=targetObject}}\n{{/if}}"); -},{}],18:[function(_dereq_,module,exports){ +exports["default"] = Ember.Handlebars.compile(".em-tree-node {\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.em-tree-node-active {\n background: #e7e7e7;\n}\n\nli.em-tree-node > span {\n cursor: pointer;\n}\n\nli.em-tree-node > span > span.actions {\n visibility: hidden;\n}\n\nli.em-tree-node > span:hover > span.actions {\n visibility: visible;\n}"); +},{}],30:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var computed = window.Ember.computed; + +var StyleBindingsMixin, TreeNodeIconAction, WithConfigMixin; + +WithConfigMixin = Em.Eu.WithConfigMixin; + +StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + +/** + * An icon action of a tree node + * @class TreeNodeIconAction + */ + +TreeNodeIconAction = Component.extend(WithConfigMixin, StyleBindingsMixin, { + attributeBindings: ['stickyMode:sticky'], + + /** + * The tag name of the icon action, + * default is `` but can be replaced with any tag. + * @property tagName + * @public + */ + tagName: 'i', + + /** + * Bind the visibility css property, + * this is required for the `sticky` property + * @property styleBindings + * @private + */ + styleBindings: 'visibility', + + /** + * Defines the css visibility according to the value of the `sticky` property + * @property visibility + * @private + */ + visibility: (function() { + if (this.get('sticky')) { + return 'visible'; + } else { + return void 0; + } + }).property('sticky'), + + /** + * 'true' if the action icon should be sticky and not disappear when item is not hovered + * @property sticky + * @public + */ + sticky: false, + stickyMode: (function() { + if (this.get('sticky')) { + return 'true'; + } else { + return void 0; + } + }).property('sticky'), + + /** + * Binds the specified css classes + * @property classNameBindings + * @private + */ + classNameBindings: ['iconClasses'], + + /** + * Set the given array of classes + * @property iconClasses + * @private + */ + iconClasses: (function() { + var _ref; + return (_ref = this.get('meta.classes')) != null ? _ref.join(" ") : void 0; + }).property('meta.classes'), + + /** + * An alias to the node model of this action + * @property node + * @public + */ + node: computed.alias('parentView.node'), + + /** + * Invoked when the action is clicked + * @method invokde + */ + invoked: (function() { + return this.get('parentView.targetObject').send(this.get('meta.action'), this); + }).on('click') +}); + +exports["default"] = TreeNodeIconAction; +},{}],31:[function(_dereq_,module,exports){ +"use strict"; +exports["default"] = Ember.Handlebars.compile("\n{{else}}\n *\n{{/if}}\n\n\n{{#if tree.in-multi-selection}}\n \n {{#if multi-selected}}\n \n {{else}}\n \n {{/if}}\n \n{{/if}}\n\n\n{{model.title}}\n{{#if tree.hovered-actions}}\n \n {{#each tree.hovered-actions}}\n {{em-tree-node-icon-action meta=this model=controller.model}}\n {{/each}}\n \n{{/if}}\n\n\n{{#if expanded}}\n {{em-tree-branch model=model tree=tree async=async targetObject=targetObject}}\n{{/if}}"); +},{}],32:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -1244,49 +2187,50 @@ WithConfigMixin = Em.Eu.WithConfigMixin; */ TreeNode = Component.extend(WithConfigMixin, { + attributeBindings: ['multi-selected'], /** - * The node model the tree node view is bound to + * The model the tree node view is bound to */ - node: void 0, + model: void 0, /** - * true if the node of this view is a root node + * A reference to the tree view, this property is auto set during component instantiation */ - isRootNode: computed.not('node.hasParent'), + tree: void 0, /** - * The root node model + * A reference to the root model */ - root: computed.alias('node.root'), + rootModel: computed.alias('tree.model'), /** * True if the node is currently expanded, meaning its children are visible. */ - expanded: false, + expanded: computed.alias('model.expanded'), /** - * True if this node is currently checked - * This is only relevant if the tree configured to support selection + * True if this node view is currently checked + * This is only relevant if the tree configured to support multi selection */ - checked: false, + 'multi-selected': computed.alias('model.selected'), /** - * True if should render an icon tag for this node + * True if should render an icon tag for this node view */ hasIcon: true, /** - * True if nodes can be selected + * True if this node can be single selected */ selectable: true, /** - * True if this node is currently selected + * True if this node is currently single selected */ isSelected: (function() { - return this.get('rootBranchView.selected') === this.get('node'); - }).property('rootBranchView.selected'), + return this.get('tree.selected') === this.get('model'); + }).property('tree.selected'), /** * True if this node is currently loading, @@ -1301,31 +2245,11 @@ TreeNode = Component.extend(WithConfigMixin, { async: computed.alias('parentView.async'), /** - * Get the view of the root node - */ - rootNodeView: (function() { - var view; - if (this.get('isRootNode')) { - return this; - } - view = this.get('parentView'); - while (view) { - if (view.get('isRootNode')) { - return view; - } - view = view.get('parentView'); - } - }).property('node'), - - /** - * The root branch view + * true if this is a leaf node, meaning it has no children */ - rootBranchView: (function() { - return this.get('rootNodeView.parentView'); - }).property('rootNodeView'), leaf: (function() { - return this.get('node.children.length') === 0; - }).property('node.children.length'), + return !this.get('model.children') || this.get('model.children.length') === 0; + }).property('model.children.length'), tagName: 'li', layoutName: 'em-tree-node', classNameBindings: ['styleClasses', 'expandedClasses', 'leafClasses'], @@ -1349,16 +2273,23 @@ TreeNode = Component.extend(WithConfigMixin, { return null; } }).property('isSelected'), + addMultiSelectionToTreeSelection: (function() { + if (this.get('multi-selected')) { + return this.get('tree.multi-selection').pushObject(this.get('model')); + } else { + return this.get('tree.multi-selection').removeObject(this.get('model')); + } + }).observes('multi-selected').on('init'), iconClass: (function() { var icons; icons = []; if (this.get('async')) { if (this.get('loading')) { icons = icons.concat(this.get('config.tree.nodeLoadingIconClasses')); - } else if (!this.get('node.children')) { + } else if (!this.get('model.children')) { icons = icons.concat(this.get('config.tree.nodeCloseIconClasses')); } else { - if (this.get('node.children.length') === 0) { + if (this.get('model.children.length') === 0) { icons = icons.concat(this.get('config.tree.nodeLeafIconClasses')); } else { icons = this.get('expanded') ? icons.concat(this.get('config.tree.nodeOpenIconClasses')) : icons.concat(this.get('config.tree.nodeCloseIconClasses')); @@ -1381,9 +2312,9 @@ TreeNode = Component.extend(WithConfigMixin, { }).property('leaf'), actions: { toggle: function() { - if (this.get('async') && !this.get('expanded') && !this.get('node.children')) { + if (this.get('async') && !this.get('expanded') && !this.get('model.children')) { this.set('loading', true); - return this.sendAction('children', this.get('node'), this); + return this.sendAction('children', this.get('model'), this); } else { return this.toggleProperty('expanded'); } @@ -1392,7 +2323,14 @@ TreeNode = Component.extend(WithConfigMixin, { if (!this.get('selectable')) { return; } - return this.set('rootBranchView.selected', this.get('node')); + return this.set('tree.selected', this.get('model')); + }, + toggleSelection: function() { + if (this.get('multi-selected')) { + return this.set('multi-selected', ''); + } else { + return this.set('multi-selected', 'true'); + } } }, children: 'getChildren', @@ -1404,7 +2342,95 @@ TreeNode = Component.extend(WithConfigMixin, { }); exports["default"] = TreeNode;; -},{}],19:[function(_dereq_,module,exports){ +},{}],33:[function(_dereq_,module,exports){ +"use strict"; +exports["default"] = Ember.Handlebars.compile("{{em-tree-node model=model tree=view async=async targetObject=targetObject}}"); +},{}],34:[function(_dereq_,module,exports){ +"use strict"; +var Component = window.Ember.Component; +var ArrayProxy = window.Ember.ArrayProxy; +var computed = window.Ember.computed; +var A = window.Ember.A; +var Tree, WithConfigMixin, expandTree; + +WithConfigMixin = Em.Eu.WithConfigMixin; + + +/** + * A tree component + * + * @class Tree + */ + +Tree = Component.extend(WithConfigMixin, { + tagName: 'ul', + layoutName: 'em-tree', + classNameBindings: ['styleClasses'], + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.tree.classes')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * The model to render as the root node of the tree + * this property is expected to be defined by the user + */ + model: void 0, + + /** + * True if node's children should be loaded asynchronously + * This gives the opportunity to the user to invoke an async call to the server to retrieve data for the current + * branch being opened + */ + async: false, + 'in-multi-selection': false, + 'multi-selection': A(), + 'selected-icon': 'fa fa-check', + 'unselected-icon': 'fa fa-times', + 'expand-depth': null, + 'auto-expand': false, + expandByDepth: (function() { + var depth; + if (this.get('expand-depth')) { + depth = parseInt(this.get('expand-depth')); + if (depth === 0) { + return; + } + return expandTree(this.get('model'), depth); + } + }).observes('expand-depth') +}); + +exports["default"] = Tree; + +expandTree = function(node, depth) { + var c, children, _i, _len, _results; + if (depth === 0) { + return; + } + node.set('expanded', true); + children = node.get('children'); + if (children && "function" === typeof children.then) { + return children.then((function(_this) { + return function(loadedChildren) { + return loadedChildren.forEach(function(c) { + return expandTree(c, depth - 1); + }); + }; + })(this)); + } else { + if (children.get('length') === 0 || depth === 0) { + return; + } + _results = []; + for (_i = 0, _len = children.length; _i < _len; _i++) { + c = children[_i]; + _results.push(expandTree(c, depth - 1)); + } + return _results; + } +}; +},{}],35:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -1438,7 +2464,7 @@ ActionGroup = Component.extend(WithConfigMixin, { }); exports["default"] = ActionGroup;; -},{}],20:[function(_dereq_,module,exports){ +},{}],36:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -1485,10 +2511,10 @@ Action = Component.extend(WithConfigMixin, { }); exports["default"] = Action;; -},{}],21:[function(_dereq_,module,exports){ +},{}],37:[function(_dereq_,module,exports){ "use strict"; exports["default"] = Ember.Handlebars.compile("{{#if icon}}\n \n{{/if}}\n"); -},{}],22:[function(_dereq_,module,exports){ +},{}],38:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -1559,7 +2585,7 @@ Editor = Component.extend(StyleBindingsMixin, { }); exports["default"] = Editor;; -},{}],23:[function(_dereq_,module,exports){ +},{}],39:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var computed = window.Ember.computed; @@ -1604,7 +2630,7 @@ Toolbar = Component.extend(WithConfigMixin, { }); exports["default"] = Toolbar;; -},{}],24:[function(_dereq_,module,exports){ +},{}],40:[function(_dereq_,module,exports){ "use strict"; var Component = window.Ember.Component; var ArrayProxy = window.Ember.ArrayProxy; @@ -1668,6 +2694,6 @@ Wysiwyg = Component.extend(WithConfigMixin, { }); exports["default"] = Wysiwyg;; -},{}]},{},[7]) -(7) +},{}]},{},[9]) +(9) }); \ No newline at end of file diff --git a/dist/named-amd/main.js b/dist/named-amd/main.js index 94e1579..afe9ecc 100644 --- a/dist/named-amd/main.js +++ b/dist/named-amd/main.js @@ -139,14 +139,12 @@ define("ember-components/accordion/accordion-item", hide: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.removeClass('in'); - return $accordionBody.height($accordionBody.height())[0].offsetHeight; + return $accordionBody.removeClass('in'); }, show: function() { var $accordionBody; $accordionBody = this.$('.panel-collapse'); - $accordionBody.addClass('in'); - return $accordionBody.height($accordionBody[0]['scrollHeight']); + return $accordionBody.addClass('in'); } }); @@ -221,6 +219,163 @@ define("ember-components/accordion/accordion", __exports__["default"] = Accordion;; }); +define("ember-components/button/button-tmpl", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile("{{#if icon-classes}}\n \n{{/if}}\n{{label}}"); + }); +define("ember-components/button/button", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var computed = __dependency1__.computed; + + var Button, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + + /** + * Button component + * + * Styled button with async support. + * + * @class Button + */ + + Button = Component.extend(WithConfigMixin, { + + /** + * The tag name the component is rendered as. + * This theoretically can be a div or anything else. + * @property tagName + * @private + */ + tagName: 'button', + + /** + * The template of the component + * @property layoutName + * @private + */ + layoutName: 'em-button', + + /** + * Bind the specified properties as DOM attributes. + * @property attributeBindings + * @private + */ + attributeBindings: ['disabled', 'state'], + + /** + * Bind the specified properties as the classes of the DOM element. + */ + classNameBindings: ['class'], + + /** + * True if the button is disabled and cannot be clicked. + * @property disabled + * @public + */ + disabled: computed.equal('state', 'executing'), + + /** + * The state of the button, can be one of the following: + * default - The button is enabled and ready to be clicked. + * executing - The promise bound to the button was sent and the promise is still executing + * resolved - The promise was resolved properly. + * rejected - The promise bound to the button was finished as rejected. + * + * The state is also bound to the DOM as `state` property, this allows to easily change styles for every + * state by using `.em-button[state=resolved]` syntax. + * + * The label of the button will change to the value of the component properties that correspond to the + * states mentioned above. + * + * @property state + * @private + */ + state: 'default', + + /** + * The action name to invoke on the controller when the button is clicked. + * @property on-click + * @public + */ + 'on-click': void 0, + + /** + * If set, an icon tag will be added as apart of the button and the given value here will be set + * as the icon's `class` attribute. + * @property icon-classes + * @public + */ + 'icon-classes': (function() { + var propName; + propName = "icon-" + this.state; + return this.getWithDefault(propName, this.get('icon-default')); + }).property('state', 'icon-default', 'icon-executing', 'icon-resolved', 'icon-rejected'), + + /* + * The label of the button, calculated according to the state of the button + * See the `state` property documentation for more info. + * @property label + * @private + */ + label: (function() { + return this.getWithDefault(this.state, this.get('default')); + }).property('state', 'default', 'executing', 'resolved', 'rejected'), + + /** + * Set by the `onClick` callback, if set, the promise will be observed and the button's state will be + * changed accordingly. + * @property promise + * @private + */ + promise: void 0, + + /** + * Triggered when the button is clicked + * Invoke the action name on the controller defined in the `action` property, default is `onClick`. + * The action on the controller recieves a property that should be set to the promise being invoked (if there is one) + * If a promise was set, the button will move to 'executing' state until the promise will be resolved + * @method onClick + * @private + */ + onClick: (function() { + this.sendAction('on-click', (function(_this) { + return function(promise) { + _this.set('promise', promise); + return _this.set('state', 'executing'); + }; + })(this)); + return false; + }).on('click'), + + /* + * Observes the promise property + * @property changeStateByPromise + * @private + */ + changeStateByPromise: (function() { + return this.get('promise').then((function(_this) { + return function() { + return _this.set('state', 'resolved'); + }; + })(this), (function(_this) { + return function(err) { + _this.set('state', 'rejected'); + return _this.set('error', err); + }; + })(this)); + }).observes('promise') + }); + + __exports__["default"] = Button; + }); define("ember-components/list/as-item", ["ember","exports"], function(__dependency1__, __exports__) { @@ -397,6 +552,7 @@ define("ember-components/list/list", List = Component.extend(WithConfigMixin, { tagName: 'ul', + attributeBindings: ['style'], classNameBindings: ['styleClasses'], styleClasses: (function() { var _ref; @@ -411,6 +567,11 @@ define("ember-components/list/list", */ selected: void 0, + /** + * True if this list supports selection + */ + selection: true, + /** * List can be bound to models, models can be a property or an object that the list is bound to. * When model changes, the list will give an opportunity to every item within the list to react upon the model change, @@ -472,24 +633,28 @@ define("ember-components/list/list", */ select: function(item) { var _ref; - if (!item || this.get('selected') === item) { - return; - } - Em.debug("Selecting tab: " + (item.get('index'))); - if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { - this.get('selected').sendAction('on-deselect', this.get('selected')); + if (!this.get('selection')) { + return item.sendAction('on-click', item); + } else { + if (!item || this.get('selected') === item) { + return; + } + Em.debug("Selecting tab: " + (item.get('index'))); + if ((_ref = this.get('selected')) != null ? _ref.sendAction : void 0) { + this.get('selected').sendAction('on-deselect', this.get('selected')); + } + this.set('selected', item); + this.get('selected').sendAction('on-select', this.get('selected')); + this.set('selected-idx', item.get('index')); + return this.get('items').forEach((function(_this) { + return function(i) { + if (_this.get('selected') === i) { + return; + } + return i.sendAction('on-selection-change', i, _this.get('selected')); + }; + })(this)); } - this.set('selected', item); - this.get('selected').sendAction('on-select', this.get('selected')); - this.set('selected-idx', item.get('index')); - return this.get('items').forEach((function(_this) { - return function(i) { - if (_this.get('selected') === i) { - return; - } - return i.sendAction('on-selection-change', i, _this.get('selected')); - }; - })(this)); }, notifyModelsChange: (function() { return run.next(this, function() { @@ -512,8 +677,8 @@ define("ember-components/list/list", __exports__["default"] = List; }); define("ember-components", - ["./tabs/tabs","./tabs/tabs-css","./tabs/tab-list","./tabs/tab","./tabs/tab-panel","./wysiwyg/wysiwyg","./wysiwyg/toolbar","./wysiwyg/action-group","./wysiwyg/action","./wysiwyg/actiontmpl","./wysiwyg/editor","./accordion/accordion","./accordion/accordion-item","./accordion/accordion-item-tmpl","./tree/node","./tree/tree-node","./tree/tree-node-tmpl","./tree/tree-branch","./tree/tree-branch-tmpl","./tree/tree-branch-css","./list/list","./list/list-item","ember","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __exports__) { + ["./tabs/tabs","./tabs/tabs-css","./tabs/tab-list","./tabs/tab","./tabs/tab-panel","./wysiwyg/wysiwyg","./wysiwyg/toolbar","./wysiwyg/action-group","./wysiwyg/action","./wysiwyg/actiontmpl","./wysiwyg/editor","./accordion/accordion","./accordion/accordion-item","./accordion/accordion-item-tmpl","./tree/tree","./tree/tree-tmpl","./tree/tree-css","./tree/node","./tree/tree-node","./tree/tree-node-tmpl","./tree/tree-node-icon-action","./tree/tree-branch","./tree/tree-branch-tmpl","./list/list","./list/list-item","./modal/modal","./modal/modal-css","./modal/modal-form","./modal/modal-emform","./modal/modal-title","./modal/modal-body","./modal/modal-footer","./modal/modal-toggler","./modal/modal-tmpl","./modal/modal-confirm","./modal/modal-confirm-tmpl","./button/button","./button/button-tmpl","ember","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __dependency34__, __dependency35__, __dependency36__, __dependency37__, __dependency38__, __dependency39__, __exports__) { "use strict"; var TabsComponent = __dependency1__["default"] || __dependency1__; @@ -537,130 +702,832 @@ define("ember-components", var WysiwygEditorComponent = __dependency11__["default"] || __dependency11__; - var AccordionComponent = __dependency12__["default"] || __dependency12__; + var AccordionComponent = __dependency12__["default"] || __dependency12__; + + var AccordionItemComponent = __dependency13__["default"] || __dependency13__; + + var AccordionItemTmpl = __dependency14__["default"] || __dependency14__; + + var TreeComponent = __dependency15__["default"] || __dependency15__; + var TreeTmpl = __dependency16__["default"] || __dependency16__; + var TreeStyle = __dependency17__["default"] || __dependency17__; + var TreeNode = __dependency18__["default"] || __dependency18__; + var TreeNodeComponent = __dependency19__["default"] || __dependency19__; + var TreeNodeTmpl = __dependency20__["default"] || __dependency20__; + var TreeNodeIconAction = __dependency21__["default"] || __dependency21__; + var TreeBranchComponent = __dependency22__["default"] || __dependency22__; + var TreeBranchTmpl = __dependency23__["default"] || __dependency23__; + var ListComponent = __dependency24__["default"] || __dependency24__; + var ListItemComponent = __dependency25__["default"] || __dependency25__; + var ModalComponent = __dependency26__["default"] || __dependency26__; + var ModalCss = __dependency27__["default"] || __dependency27__; + var ModalFormComponent = __dependency28__["default"] || __dependency28__; + var ModalEmFormComponent = __dependency29__["default"] || __dependency29__; + var ModalTitleComponent = __dependency30__["default"] || __dependency30__; + var ModalBodyComponent = __dependency31__["default"] || __dependency31__; + var ModalFooterComponent = __dependency32__["default"] || __dependency32__; + var ModalTogglerComponent = __dependency33__["default"] || __dependency33__; + var ModalTmpl = __dependency34__["default"] || __dependency34__; + var ModalConfirmComponent = __dependency35__["default"] || __dependency35__; + var ModalConfirmTmpl = __dependency36__["default"] || __dependency36__; + var ButtonComponent = __dependency37__["default"] || __dependency37__; + var ButtonTmplComponent = __dependency38__["default"] || __dependency38__; + var Application = __dependency39__.Application; + var Namespace = __dependency39__.Namespace; + + Application.initializer({ + name: 'em-components', + initialize: function(c) { + var Config; + Em.EmberComponents = Namespace.create({ + VERSION: '0.0.1' + }); + Em.Config = Config = Em.Eu.Config.create(); + Config.addConfig('default', { + tabs: { + tabsTag: ['div'], + tabTag: ['li'], + tabListTag: ['ul'] + }, + tree: { + classes: ['em-tree-branch', 'em-tree', 'fa-ul'], + branchClasses: ['em-tree-branch', 'fa-ul'], + nodeClasses: ['em-tree-node'], + nodeOpenClasses: [], + nodeCloseClasses: [], + nodeOpenIconClasses: ['fa-li', 'fa', 'fa-minus-square-o'], + nodeCloseIconClasses: ['fa-li', 'fa', 'fa-plus-square-o'], + nodeLeafClasses: ['leaf'], + nodeLeafIconClasses: ['fa-li', 'fa', 'fa-square-o'], + nodeLoadingIconClasses: ['fa-li', 'fa', 'fa-spinner', 'fa-spin'], + nodeSelectedClasses: ['em-tree-node-active'] + } + }); + Config.addConfig('classic', { + tabs: { + tabsClasses: ['em-tabs'], + tabClasses: ['em-tab'], + tabListClasses: ['em-tab-list'], + tabPanelClasses: ['em-tab-panel'] + } + }); + Config.addConfig('bs', { + tabs: { + tabListClasses: ['nav', 'nav-tabs'], + tabSelectedClasses: ['active'] + }, + wysiwyg: { + classes: ['well'], + toolbarClasses: ['btn-toolbar'], + actionGroupClasses: ['btn-group'], + actionClasses: ['btn btn-default'], + actionActiveClasses: ['active'] + }, + accordion: { + classes: ['panel-group'], + itemClasses: ['panel', 'panel-default'], + itemSelectedClasses: ['active'], + panelHeaderClasses: ['panel-heading'], + panelTitleClasses: ['panel-title'], + panelTogglerClasses: ['accordion-toggle'], + panelBodyContainerClasses: ['panel-collapse', 'collapse'], + panelBodyClasses: ['panel-body'] + }, + modal: { + classes: ['em-modal', 'modal', 'fade'], + bodyClasses: ['modal-body'], + titleClasses: ['modal-header'], + footerClasses: ['modal-footer'] + } + }); + Config.addConfig('foundation', { + tabs: { + tabListClasses: ['tabs'], + tabSelectedClasses: ['active'], + tabClasses: ['tab-title'], + tabPanelClasses: ['content'] + } + }); + Em.EmberComponents.Config = Em.Config = Config; + c.register('component:em-tabs', TabsComponent); + c.register('template:components/em-tabs-css', TabsStyle); + c.register('component:em-tab-list', TabListComponent); + c.register('component:em-tab', TabComponent); + c.register('component:em-tab-panel', TabPanelComponent); + c.register('component:em-wysiwyg', WysiwygComponent); + c.register('component:em-wysiwyg-toolbar', WysiwygToolbarComponent); + c.register('component:em-wysiwyg-action-group', WysiwygActionGroupComponent); + c.register('component:em-wysiwyg-action', WysiwygActionComponent); + c.register('template:em-wysiwyg-action', WysiwygActionTmpl); + c.register('component:em-wysiwyg-editor', WysiwygEditorComponent); + c.register('component:em-accordion', AccordionComponent); + c.register('component:em-accordion-item', AccordionItemComponent); + c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); + c.register('component:em-tree', TreeComponent); + c.register('template:em-tree', TreeTmpl); + c.register('component:em-tree-node', TreeNodeComponent); + c.register('template:em-tree-node', TreeNodeTmpl); + c.register('component:em-tree-node-icon-action', TreeNodeIconAction); + c.register('component:em-tree-branch', TreeBranchComponent); + c.register('template:em-tree-branch', TreeBranchTmpl); + c.register('template:components/em-tree-css', TreeStyle); + c.register('component:em-list', ListComponent); + c.register('component:em-list-item', ListItemComponent); + c.register('component:em-modal', ModalComponent); + c.register('template:components/em-modal-css', ModalCss); + c.register('component:em-modal-form', ModalFormComponent); + c.register('component:em-modal-emform', ModalEmFormComponent); + c.register('component:em-modal-title', ModalTitleComponent); + c.register('component:em-modal-body', ModalBodyComponent); + c.register('component:em-modal-footer', ModalFooterComponent); + c.register('component:em-modal-toggler', ModalTogglerComponent); + c.register('template:em-modal', ModalTmpl); + c.register('component:em-modal-confirm', ModalConfirmComponent); + c.register('template:em-modal-confirm', ModalConfirmTmpl); + c.register('component:em-button', ButtonComponent); + return c.register('template:em-button', ButtonTmplComponent); + } + }); + + __exports__.TabsComponent = TabsComponent; + __exports__.TabListComponent = TabListComponent; + __exports__.TabComponent = TabComponent; + __exports__.TabPanelComponent = TabPanelComponent; + __exports__.WysiwygComponent = WysiwygComponent; + __exports__.WysiwygToolbarComponent = WysiwygToolbarComponent; + __exports__.WysiwygActionGroupComponent = WysiwygActionGroupComponent; + __exports__.WysiwygActionComponent = WysiwygActionComponent; + __exports__.WysiwygEditorComponent = WysiwygEditorComponent; + __exports__.AccordionComponent = AccordionComponent; + __exports__.AccordionItemComponent = AccordionItemComponent; + __exports__.TreeComponent = TreeComponent; + __exports__.TreeNodeComponent = TreeNodeComponent; + __exports__.TreeBranchComponent = TreeBranchComponent; + __exports__.TreeNode = TreeNode; + __exports__.TreeNodeIconAction = TreeNodeIconAction; + __exports__.ListComponent = ListComponent; + __exports__.ListItemComponent = ListItemComponent; + __exports__.ModalComponent = ModalComponent; + __exports__.ModalTitleComponent = ModalTitleComponent; + __exports__.ModalBodyComponent = ModalBodyComponent; + __exports__.ModalFooterComponent = ModalFooterComponent; + __exports__.ModalTogglerComponent = ModalTogglerComponent; + __exports__.ModalConfirmComponent = ModalConfirmComponent; + __exports__.ModalFormComponent = ModalFormComponent; + __exports__.ModalEmFormComponent = ModalEmFormComponent; + __exports__.ButtonComponent = ButtonComponent; + }); +define("ember-components/modal/modal-body", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var ModalBody, StyleBindingsMixin, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * `{{em-modal-body}}` component. + * + * The body of the modal + * + * @class ModalBody + * @public + */ + + ModalBody = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.bodyClasses')) != null ? _ref.join(" ") : void 0; + }).property() + }); + + __exports__["default"] = ModalBody; + }); +define("ember-components/modal/modal-confirm-tmpl", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile("{{#em-modal id=confirm-id configName=configName model-id=model-id open-if=open-if close-if=close-if}}\n {{#em-modal-title}}\n {{#em-modal-toggler class=\"close\"}}×Close{{/em-modal-toggler}}\n

{{title}}

\n {{/em-modal-title}}\n {{#em-modal-body}}\n {{message}}\n {{/em-modal-body}}\n {{#em-modal-footer}}\n \n {{#em-modal-toggler class=\"btn btn-default\"}}No{{/em-modal-toggler}}\n {{/em-modal-footer}}\n{{/em-modal}}"); + }); +define("ember-components/modal/modal-confirm", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + + /** + * A confirmation modal with 'Yes' & 'No' buttons + * When 'no' is pressed the modal is just closed. + * When 'yes' is pressed an action bound to the action on the controller set in the `confirm` property is invoked, + * giving the controller a chance to decide whether to close the modal or not. + * + * @class ModalConfirm + */ + var ModalConfirm; + + ModalConfirm = Component.extend({ + layoutName: 'em-modal-confirm', + + /** + * Bound to the action on the controller to be invoked when the 'yes' button is pressed. + * @property confirm + * @public + */ + confirm: "confirm", + + /** + * The default title of the modal if not set otherwise. + * + * @property title + * @public + */ + title: 'Please confirm', + + /** + * The default message of the modal if not set otherwise. + * + * @property message + * @public + */ + message: 'Please press Yes to confirm the operation.', + actions: { + + /** + * Invoked when the user clicks the "Yes" button, triggers an action on the controller. + * + * @method confirmPressed + * @private + */ + confirmPressed: function() { + return this.sendAction('confirm'); + } + } + }); + + __exports__["default"] = ModalConfirm; + }); +define("ember-components/modal/modal-css", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile(".em-modal {\n background-color: hsla(0, 0%, 100%, .85);\n}"); + }); +define("ember-components/modal/modal-emform", + ["ember","./modal-form","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var FormModal = __dependency2__["default"] || __dependency2__; + var EmModalForm; + + EmModalForm = FormModal.extend({ + classNameBindings: ['form'], + attributeBindings: ['role'], + role: 'form', + model: void 0, + submit_button: false + }); + + __exports__["default"] = EmModalForm; + }); +define("ember-components/modal/modal-footer", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var ModalFooter, StyleBindingsMixin, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * `{{em-modal-footer}}` component. + * + * The footer of the modal + * + * @class ModalFooter + * @public + */ + + ModalFooter = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.footerClasses')) != null ? _ref.join(" ") : void 0; + }).property() + }); + + __exports__["default"] = ModalFooter; + }); +define("ember-components/modal/modal-form", + ["ember","./modal","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var Modal = __dependency2__["default"] || __dependency2__; + + /** + * A flavour of a {{#crossLink "Modal}}Modal{{/crossLink}} that handles form submission right. + * @class ModalForm + */ + var ModalForm; + + ModalForm = Modal.extend({ + tagName: 'form', + attributeBindings: ['in-async'], + 'in-async': null, + 'close-if-error': false, + submitted: false, + error: null, + + /** + * Handle form submit event. + * Submit the form, if the event returns a promise, then wait for the promise to be fulfilled first before + * closing the modal, if the promise returned an error, then the `error` property will be set with the given error object of the + * promise, when error occurs, the modal will only get closed if the `close-if-error` property isn't set to false + * + * @method submitForm + * @private + */ + submitForm: (function(e) { + e.preventDefault(); + this.sendAction('on-submit', this, e); + this.set('submitted', true); + if (e.promise && "function" === typeof e.promise.then) { + this.set('in-async', 'true'); + return e.promise.then((function(_this) { + return function(r) { + _this.set('in-async', null); + return _this.close(); + }; + })(this), (function(_this) { + return function(err) { + _this.set('in-async', null); + _this.set('error', err); + if (_this.get('close-if-error')) { + return _this.close(); + } + }; + })(this)); + } else { + return this.close(); + } + }).on('submit'), + close: function() { + this.set('error', null); + if (!this.get('submitted')) { + this.sendAction('on-cancel', this); + } + return this._super.apply(this, arguments); + } + }); + + __exports__["default"] = ModalForm; + }); +define("ember-components/modal/modal-title", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var ModalTitle, StyleBindingsMixin, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * `{{em-modal-title}}` component. + * + * The title of the modal + * + * @class ModalTitle + * @public + */ + + ModalTitle = Component.extend(WithConfigMixin, StyleBindingsMixin, { + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.titleClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * Register the title within the modal + * Note: Expects this title to be the direct descendant of the modal component + * + * @method registerInModal + * @private + */ + registerInModal: function() { + return (this.get('parentView').setTitle(this)).on('init'); + } + }); + + __exports__["default"] = ModalTitle; + }); +define("ember-components/modal/modal-tmpl", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile("{{#if is-open}}\n
\n
\n {{yield}}\n
\n
\n{{/if}}"); + }); +define("ember-components/modal/modal-toggler", + ["ember","./modal","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + var View = __dependency1__.View; + var Modal = __dependency2__["default"] || __dependency2__; + var ModalToggler, StyleBindingsMixin, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * `{{em-modal-toggler}}` component. + * + * A component to toggle the visibility of a modal + * + * @class ModalToggler + * @event on-toggle triggered when the toggler is clicked before changing the visibility of the modal + * @param toggler Toggler - This instance of the toggler + * @public + */ + + ModalToggler = Component.extend(WithConfigMixin, StyleBindingsMixin, { + tagName: 'button', + classNameBindings: ['styleClasses'], + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.togglerClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * Toggle the visibility of the modal that this toggler controls. + * + * @method toggleVisibility + * @private + */ + toggleVisibility: (function() { + this.sendAction('on-toggle', this); + return this.get('modal').toggleVisibility(); + }).on('click'), + + /** + * Find the modal view and set it as a `modal` property + * A toggler can live as a descendant (not neccessarily a direct one) of a modal or outside of the modal chain + * TODO: Assert modal existance + * @method modalAsProperty + */ + modalAsProperty: (function() { + var modalAsAncestor; + modalAsAncestor = this.nearestOfType(Modal); + if (modalAsAncestor) { + return this.set('modal', modalAsAncestor); + } else { + return run.schedule('afterRender', this, function() { + return this.set('modal', View.views[this.get('modal-id')]); + }); + } + }).on('willInsertElement') + }); + + __exports__["default"] = ModalToggler; + }); +define("ember-components/modal/modal", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var run = __dependency1__.run; + + var ModalComponent, StyleBindingsMixin, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * `{{em-modal}}` component. + * + * Define a modal component that can be opened and closed, the modal visibility is controlled by the + * {{#crossLink "ModalToggler"}}ModalToggler{{/crossLink}} component. + * + * ```handlebars + * {{#em-modal id="modal1"}} + * {{#em-modal-title}} + * {{#em-modal-toggler}}×{{/em-modal-toggler}} + * + * {{/em-modal-title}} + * {{#em-modal-body}} + * One fine body… + * {{/em-modal-body}} + * {{#em-modal-footer}} + * {{#em-modal-toggler}}Close{{/em-modal-toggler}} + * {{/em-modal-footer}} + * {{/em-modal}} + * {{#em-modal-toggler modal-id="modal1"}}Click me!{{/em-modal-toggler}} + * ``` + * + * @class Modal + * @event will-open + * @event did-open + * @event will-close + * @public + */ + + ModalComponent = Component.extend(WithConfigMixin, StyleBindingsMixin, { + layoutName: 'em-modal', + + /** + * Properties bound as attributes the DOM element. + * see documentation per property. + * @property panels + * @private + * @type Array + */ + attributeBindings: ['is-open', 'did-open', 'tabindex'], + classNameBindings: ['styleClasses', 'styleOpenningClasses'], + styleBindings: ['display'], + + /** + * Define the tabindex DOM property. + * Required otherwise no keyDown events + * @property tabindex + */ + tabindex: 0, + + /** + * The CSS classes that will be attached to the DOM element of the modal + * Classes should be configured externally by using the `config` object. + * @property styleClasses + * @private + * @type String + */ + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.modal.classes')) != null ? _ref.join(" ") : void 0; + }).property('config.modal.classes'), + + /** + * The class name that will be set when the modal gets opened + * @property styleOpenningClasses + * @public + */ + styleOpenningClasses: (function() { + if (this.get('did-open')) { + return "in"; + } else { + return ""; + } + }).property('did-open'), + + /* + * The CSS `display` property state. + * @property display + * @public + */ + display: (function() { + if (this.get('did-open')) { + return 'block'; + } else { + return 'none'; + } + }).property('did-open'), + + /** + * `show` property is bound to the DOM element as an attribute. + * This property is set to true immediately when the `toggleVisibility` method is invoked. + * + * This property can be used to start a transitioning effect, for example: + * ```css + * em-modal[show] { + * opacity: 0; + * transition: opacity 100ms ease; + * } + * ``` + * + * The transition effect should be ended when the modal is gets visible, see the property `shown` for more info. + * @property opened + * @see 'did-open' + * @private + */ + 'is-open': false, + + /** + * A property bound to the DOM element that indicates that the modal has been made visible to the user. + * (after the DOM element was set with `display: block;`) + * + * This proeprty can be used by CSS to end a transitioning effect by setting the CSS `opacity` to a higher number, for example: + * + * ```css + * em-modal[shown] { + * opacity: 1; + * } + } + * ``` + * @property did-open + * @private + */ + 'did-open': false, + + /** + * Open modal and make it visible. + * @method open + * @public + */ + open: function() { + this.trigger('show'); + this.sendAction('show', this); + this.set('is-open', 'true'); + return run.schedule('afterRender', this, function() { + this.set('did-open', 'true'); + return this.trigger('shown'); + }); + }, + + /** + * Close the modal by making it invisible. + * @method close + * @public + */ + close: function() { + this.trigger('hide'); + this.sendAction('hide', this); + this.set('is-open', void 0); + return this.set('did-open', void 0); + }, + + /** + * Toggle the visibility of the modal based on its current state. + * @method toggleVisibility + * @public + */ + toggleVisibility: function() { + if (this.get('is-open')) { + return this.close(); + } else { + return this.open(); + } + }, + + /** + * Set the title of the modal. + * @method setTitle + * @private + * @type ModalTitle + */ + setTitle: function(title) { + return this.set('title', title); + }, + + /** + * Set the toggler of the modal + * @method setToggler + * @private + * @type ModalToggler + */ + setToggler: function(toggler) { + return this.set('toggler', toggler); + }, + + /** + * Close the modal if the user clicks outside of the modal space. + * @method closeIfClickedOutside + * @private + */ + closeIfClickedOutside: (function(e) { + if (e.target !== this.get('element')) { + return; + } + return this.close(); + }).on('click'), + + /** + * Handle keyboard events + * @method handleKeyboard + * @private + */ + handleKeyboard: (function(e) { + switch (e.keyCode) { + case 27: + return this.close(); + } + }).on('keyDown'), - var AccordionItemComponent = __dependency13__["default"] || __dependency13__; + /** + * Consumer can bind this property for a more fine grained control over when the modal is opened, + * This is good for situations where openning the modal via the `toggler` is not enough. + * + * @property open-if + * @public + */ + 'open-if': false, - var AccordionItemTmpl = __dependency14__["default"] || __dependency14__; + /** + * observers the `open-if` property, if set to true, then open the modal. + * @method openIf + * @private + */ + openIf: (function() { + if (!this.get('open-if')) { + return; + } + this.open(); + return this.set('open-if', false); + }).observes('open-if'), - var TreeNode = __dependency15__["default"] || __dependency15__; - var TreeNodeComponent = __dependency16__["default"] || __dependency16__; - var TreeNodeTmpl = __dependency17__["default"] || __dependency17__; - var TreeBranchComponent = __dependency18__["default"] || __dependency18__; - var TreeBranchTmpl = __dependency19__["default"] || __dependency19__; - var TreeBranchStyle = __dependency20__["default"] || __dependency20__; - var ListComponent = __dependency21__["default"] || __dependency21__; - var ListItemComponent = __dependency22__["default"] || __dependency22__; - var Application = __dependency23__.Application; - var Namespace = __dependency23__.Namespace; + /** + * Consumer can bind this property for a more fine grained control over when the modal is closed, + * This is good for situations where closing the modal via the `toggler` is not enough. + * + * @property close-if + * @public + */ + 'close-if': false, - Application.initializer({ - name: 'em-components', - initialize: function(c) { - var Config; - Em.EmberComponents = Namespace.create({ - VERSION: '0.0.1' - }); - Em.Config = Config = Em.Eu.Config.create(); - Config.addConfig('default', { - tabs: { - tabsTag: ['div'], - tabTag: ['li'], - tabListTag: ['ul'] - }, - tree: { - branchClasses: ['em-tree-branch', 'fa-ul'], - nodeClasses: ['em-tree-node'], - nodeOpenClasses: [], - nodeCloseClasses: [], - nodeOpenIconClasses: ['fa-li', 'fa', 'fa-minus-square-o'], - nodeCloseIconClasses: ['fa-li', 'fa', 'fa-plus-square-o'], - nodeLeafClasses: ['leaf'], - nodeLeafIconClasses: ['fa-li', 'fa', 'fa-square-o'], - nodeLoadingIconClasses: ['fa-li', 'fa', 'fa-spinner', 'fa-spin'], - nodeSelectedClasses: ['em-tree-node-active'] - } - }); - Config.addConfig('classic', { - tabs: { - tabsClasses: ['em-tabs'], - tabClasses: ['em-tab'], - tabListClasses: ['em-tab-list'], - tabPanelClasses: ['em-tab-panel'] - } - }); - Config.addConfig('bs', { - tabs: { - tabListClasses: ['nav', 'nav-tabs'], - tabSelectedClasses: ['active'] - }, - wysiwyg: { - classes: ['well'], - toolbarClasses: ['btn-toolbar'], - actionGroupClasses: ['btn-group'], - actionClasses: ['btn btn-default'], - actionActiveClasses: ['active'] - }, - accordion: { - classes: ['panel-group'], - itemClasses: ['panel', 'panel-default'], - itemSelectedClasses: ['active'], - panelHeaderClasses: ['panel-heading'], - panelTitleClasses: ['panel-title'], - panelTogglerClasses: ['accordion-toggle'], - panelBodyContainerClasses: ['panel-collapse', 'collapse'], - panelBodyClasses: ['panel-body'] - } - }); - Config.addConfig('foundation', { - tabs: { - tabListClasses: ['tabs'], - tabSelectedClasses: ['active'], - tabClasses: ['tab-title'], - tabPanelClasses: ['content'] - } - }); - Em.EmberComponents.Config = Em.Config = Config; - c.register('component:em-tabs', TabsComponent); - c.register('template:components/em-tabs-css', TabsStyle); - c.register('component:em-tab-list', TabListComponent); - c.register('component:em-tab', TabComponent); - c.register('component:em-tab-panel', TabPanelComponent); - c.register('component:em-wysiwyg', WysiwygComponent); - c.register('component:em-wysiwyg-toolbar', WysiwygToolbarComponent); - c.register('component:em-wysiwyg-action-group', WysiwygActionGroupComponent); - c.register('component:em-wysiwyg-action', WysiwygActionComponent); - c.register('template:em-wysiwyg-action', WysiwygActionTmpl); - c.register('component:em-wysiwyg-editor', WysiwygEditorComponent); - c.register('component:em-accordion', AccordionComponent); - c.register('component:em-accordion-item', AccordionItemComponent); - c.register('template:em-accordion-item-tmpl', AccordionItemTmpl); - c.register('component:em-tree-node', TreeNodeComponent); - c.register('template:em-tree-node', TreeNodeTmpl); - c.register('component:em-tree-branch', TreeBranchComponent); - c.register('template:em-tree-branch', TreeBranchTmpl); - c.register('template:components/em-tree-branch-css', TreeBranchStyle); - c.register('component:em-list', ListComponent); - return c.register('component:em-list-item', ListItemComponent); - } + /** + * observers the `close-if` property, if set to true, then close the modal. + * @method closeIf + * @private + */ + closeIf: (function() { + if (!this.get('close-if')) { + return; + } + this.close(); + return this.set('close-if', false); + }).observes('close-if') }); - __exports__.TabsComponent = TabsComponent; - __exports__.TabListComponent = TabListComponent; - __exports__.TabComponent = TabComponent; - __exports__.TabPanelComponent = TabPanelComponent; - __exports__.WysiwygComponent = WysiwygComponent; - __exports__.WysiwygToolbarComponent = WysiwygToolbarComponent; - __exports__.WysiwygActionGroupComponent = WysiwygActionGroupComponent; - __exports__.WysiwygActionComponent = WysiwygActionComponent; - __exports__.WysiwygEditorComponent = WysiwygEditorComponent; - __exports__.AccordionComponent = AccordionComponent; - __exports__.AccordionItemComponent = AccordionItemComponent; - __exports__.TreeNodeComponent = TreeNodeComponent; - __exports__.TreeBranchComponent = TreeBranchComponent; - __exports__.TreeNode = TreeNode; - __exports__.ListComponent = ListComponent; - __exports__.ListItemComponent = ListItemComponent; + __exports__["default"] = ModalComponent; }); define("ember-components/tabs/tab-list", ["ember","exports"], @@ -1139,7 +2006,7 @@ define("ember-components/tree/node", function(__dependency1__, __exports__) { "use strict"; var Ember = __dependency1__["default"] || __dependency1__; - var Node; + var Node, findChildrenOfNodeBy; Node = Ember.Object.extend({ children: void 0, @@ -1200,22 +2067,38 @@ define("ember-components/tree/node", }).property('children.length'), isLevel1: (function() { return this.get('level') === 0; - }).property('children.length') + }).property('children.length'), + findChildBy: function(key, name) { + return findChildrenOfNodeBy(this, key, name); + } }); __exports__["default"] = Node; - }); -define("ember-components/tree/tree-branch-css", - ["exports"], - function(__exports__) { - "use strict"; - __exports__["default"] = Ember.Handlebars.compile(".em-tree-node {\n cursor: pointer;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.em-tree-node-active {\n background: #e7e7e7;\n}"); + + findChildrenOfNodeBy = function(currChild, key, value) { + var c, _i, _len, _ref, _ref1; + if (currChild.get(key) === value) { + return currChild; + } else if (((_ref = currChild.get('children')) != null ? _ref.length : void 0) > 0) { + _ref1 = currChild.get('children'); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + c = _ref1[_i]; + if (c.get(key) === value) { + return c; + } else { + findChildrenOfNodeBy(c, key, value); + } + } + return null; + } + return null; + }; }); define("ember-components/tree/tree-branch-tmpl", ["exports"], function(__exports__) { "use strict"; - __exports__["default"] = Ember.Handlebars.compile("{{#each nodes}}\n {{em-tree-node node=this async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); + __exports__["default"] = Ember.Handlebars.compile("{{#each children}}\n {{em-tree-node model=this tree=view.tree async=controller.async targetObject=controller.targetObject}}\n{{/each}}"); }); define("ember-components/tree/tree-branch", ["ember","exports"], @@ -1239,20 +2122,15 @@ define("ember-components/tree/tree-branch", TreeBranch = Component.extend(WithConfigMixin, { /** - * The node to render its children within this branch - * this property is expected to be defined by the user - */ - node: void 0, - - /** - * The root node of the tree + * The model to render its children within this branch + * this property is set during component markup creation */ - rootNode: computed.alias('node.root'), + model: void 0, /** * A list of {{#crossLink "TreeNode"}}nodes{{/crossLink}} instances. */ - nodes: computed.alias('node.children'), + children: computed.alias('model.children'), /** * True if node's children should be loaded asynchronously @@ -1271,11 +2149,118 @@ define("ember-components/tree/tree-branch", __exports__["default"] = TreeBranch;; }); +define("ember-components/tree/tree-css", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile(".em-tree-node {\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.em-tree-node-active {\n background: #e7e7e7;\n}\n\nli.em-tree-node > span {\n cursor: pointer;\n}\n\nli.em-tree-node > span > span.actions {\n visibility: hidden;\n}\n\nli.em-tree-node > span:hover > span.actions {\n visibility: visible;\n}"); + }); +define("ember-components/tree/tree-node-icon-action", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var computed = __dependency1__.computed; + + var StyleBindingsMixin, TreeNodeIconAction, WithConfigMixin; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + StyleBindingsMixin = Em.Eu.StyleBindingsMixin; + + + /** + * An icon action of a tree node + * @class TreeNodeIconAction + */ + + TreeNodeIconAction = Component.extend(WithConfigMixin, StyleBindingsMixin, { + attributeBindings: ['stickyMode:sticky'], + + /** + * The tag name of the icon action, + * default is `` but can be replaced with any tag. + * @property tagName + * @public + */ + tagName: 'i', + + /** + * Bind the visibility css property, + * this is required for the `sticky` property + * @property styleBindings + * @private + */ + styleBindings: 'visibility', + + /** + * Defines the css visibility according to the value of the `sticky` property + * @property visibility + * @private + */ + visibility: (function() { + if (this.get('sticky')) { + return 'visible'; + } else { + return void 0; + } + }).property('sticky'), + + /** + * 'true' if the action icon should be sticky and not disappear when item is not hovered + * @property sticky + * @public + */ + sticky: false, + stickyMode: (function() { + if (this.get('sticky')) { + return 'true'; + } else { + return void 0; + } + }).property('sticky'), + + /** + * Binds the specified css classes + * @property classNameBindings + * @private + */ + classNameBindings: ['iconClasses'], + + /** + * Set the given array of classes + * @property iconClasses + * @private + */ + iconClasses: (function() { + var _ref; + return (_ref = this.get('meta.classes')) != null ? _ref.join(" ") : void 0; + }).property('meta.classes'), + + /** + * An alias to the node model of this action + * @property node + * @public + */ + node: computed.alias('parentView.node'), + + /** + * Invoked when the action is clicked + * @method invokde + */ + invoked: (function() { + return this.get('parentView.targetObject').send(this.get('meta.action'), this); + }).on('click') + }); + + __exports__["default"] = TreeNodeIconAction; + }); define("ember-components/tree/tree-node-tmpl", ["exports"], function(__exports__) { "use strict"; - __exports__["default"] = Ember.Handlebars.compile("{{#if hasIcon}}\n \n{{else}}\n *\n{{/if}}\n\n{{node.title}}\n\n{{#if expanded}}\n {{em-tree-branch node=node async=async targetObject=targetObject}}\n{{/if}}"); + __exports__["default"] = Ember.Handlebars.compile("\n{{else}}\n *\n{{/if}}\n\n\n{{#if tree.in-multi-selection}}\n \n {{#if multi-selected}}\n \n {{else}}\n \n {{/if}}\n \n{{/if}}\n\n\n{{model.title}}\n{{#if tree.hovered-actions}}\n \n {{#each tree.hovered-actions}}\n {{em-tree-node-icon-action meta=this model=controller.model}}\n {{/each}}\n \n{{/if}}\n\n\n{{#if expanded}}\n {{em-tree-branch model=model tree=tree async=async targetObject=targetObject}}\n{{/if}}"); }); define("ember-components/tree/tree-node", ["ember","exports"], @@ -1297,49 +2282,50 @@ define("ember-components/tree/tree-node", */ TreeNode = Component.extend(WithConfigMixin, { + attributeBindings: ['multi-selected'], /** - * The node model the tree node view is bound to + * The model the tree node view is bound to */ - node: void 0, + model: void 0, /** - * true if the node of this view is a root node + * A reference to the tree view, this property is auto set during component instantiation */ - isRootNode: computed.not('node.hasParent'), + tree: void 0, /** - * The root node model + * A reference to the root model */ - root: computed.alias('node.root'), + rootModel: computed.alias('tree.model'), /** * True if the node is currently expanded, meaning its children are visible. */ - expanded: false, + expanded: computed.alias('model.expanded'), /** - * True if this node is currently checked - * This is only relevant if the tree configured to support selection + * True if this node view is currently checked + * This is only relevant if the tree configured to support multi selection */ - checked: false, + 'multi-selected': computed.alias('model.selected'), /** - * True if should render an icon tag for this node + * True if should render an icon tag for this node view */ hasIcon: true, /** - * True if nodes can be selected + * True if this node can be single selected */ selectable: true, /** - * True if this node is currently selected + * True if this node is currently single selected */ isSelected: (function() { - return this.get('rootBranchView.selected') === this.get('node'); - }).property('rootBranchView.selected'), + return this.get('tree.selected') === this.get('model'); + }).property('tree.selected'), /** * True if this node is currently loading, @@ -1354,31 +2340,11 @@ define("ember-components/tree/tree-node", async: computed.alias('parentView.async'), /** - * Get the view of the root node - */ - rootNodeView: (function() { - var view; - if (this.get('isRootNode')) { - return this; - } - view = this.get('parentView'); - while (view) { - if (view.get('isRootNode')) { - return view; - } - view = view.get('parentView'); - } - }).property('node'), - - /** - * The root branch view + * true if this is a leaf node, meaning it has no children */ - rootBranchView: (function() { - return this.get('rootNodeView.parentView'); - }).property('rootNodeView'), leaf: (function() { - return this.get('node.children.length') === 0; - }).property('node.children.length'), + return !this.get('model.children') || this.get('model.children.length') === 0; + }).property('model.children.length'), tagName: 'li', layoutName: 'em-tree-node', classNameBindings: ['styleClasses', 'expandedClasses', 'leafClasses'], @@ -1402,16 +2368,23 @@ define("ember-components/tree/tree-node", return null; } }).property('isSelected'), + addMultiSelectionToTreeSelection: (function() { + if (this.get('multi-selected')) { + return this.get('tree.multi-selection').pushObject(this.get('model')); + } else { + return this.get('tree.multi-selection').removeObject(this.get('model')); + } + }).observes('multi-selected').on('init'), iconClass: (function() { var icons; icons = []; if (this.get('async')) { if (this.get('loading')) { icons = icons.concat(this.get('config.tree.nodeLoadingIconClasses')); - } else if (!this.get('node.children')) { + } else if (!this.get('model.children')) { icons = icons.concat(this.get('config.tree.nodeCloseIconClasses')); } else { - if (this.get('node.children.length') === 0) { + if (this.get('model.children.length') === 0) { icons = icons.concat(this.get('config.tree.nodeLeafIconClasses')); } else { icons = this.get('expanded') ? icons.concat(this.get('config.tree.nodeOpenIconClasses')) : icons.concat(this.get('config.tree.nodeCloseIconClasses')); @@ -1434,9 +2407,9 @@ define("ember-components/tree/tree-node", }).property('leaf'), actions: { toggle: function() { - if (this.get('async') && !this.get('expanded') && !this.get('node.children')) { + if (this.get('async') && !this.get('expanded') && !this.get('model.children')) { this.set('loading', true); - return this.sendAction('children', this.get('node'), this); + return this.sendAction('children', this.get('model'), this); } else { return this.toggleProperty('expanded'); } @@ -1445,7 +2418,14 @@ define("ember-components/tree/tree-node", if (!this.get('selectable')) { return; } - return this.set('rootBranchView.selected', this.get('node')); + return this.set('tree.selected', this.get('model')); + }, + toggleSelection: function() { + if (this.get('multi-selected')) { + return this.set('multi-selected', ''); + } else { + return this.set('multi-selected', 'true'); + } } }, children: 'getChildren', @@ -1458,6 +2438,100 @@ define("ember-components/tree/tree-node", __exports__["default"] = TreeNode;; }); +define("ember-components/tree/tree-tmpl", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = Ember.Handlebars.compile("{{em-tree-node model=model tree=view async=async targetObject=targetObject}}"); + }); +define("ember-components/tree/tree", + ["ember","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Component = __dependency1__.Component; + var ArrayProxy = __dependency1__.ArrayProxy; + var computed = __dependency1__.computed; + var A = __dependency1__.A; + var Tree, WithConfigMixin, expandTree; + + WithConfigMixin = Em.Eu.WithConfigMixin; + + + /** + * A tree component + * + * @class Tree + */ + + Tree = Component.extend(WithConfigMixin, { + tagName: 'ul', + layoutName: 'em-tree', + classNameBindings: ['styleClasses'], + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.tree.classes')) != null ? _ref.join(" ") : void 0; + }).property(), + + /** + * The model to render as the root node of the tree + * this property is expected to be defined by the user + */ + model: void 0, + + /** + * True if node's children should be loaded asynchronously + * This gives the opportunity to the user to invoke an async call to the server to retrieve data for the current + * branch being opened + */ + async: false, + 'in-multi-selection': false, + 'multi-selection': A(), + 'selected-icon': 'fa fa-check', + 'unselected-icon': 'fa fa-times', + 'expand-depth': null, + 'auto-expand': false, + expandByDepth: (function() { + var depth; + if (this.get('expand-depth')) { + depth = parseInt(this.get('expand-depth')); + if (depth === 0) { + return; + } + return expandTree(this.get('model'), depth); + } + }).observes('expand-depth') + }); + + __exports__["default"] = Tree; + + expandTree = function(node, depth) { + var c, children, _i, _len, _results; + if (depth === 0) { + return; + } + node.set('expanded', true); + children = node.get('children'); + if (children && "function" === typeof children.then) { + return children.then((function(_this) { + return function(loadedChildren) { + return loadedChildren.forEach(function(c) { + return expandTree(c, depth - 1); + }); + }; + })(this)); + } else { + if (children.get('length') === 0 || depth === 0) { + return; + } + _results = []; + for (_i = 0, _len = children.length; _i < _len; _i++) { + c = children[_i]; + _results.push(expandTree(c, depth - 1)); + } + return _results; + } + }; + }); define("ember-components/wysiwyg/action-group", ["ember","exports"], function(__dependency1__, __exports__) { diff --git a/package.json b/package.json index 7272b92..764cc8b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ember-components", "description": "A suite of components for Ember.js", - "version": "0.1.0", + "version": "0.2.0", "homepage": "http://ember-addons.github.io/ember-components", "license": "ASF 2.0", "authors": [