mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Add angular-bindonce
This commit is contained in:
parent
7ea19970b7
commit
4f35fd62f4
12 changed files with 607 additions and 6 deletions
|
@ -38,7 +38,8 @@
|
|||
"angular-bootstrap": "~0.10.0",
|
||||
"stacktrace.js": "https://github.com/stacktracejs/stacktrace.js.git#~0.6.0",
|
||||
"jsonpath": "*",
|
||||
"moment-timezone": "~0.0.3"
|
||||
"moment-timezone": "~0.0.3",
|
||||
"angular-bindonce": "~0.3.1"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
|
37
src/bower_components/angular-bindonce/.bower.json
vendored
Normal file
37
src/bower_components/angular-bindonce/.bower.json
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "angular-bindonce",
|
||||
"version": "0.3.1",
|
||||
"main": "bindonce.js",
|
||||
"description": "Zero watchers binding directives for AngularJS",
|
||||
"homepage": "https://github.com/Pasvaz/bindonce",
|
||||
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Pasvaz/bindonce.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {},
|
||||
"keywords": [
|
||||
"angularjs",
|
||||
"angular",
|
||||
"directive",
|
||||
"binding",
|
||||
"watcher",
|
||||
"bindonce"
|
||||
],
|
||||
"_release": "0.3.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.3.1",
|
||||
"commit": "350abf029a6e1b3ee200261084e563d4d3d15e2c"
|
||||
},
|
||||
"_source": "git://github.com/Pasvaz/bindonce.git",
|
||||
"_target": "~0.3.1",
|
||||
"_originalSource": "angular-bindonce",
|
||||
"_direct": true
|
||||
}
|
32
src/bower_components/angular-bindonce/CHANGELOG.md
vendored
Normal file
32
src/bower_components/angular-bindonce/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# 0.3.1 (2014-02-12)
|
||||
### Features
|
||||
- **bo-bind:**
|
||||
- alias for bo-text
|
||||
|
||||
### Bug Fixes
|
||||
- **Angular Promises**
|
||||
- Ensures that promises are resolved before to run binders ([b3ef1b4](https://github.com/Pasvaz/bindonce/commit/b3ef1b46edfe83f10ed455d5520027f731563f32))
|
||||
|
||||
### Minor improvements
|
||||
- Updated Readme
|
||||
|
||||
<hr />
|
||||
# 0.3.0 (2014-01-21)
|
||||
### Features
|
||||
- **bo-switch:**
|
||||
- Create new directive: bo-switch ([652d0db](https://github.com/Pasvaz/bindonce/commit/652d0db04325166a180377c738a376543b5f2357))
|
||||
|
||||
<hr />
|
||||
# 0.2.3 (2014-01-20)
|
||||
### Bug Fixes
|
||||
|
||||
- **bo-if:**
|
||||
- Ensures that we both process newly added binders from bo-if, and that
|
||||
we only process each binder once ([d11f863](https://github.com/Pasvaz/bindonce/commit/e091c273bbd17603d410fecc363874f0d1e6f38e))
|
||||
|
||||
### Features
|
||||
|
||||
- **Minification:**
|
||||
- add min file ([47277ee](https://github.com/Pasvaz/bindonce/commit/47277eedd092b3210de362c725a7dadcddac8e87))
|
||||
- **Changelog:**
|
||||
- Created a changelog file
|
148
src/bower_components/angular-bindonce/README.md
vendored
Normal file
148
src/bower_components/angular-bindonce/README.md
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
Bindonce
|
||||
========
|
||||
|
||||
High performance binding for AngularJs
|
||||
|
||||
## Usage
|
||||
* download, clone or fork it or install it using [bower](http://twitter.github.com/bower/) `bower install angular-bindonce`
|
||||
* Include the `bindonce.js` script provided by this component into your app.
|
||||
* Add `'pasvaz.bindonce'` as a module dependency to your app: `angular.module('app', ['pasvaz.bindonce'])`
|
||||
|
||||
## Overview
|
||||
AngularJs provides a great data binding system but if you abuse of it the page can run into some performance issues, it's known that more of 2000 watchers can lag the UI and that amount can be reached easily if you don't pay attention to the data-binding. Sometime you really need to bind your data using watchers, especially for SPA because the data are updated in real time, but often you can avoid it with some efforts, most of the data presented in your page, once rendered, are immutable so you shouldn't keep watching them for changes.
|
||||
|
||||
For instance, take a look to this snippet:
|
||||
```html
|
||||
<ul>
|
||||
<li ng-repeat="person in Persons">
|
||||
<a ng-href="#/people/{{person.id}}"><img ng-src="{{person.imageUrl}}"></a>
|
||||
<a ng-href="#/people/{{person.id}}"><span ng-bind="person.name"></span></a>
|
||||
<p ng-class="{'cycled':person.generated}" ng-bind-html-unsafe="person.description"></p>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
Angular internally creates a `$watch` for each `ng-*` directive in order to keep the data up to date, so in this example just for displaying few info it creates 6 + 1 *(ngRepeatWatch)* watchers per `person`, even if the `person` is supposed to remain the same once shown. Iterate this amount for each person and you can have an idea about how easy is to reach 2000 watchers. Now if you need it because those data could change while you show the page or are bound to some models, it's ok. But most of the time they are static data that don't change once rendered. This is where **bindonce** can really help you.
|
||||
|
||||
The above example done with **bindonce**:
|
||||
```html
|
||||
<ul>
|
||||
<li bindonce ng-repeat="person in Persons">
|
||||
<a bo-href="'#/people/' + person.id"><img bo-src="person.imageUrl"></a>
|
||||
<a bo-href="'#/people/' + person.id" bo-text="person.name"></a>
|
||||
<p bo-class="{'cycled':person.generated}" bo-html="person.description"></p>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
Now this example uses **0 watches** per `person` and renders exactly the same result as the above that uses ng-*. *(Angular still uses 1 watcher for ngRepeatWatch)*
|
||||
|
||||
### The smart approach
|
||||
OK until here nothing completely new, with a bit of efforts you could create your own directive and render the `person` inside the `link` function, or you could use [watch fighters](https://github.com/abourget/abourget-angular) that has a similar approach, but there is still one problem that you have to face and **bindonce** already handles it: *the existence of the data when the directive renders the content*. Usually the directives, unless you use watchers or bind their attributes to the scope (still a watcher), render the content when they are loaded into the markup, but if at that given time your data is not available, the directive can't render it. Bindonce can wait until the data is ready before to rendering the content.
|
||||
Let's take a look at the follow snippet to better understand the concept:
|
||||
```html
|
||||
<span my-custom-set-text="Person.firstname"></span>
|
||||
<span my-custom-set-text="Person.lastname"></span>
|
||||
...
|
||||
<script>
|
||||
angular.module('testApp', [])
|
||||
.directive('myCustomSetText', function () {
|
||||
return {
|
||||
link:function (scope, elem, attr, ctrl) {
|
||||
elem.text(scope.$eval(attr.myCustomSetText));
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
This basic directive works as expected, it renders the `Person` data without using any watchers. However, if `Person` is not yet available inside the $scope when the page is loaded (say we get `Person` via $http or via $resource), the directive is useless, `scope.$eval(attr.myCustomSetText)` simply renders nothing and exits.
|
||||
|
||||
Here is how we can solve this issue with **bindonce**:
|
||||
```html
|
||||
<div bindonce="Person" bo-title="Person.title">
|
||||
<span bo-text="Person.firstname"></span>
|
||||
<span bo-text="Person.lastname"></span>
|
||||
<img bo-src="Person.picture" bo-alt="Person.title">
|
||||
<p bo-class="{'fancy':Person.isNice}" bo-html="Person.story"></p>
|
||||
</div>
|
||||
```
|
||||
`bindonce="Person"` does the trick, any `bo-*` attribute belonging to `bindonce` waits until the parent `bindonce="{somedata}"` is validated and then renders its content. Once the scope contains the value `Person` then each bo-* child gets filled with the proper values. In order to accomplish this task, **bindonce** uses just **one** temporary watcher, no matters how many children need to be rendered. As soon as it gets `Person` the watcher is promptly removed. If the $scope already contains the data `bindonce` is looking for, then it doesn't create the temporary watcher and simply starts rendering its children.
|
||||
|
||||
You may have noticed that the first example didn't assign any value to the `bindonce` attribute:
|
||||
```html
|
||||
<ul>
|
||||
<li bindonce ng-repeat="person in Persons">
|
||||
...
|
||||
```
|
||||
when used with `ng-repeat` `bindonce` doesn't need to check if `person` is defined because `ng-repeat` creates the directives only when `person` exists. You could be more explicit: `<li bindonce="person" ng-repeat="person in Persons">`, however assigning a value to `bindonce` in an `ng-repeat` won't make any difference.
|
||||
|
||||
### Interpolation
|
||||
Some directives (ng-href, ng-src) use interpolation, ie: `ng-href="/profile/{{User.profileId}}"`.
|
||||
Both `ng-href` and `ng-src` have the bo-* equivalent directives: `bo-href-i` and `bo-src-i` (pay attention to the **-i**, it stands for **interpolate**). As expected they don't use watchers however Angular creates one watcher per interpolation, for instance `bo-href-i="/profile/{{User.profileId}}"` sets the element's href **once**, as expected, but Angular keeps a watcher active on `{{User.profileId}}` even if `bo-href-i` doesn't use it.
|
||||
That's why by default the `bo-href` doesn't use interpolation or watchers. The above equivalent with 0 watchers would be `bo-href="'/profile/' + User.profileId"`. Nevertheless, `bo-href-i` and `bo-src-i` are still maintained for compatibility reasons.
|
||||
|
||||
### Filters
|
||||
Almost every `bo-*` directive replace the equivalent `ng-*` and works in the same ways, except it is evaluated once.
|
||||
Consequentially you can use any valid angular expression, including filters. This is an example how to use a filter:
|
||||
```html
|
||||
<div bindonce="Person">
|
||||
<span bo-bind="Person.bill | currency:'USD$'"></span>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Attribute Usage
|
||||
| Directive | Description | Example |
|
||||
|------------|----------------|-----|
|
||||
| `bindonce="{somedata}"`| **bindonce** is the main directive. `{somedata}` is optional, and if present, forces bindonce to wait until `somedata` is defined before rendering its children | `<div bindonce="Person">...<div>` |
|
||||
| `bo-if = "condition"` | equivalent to `ng-if` but doesn't use watchers |`<ANY bo-if="Person.isPublic"></ANY>`|
|
||||
| `bo-switch = "expression"` | equivalent to `ng-switch` but doesn't use watchers |`<div bo-switch="Person.isPublic">` `<span bo-switch-when="'yes">public</span>` `<span bo-switch-default>private</span>` `</div>`|
|
||||
| `bo-show = "condition"` | equivalent to `ng-show` but doesn't use watchers |`<ANY bo-show="Person.isPublic"></ANY>`|
|
||||
| `bo-hide = "condition"` | equivalent to `ng-hide` but doesn't use watchers |`<ANY bo-hide="Person.isPrivate"></ANY>`|
|
||||
| `bo-text = "text"` | evaluates "text" and print it as text inside the element | `<span bo-text="Person.name"></span>` |
|
||||
| `bo-bind = "text"` | alias for `bo-text`, equivalent to `ng-bind` but doesn't use watchers | `<span bo-bind="Person.name"></span>` |
|
||||
| `bo-html = "markup"` | evaluates "markup" and render it as html inside the element |`bo-html="Person.description"`|
|
||||
| `bo-href-i = "url"`<br>*use `bo-href` instead* | **equivalent** to `ng-href`.<br>**Heads up!** Using interpolation `{{}}` it creates one watcher: <br>`bo-href-i="/p/{{Person.id}}"`. <br>Use `bo-href` to avoid the watcher:<br> `bo-href="'/p/' + Person.id"` |`<a bo-href-i="/profile{{Person.id}}"></a>`|
|
||||
| `bo-href = "url"` | **similar** to `ng-href` but doesn't allow interpolation using `{{}}` like `ng-href`. <br>**Heads up!** You can't use interpolation `{{}}` inside the url, use bo-href-i for that purpose |`<a bo-href="'/profile' + Person.id"></a>` <br />or<br /> `<a bo-href="link" bo-text="Link"></a>`|
|
||||
| `bo-src-i = "url"`<br>*use `bo-src` instead* | **equivalent** to `ng-src`. <br>**Heads up!** It creates one watcher |`<img bo-src-i="{{picture}}" bo-alt="title">`|
|
||||
| `bo-src = "url"` | **similar** to `ng-src` but doesn't allow interpolation using `{{}}` like `ng-src`. <br>**Heads up!** You can't use interpolation `{{}}`, use bo-src-i for that purpose |`<img bo-src="picture" bo-alt="title">`|
|
||||
| `bo-class = "object/string"` | equivalent to `ng-class` but doesn't use watchers |`<span bo-class="{'fancy':Person.condition}">`|
|
||||
| `bo-alt = "text"` | evaluates "text" and render it as `alt` for the element |`<ANY bo-alt="title">`|
|
||||
| `bo-title = "text"` | evaluates "text" and render it as `title` for the element |`<ANY bo-title="title">`|
|
||||
| `bo-id = "#id"` | evaluates "#id" and render it as `id` for the element |`<ANY bo-id="id">`|
|
||||
| `bo-style = "object"` | equivalent to `ng-style` but doesn't use watchers |`<ANY bo-style="{'color':Person.color}">`|
|
||||
| `bo-value = "expression"` | evaluates "expression" and render it as `value` for the element |`<input type="radio" bo-value="value">`|
|
||||
| `bo-attr bo-attr-foo = "text"` | evaluates "text" and render it as a custom attribute for the element |`<div bo-attr bo-attr-foo="bar"></div>`|
|
||||
|
||||
## Build
|
||||
```
|
||||
$ npm install uglify-js -g
|
||||
$ uglifyjs bindonce.js -c -m -o bindonce.min.js
|
||||
```
|
||||
|
||||
## Todo
|
||||
Examples and Tests
|
||||
|
||||
## Copyright
|
||||
BindOnce was written by **Pasquale Vazzana**, you can follow him on [google+](https://plus.google.com/101872882413388363602) or on [@twitter](https://twitter.com/PasqualeVazzana)
|
||||
|
||||
Thanks to all the [contributors](https://github.com/Pasvaz/bindonce/graphs/contributors)
|
||||
|
||||
## LICENSE - "MIT License"
|
||||
|
||||
Copyright (c) 2013-2014 Pasquale Vazzana
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
322
src/bower_components/angular-bindonce/bindonce.js
vendored
Normal file
322
src/bower_components/angular-bindonce/bindonce.js
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
(function () {
|
||||
"use strict";
|
||||
/**
|
||||
* Bindonce - Zero watches binding for AngularJs
|
||||
* @version v0.3.1
|
||||
* @link https://github.com/Pasvaz/bindonce
|
||||
* @author Pasquale Vazzana <pasqualevazzana@gmail.com>
|
||||
* @license MIT License, http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
var bindonceModule = angular.module('pasvaz.bindonce', []);
|
||||
|
||||
bindonceModule.directive('bindonce', function ()
|
||||
{
|
||||
var toBoolean = function (value)
|
||||
{
|
||||
if (value && value.length !== 0)
|
||||
{
|
||||
var v = angular.lowercase("" + value);
|
||||
value = !(v === 'f' || v === '0' || v === 'false' || v === 'no' || v === 'n' || v === '[]');
|
||||
}
|
||||
else
|
||||
{
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||
if (isNaN(msie))
|
||||
{
|
||||
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||
}
|
||||
|
||||
var bindonceDirective =
|
||||
{
|
||||
restrict: "AM",
|
||||
controller: ['$scope', '$element', '$attrs', '$interpolate', function ($scope, $element, $attrs, $interpolate)
|
||||
{
|
||||
var showHideBinder = function (elm, attr, value)
|
||||
{
|
||||
var show = (attr === 'show') ? '' : 'none';
|
||||
var hide = (attr === 'hide') ? '' : 'none';
|
||||
elm.css('display', toBoolean(value) ? show : hide);
|
||||
};
|
||||
var classBinder = function (elm, value)
|
||||
{
|
||||
if (angular.isObject(value) && !angular.isArray(value))
|
||||
{
|
||||
var results = [];
|
||||
angular.forEach(value, function (value, index)
|
||||
{
|
||||
if (value) results.push(index);
|
||||
});
|
||||
value = results;
|
||||
}
|
||||
if (value)
|
||||
{
|
||||
elm.addClass(angular.isArray(value) ? value.join(' ') : value);
|
||||
}
|
||||
};
|
||||
|
||||
var ctrl =
|
||||
{
|
||||
watcherRemover: undefined,
|
||||
binders: [],
|
||||
group: $attrs.boName,
|
||||
element: $element,
|
||||
ran: false,
|
||||
|
||||
addBinder: function (binder)
|
||||
{
|
||||
this.binders.push(binder);
|
||||
|
||||
// In case of late binding (when using the directive bo-name/bo-parent)
|
||||
// it happens only when you use nested bindonce, if the bo-children
|
||||
// are not dom children the linking can follow another order
|
||||
if (this.ran)
|
||||
{
|
||||
this.runBinders();
|
||||
}
|
||||
},
|
||||
|
||||
setupWatcher: function (bindonceValue)
|
||||
{
|
||||
var that = this;
|
||||
this.watcherRemover = $scope.$watch(bindonceValue, function (newValue)
|
||||
{
|
||||
if (newValue === undefined) return;
|
||||
that.removeWatcher();
|
||||
that.runBinders();
|
||||
}, true);
|
||||
},
|
||||
|
||||
removeWatcher: function ()
|
||||
{
|
||||
if (this.watcherRemover !== undefined)
|
||||
{
|
||||
this.watcherRemover();
|
||||
this.watcherRemover = undefined;
|
||||
}
|
||||
},
|
||||
|
||||
runBinders: function ()
|
||||
{
|
||||
while (this.binders.length > 0)
|
||||
{
|
||||
var binder = this.binders.shift();
|
||||
if (this.group && this.group != binder.group) continue;
|
||||
var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value);
|
||||
switch (binder.attr)
|
||||
{
|
||||
case 'boIf':
|
||||
if (toBoolean(value))
|
||||
{
|
||||
binder.transclude(binder.scope.$new(), function (clone)
|
||||
{
|
||||
var parent = binder.element.parent();
|
||||
var afterNode = binder.element && binder.element[binder.element.length - 1];
|
||||
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
|
||||
var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
|
||||
angular.forEach(clone, function (node)
|
||||
{
|
||||
parentNode.insertBefore(node, afterNextSibling);
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'boSwitch':
|
||||
var selectedTranscludes, switchCtrl = binder.controller[0];
|
||||
if ((selectedTranscludes = switchCtrl.cases['!' + value] || switchCtrl.cases['?']))
|
||||
{
|
||||
binder.scope.$eval(binder.attrs.change);
|
||||
angular.forEach(selectedTranscludes, function (selectedTransclude)
|
||||
{
|
||||
selectedTransclude.transclude(binder.scope.$new(), function (clone)
|
||||
{
|
||||
var parent = selectedTransclude.element.parent();
|
||||
var afterNode = selectedTransclude.element && selectedTransclude.element[selectedTransclude.element.length - 1];
|
||||
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
|
||||
var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
|
||||
angular.forEach(clone, function (node)
|
||||
{
|
||||
parentNode.insertBefore(node, afterNextSibling);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'boSwitchWhen':
|
||||
var ctrl = binder.controller[0];
|
||||
ctrl.cases['!' + binder.attrs.boSwitchWhen] = (ctrl.cases['!' + binder.attrs.boSwitchWhen] || []);
|
||||
ctrl.cases['!' + binder.attrs.boSwitchWhen].push({ transclude: binder.transclude, element: binder.element });
|
||||
break;
|
||||
case 'boSwitchDefault':
|
||||
var ctrl = binder.controller[0];
|
||||
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
||||
ctrl.cases['?'].push({ transclude: binder.transclude, element: binder.element });
|
||||
break;
|
||||
case 'hide':
|
||||
case 'show':
|
||||
showHideBinder(binder.element, binder.attr, value);
|
||||
break;
|
||||
case 'class':
|
||||
classBinder(binder.element, value);
|
||||
break;
|
||||
case 'text':
|
||||
binder.element.text(value);
|
||||
break;
|
||||
case 'html':
|
||||
binder.element.html(value);
|
||||
break;
|
||||
case 'style':
|
||||
binder.element.css(value);
|
||||
break;
|
||||
case 'src':
|
||||
binder.element.attr(binder.attr, value);
|
||||
if (msie) binder.element.prop('src', value);
|
||||
break;
|
||||
case 'attr':
|
||||
angular.forEach(binder.attrs, function (attrValue, attrKey)
|
||||
{
|
||||
var newAttr, newValue;
|
||||
if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
|
||||
{
|
||||
newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
newValue = binder.scope.$eval(binder.attrs[attrKey]);
|
||||
binder.element.attr(newAttr, newValue);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'href':
|
||||
case 'alt':
|
||||
case 'title':
|
||||
case 'id':
|
||||
case 'value':
|
||||
binder.element.attr(binder.attr, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.ran = true;
|
||||
}
|
||||
};
|
||||
|
||||
return ctrl;
|
||||
}],
|
||||
|
||||
link: function (scope, elm, attrs, bindonceController)
|
||||
{
|
||||
var value = (attrs.bindonce) ? scope.$eval(attrs.bindonce) : true;
|
||||
if (value !== undefined)
|
||||
{
|
||||
// since Angular 1.2 promises are no longer
|
||||
// undefined until they don't get resolved
|
||||
if (value.then && typeof value.then === 'function')
|
||||
{
|
||||
value.then(function ()
|
||||
{
|
||||
bindonceController.runBinders();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
bindonceController.runBinders();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bindonceController.setupWatcher(attrs.bindonce);
|
||||
elm.bind("$destroy", bindonceController.removeWatcher);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return bindonceDirective;
|
||||
});
|
||||
|
||||
angular.forEach(
|
||||
[
|
||||
{ directiveName: 'boShow', attribute: 'show' },
|
||||
{ directiveName: 'boHide', attribute: 'hide' },
|
||||
{ directiveName: 'boClass', attribute: 'class' },
|
||||
{ directiveName: 'boText', attribute: 'text' },
|
||||
{ directiveName: 'boBind', attribute: 'text' },
|
||||
{ directiveName: 'boHtml', attribute: 'html' },
|
||||
{ directiveName: 'boSrcI', attribute: 'src', interpolate: true },
|
||||
{ directiveName: 'boSrc', attribute: 'src' },
|
||||
{ directiveName: 'boHrefI', attribute: 'href', interpolate: true },
|
||||
{ directiveName: 'boHref', attribute: 'href' },
|
||||
{ directiveName: 'boAlt', attribute: 'alt' },
|
||||
{ directiveName: 'boTitle', attribute: 'title' },
|
||||
{ directiveName: 'boId', attribute: 'id' },
|
||||
{ directiveName: 'boStyle', attribute: 'style' },
|
||||
{ directiveName: 'boValue', attribute: 'value' },
|
||||
{ directiveName: 'boAttr', attribute: 'attr' },
|
||||
|
||||
{ directiveName: 'boIf', transclude: 'element', terminal: true, priority: 1000 },
|
||||
{ directiveName: 'boSwitch', require: 'boSwitch', controller: function () { this.cases = {}; } },
|
||||
{ directiveName: 'boSwitchWhen', transclude: 'element', priority: 800, require: '^boSwitch', },
|
||||
{ directiveName: 'boSwitchDefault', transclude: 'element', priority: 800, require: '^boSwitch', }
|
||||
],
|
||||
function (boDirective)
|
||||
{
|
||||
var childPriority = 200;
|
||||
return bindonceModule.directive(boDirective.directiveName, function ()
|
||||
{
|
||||
var bindonceDirective =
|
||||
{
|
||||
priority: boDirective.priority || childPriority,
|
||||
transclude: boDirective.transclude || false,
|
||||
terminal: boDirective.terminal || false,
|
||||
require: ['^bindonce'].concat(boDirective.require || []),
|
||||
controller: boDirective.controller,
|
||||
compile: function (tElement, tAttrs, transclude)
|
||||
{
|
||||
return function (scope, elm, attrs, controllers)
|
||||
{
|
||||
var bindonceController = controllers[0];
|
||||
var name = attrs.boParent;
|
||||
if (name && bindonceController.group !== name)
|
||||
{
|
||||
var element = bindonceController.element.parent();
|
||||
bindonceController = undefined;
|
||||
var parentValue;
|
||||
|
||||
while (element[0].nodeType !== 9 && element.length)
|
||||
{
|
||||
if ((parentValue = element.data('$bindonceController'))
|
||||
&& parentValue.group === name)
|
||||
{
|
||||
bindonceController = parentValue;
|
||||
break;
|
||||
}
|
||||
element = element.parent();
|
||||
}
|
||||
if (!bindonceController)
|
||||
{
|
||||
throw new Error("No bindonce controller: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
bindonceController.addBinder(
|
||||
{
|
||||
element: elm,
|
||||
attr: boDirective.attribute || boDirective.directiveName,
|
||||
attrs: attrs,
|
||||
value: attrs[boDirective.directiveName],
|
||||
interpolate: boDirective.interpolate,
|
||||
group: name,
|
||||
transclude: transclude,
|
||||
controller: controllers.slice(1),
|
||||
scope: scope
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return bindonceDirective;
|
||||
});
|
||||
})
|
||||
})();
|
1
src/bower_components/angular-bindonce/bindonce.min.js
vendored
Normal file
1
src/bower_components/angular-bindonce/bindonce.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!function(){"use strict";var e=angular.module("pasvaz.bindonce",[]);e.directive("bindonce",function(){var e=function(e){if(e&&0!==e.length){var t=angular.lowercase(""+e);e=!("f"===t||"0"===t||"false"===t||"no"===t||"n"===t||"[]"===t)}else e=!1;return e},t=parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent))||[])[1],10);isNaN(t)&&(t=parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent))||[])[1],10));var r={restrict:"AM",controller:["$scope","$element","$attrs","$interpolate",function(r,a,n,i){var c=function(t,r,a){var n="show"===r?"":"none",i="hide"===r?"":"none";t.css("display",e(a)?n:i)},o=function(e,t){if(angular.isObject(t)&&!angular.isArray(t)){var r=[];angular.forEach(t,function(e,t){e&&r.push(t)}),t=r}t&&e.addClass(angular.isArray(t)?t.join(" "):t)},s={watcherRemover:void 0,binders:[],group:n.boName,element:a,ran:!1,addBinder:function(e){this.binders.push(e),this.ran&&this.runBinders()},setupWatcher:function(e){var t=this;this.watcherRemover=r.$watch(e,function(e){void 0!==e&&(t.removeWatcher(),t.runBinders())},!0)},removeWatcher:function(){void 0!==this.watcherRemover&&(this.watcherRemover(),this.watcherRemover=void 0)},runBinders:function(){for(;this.binders.length>0;){var r=this.binders.shift();if(!this.group||this.group==r.group){var a=r.scope.$eval(r.interpolate?i(r.value):r.value);switch(r.attr){case"boIf":e(a)&&r.transclude(r.scope.$new(),function(e){var t=r.element.parent(),a=r.element&&r.element[r.element.length-1],n=t&&t[0]||a&&a.parentNode,i=a&&a.nextSibling||null;angular.forEach(e,function(e){n.insertBefore(e,i)})});break;case"boSwitch":var n,s=r.controller[0];(n=s.cases["!"+a]||s.cases["?"])&&(r.scope.$eval(r.attrs.change),angular.forEach(n,function(e){e.transclude(r.scope.$new(),function(t){var r=e.element.parent(),a=e.element&&e.element[e.element.length-1],n=r&&r[0]||a&&a.parentNode,i=a&&a.nextSibling||null;angular.forEach(t,function(e){n.insertBefore(e,i)})})}));break;case"boSwitchWhen":var l=r.controller[0];l.cases["!"+r.attrs.boSwitchWhen]=l.cases["!"+r.attrs.boSwitchWhen]||[],l.cases["!"+r.attrs.boSwitchWhen].push({transclude:r.transclude,element:r.element});break;case"boSwitchDefault":var l=r.controller[0];l.cases["?"]=l.cases["?"]||[],l.cases["?"].push({transclude:r.transclude,element:r.element});break;case"hide":case"show":c(r.element,r.attr,a);break;case"class":o(r.element,a);break;case"text":r.element.text(a);break;case"html":r.element.html(a);break;case"style":r.element.css(a);break;case"src":r.element.attr(r.attr,a),t&&r.element.prop("src",a);break;case"attr":angular.forEach(r.attrs,function(e,t){var a,n;t.match(/^boAttr./)&&r.attrs[t]&&(a=t.replace(/^boAttr/,"").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),n=r.scope.$eval(r.attrs[t]),r.element.attr(a,n))});break;case"href":case"alt":case"title":case"id":case"value":r.element.attr(r.attr,a)}}}this.ran=!0}};return s}],link:function(e,t,r,a){var n=r.bindonce?e.$eval(r.bindonce):!0;void 0!==n?n.then&&"function"==typeof n.then?n.then(function(){a.runBinders()}):a.runBinders():(a.setupWatcher(r.bindonce),t.bind("$destroy",a.removeWatcher))}};return r}),angular.forEach([{directiveName:"boShow",attribute:"show"},{directiveName:"boHide",attribute:"hide"},{directiveName:"boClass",attribute:"class"},{directiveName:"boText",attribute:"text"},{directiveName:"boBind",attribute:"text"},{directiveName:"boHtml",attribute:"html"},{directiveName:"boSrcI",attribute:"src",interpolate:!0},{directiveName:"boSrc",attribute:"src"},{directiveName:"boHrefI",attribute:"href",interpolate:!0},{directiveName:"boHref",attribute:"href"},{directiveName:"boAlt",attribute:"alt"},{directiveName:"boTitle",attribute:"title"},{directiveName:"boId",attribute:"id"},{directiveName:"boStyle",attribute:"style"},{directiveName:"boValue",attribute:"value"},{directiveName:"boAttr",attribute:"attr"},{directiveName:"boIf",transclude:"element",terminal:!0,priority:1e3},{directiveName:"boSwitch",require:"boSwitch",controller:function(){this.cases={}}},{directiveName:"boSwitchWhen",transclude:"element",priority:800,require:"^boSwitch"},{directiveName:"boSwitchDefault",transclude:"element",priority:800,require:"^boSwitch"}],function(t){var r=200;return e.directive(t.directiveName,function(){var e={priority:t.priority||r,transclude:t.transclude||!1,terminal:t.terminal||!1,require:["^bindonce"].concat(t.require||[]),controller:t.controller,compile:function(e,r,a){return function(e,r,n,i){var c=i[0],o=n.boParent;if(o&&c.group!==o){var s=c.element.parent();c=void 0;for(var l;9!==s[0].nodeType&&s.length;){if((l=s.data("$bindonceController"))&&l.group===o){c=l;break}s=s.parent()}if(!c)throw new Error("No bindonce controller: "+o)}c.addBinder({element:r,attr:t.attribute||t.directiveName,attrs:n,value:n[t.directiveName],interpolate:t.interpolate,group:o,transclude:a,controller:i.slice(1),scope:e})}}};return e})})}();
|
28
src/bower_components/angular-bindonce/bower.json
vendored
Normal file
28
src/bower_components/angular-bindonce/bower.json
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "angular-bindonce",
|
||||
"version": "0.3.1",
|
||||
"main": "bindonce.js",
|
||||
"description": "Zero watchers binding directives for AngularJS",
|
||||
"homepage": "https://github.com/Pasvaz/bindonce",
|
||||
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Pasvaz/bindonce.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {
|
||||
},
|
||||
"keywords": [
|
||||
"angularjs",
|
||||
"angular",
|
||||
"directive",
|
||||
"binding",
|
||||
"watcher",
|
||||
"bindonce"
|
||||
]
|
||||
}
|
28
src/bower_components/angular-bindonce/package.json
vendored
Normal file
28
src/bower_components/angular-bindonce/package.json
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "angular-bindonce",
|
||||
"version": "0.3.1",
|
||||
"main": "bindonce.js",
|
||||
"description": "Zero watchers binding directives for AngularJS",
|
||||
"homepage": "https://github.com/Pasvaz/bindonce",
|
||||
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Pasvaz/bindonce.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {
|
||||
},
|
||||
"keywords": [
|
||||
"angularjs",
|
||||
"angular",
|
||||
"directive",
|
||||
"binding",
|
||||
"watcher",
|
||||
"bindonce"
|
||||
]
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
<body ng-controller="kibana" ng-class="'application-'+activeApp">
|
||||
<kbn-notifications list="notifList"></kbn-notifications>
|
||||
<div class="content" style="display: none;">
|
||||
<nav class="navbar navbar-inverse navbar-static-top">
|
||||
<nav bindonce class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="container-fluid">
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-repeat="app in apps" ng-class="{active: activeApp == app.id}">
|
||||
<a href="#/{{app.id}}">{{app.name}}</a>
|
||||
<a href="#/{{app.id}}" bo-text="app.name"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<ul class="nav nav-pills nav-stacked nav-condensed">
|
||||
<ul bindonce class="nav nav-pills nav-stacked nav-condensed">
|
||||
<li ng-repeat="field in fields track by $index" ng-class="{'active':field.display}">
|
||||
<a ng-click="toggle(field.name)">
|
||||
<i class="fa" ng-class="typeIcon(field.type)"></i> {{field.name}}
|
||||
<i class="fa discovery-field-type" bo-class="typeIcon(field.type)"></i> <span bo-text="field.name"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a ng-click="refresh()"><small>refresh field list</small></a></li>
|
||||
|
|
|
@ -13,10 +13,12 @@ define(function (require) {
|
|||
|
||||
require('elasticsearch');
|
||||
require('angular-route');
|
||||
require('angular-bindonce');
|
||||
|
||||
var kibana = angular.module('kibana', [
|
||||
// list external requirements here
|
||||
'elasticsearch',
|
||||
'pasvaz.bindonce',
|
||||
'ngRoute'
|
||||
]);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ require.config({
|
|||
'angular-mocks': '../bower_components/angular-mocks/angular-mocks',
|
||||
'angular-route': '../bower_components/angular-route/angular-route',
|
||||
'angular-bootstrap': '../bower_components/angular-bootstrap/ui-bootstrap-tpls',
|
||||
'angular-bindonce': '../bower_components/angular-bindonce/bindonce',
|
||||
async: '../bower_components/async/lib/async',
|
||||
css: '../bower_components/require-css/css',
|
||||
text: '../bower_components/requirejs-text/text',
|
||||
|
@ -34,7 +35,8 @@ require.config({
|
|||
'angular-route': ['angular'],
|
||||
'angular-mocks': ['angular'],
|
||||
'elasticsearch': ['angular'],
|
||||
'angular-bootstrap': ['angular']
|
||||
'angular-bootstrap': ['angular'],
|
||||
'angular-bindonce': ['angular']
|
||||
},
|
||||
waitSeconds: 60
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue