UNPKG

117 kBJavaScriptView Raw
1/**
2@author leeluolee
3@version 0.2.12
4@homepage http://regularjs.github.io
5*/
6
7/**
8 * Require the given path.
9 *
10 * @param {String} path
11 * @return {Object} exports
12 * @api public
13 */
14
15function require(path, parent, orig) {
16 var resolved = require.resolve(path);
17
18 // lookup failed
19 if (null == resolved) {
20 throwError()
21 return
22 }
23
24 var module = require.modules[resolved];
25
26 // perform real require()
27 // by invoking the module's
28 // registered function
29 if (!module._resolving && !module.exports) {
30 var mod = {};
31 mod.exports = {};
32 mod.client = mod.component = true;
33 module._resolving = true;
34 module.call(this, mod.exports, require.relative(resolved), mod);
35 delete module._resolving;
36 module.exports = mod.exports;
37 }
38
39 function throwError () {
40 orig = orig || path;
41 parent = parent || 'root';
42 var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
43 err.path = orig;
44 err.parent = parent;
45 err.require = true;
46 throw err;
47 }
48
49 return module.exports;
50}
51
52/**
53 * Registered modules.
54 */
55
56require.modules = {};
57
58/**
59 * Registered aliases.
60 */
61
62require.aliases = {};
63
64/**
65 * Resolve `path`.
66 *
67 * Lookup:
68 *
69 * - PATH/index.js
70 * - PATH.js
71 * - PATH
72 *
73 * @param {String} path
74 * @return {String} path or null
75 * @api private
76 */
77
78require.exts = [
79 '',
80 '.js',
81 '.json',
82 '/index.js',
83 '/index.json'
84 ];
85
86require.resolve = function(path) {
87 if (path.charAt(0) === '/') path = path.slice(1);
88
89 for (var i = 0; i < 5; i++) {
90 var fullPath = path + require.exts[i];
91 if (require.modules.hasOwnProperty(fullPath)) return fullPath;
92 if (require.aliases.hasOwnProperty(fullPath)) return require.aliases[fullPath];
93 }
94};
95
96/**
97 * Normalize `path` relative to the current path.
98 *
99 * @param {String} curr
100 * @param {String} path
101 * @return {String}
102 * @api private
103 */
104
105require.normalize = function(curr, path) {
106
107 var segs = [];
108
109 if ('.' != path.charAt(0)) return path;
110
111 curr = curr.split('/');
112 path = path.split('/');
113
114 for (var i = 0; i < path.length; ++i) {
115 if ('..' === path[i]) {
116 curr.pop();
117 } else if ('.' != path[i] && '' != path[i]) {
118 segs.push(path[i]);
119 }
120 }
121 return curr.concat(segs).join('/');
122};
123
124/**
125 * Register module at `path` with callback `definition`.
126 *
127 * @param {String} path
128 * @param {Function} definition
129 * @api private
130 */
131
132require.register = function(path, definition) {
133 require.modules[path] = definition;
134};
135
136/**
137 * Alias a module definition.
138 *
139 * @param {String} from
140 * @param {String} to
141 * @api private
142 */
143
144require.alias = function(from, to) {
145 if (!require.modules.hasOwnProperty(from)) {
146 throwError()
147 return
148 }
149 require.aliases[to] = from;
150
151 function throwError () {
152 throw new Error('Failed to alias "' + from + '", it does not exist');
153 }
154};
155
156/**
157 * Return a require function relative to the `parent` path.
158 *
159 * @param {String} parent
160 * @return {Function}
161 * @api private
162 */
163
164require.relative = function(parent) {
165 var p = require.normalize(parent, '..');
166
167 /**
168 * The relative require() itself.
169 */
170
171 function localRequire(path) {
172 var resolved = localRequire.resolve(path);
173 return require(resolved, parent, path);
174 }
175
176 /**
177 * Resolve relative to the parent.
178 */
179
180 localRequire.resolve = function(path) {
181 var c = path.charAt(0);
182 if ('/' === c) return path.slice(1);
183 if ('.' === c) return require.normalize(p, path);
184
185 // resolve deps by returning
186 // the dep in the nearest "deps"
187 // directory
188 var segs = parent.split('/');
189 var i = segs.length;
190 while (i--) {
191 if (segs[i] === 'deps') {
192 break;
193 }
194 }
195 path = segs.slice(0, i + 2).join('/') + '/deps/' + path;
196 return path;
197 };
198
199 /**
200 * Check if module is defined at `path`.
201 */
202
203 localRequire.exists = function(path) {
204 return require.modules.hasOwnProperty(localRequire.resolve(path));
205 };
206
207 return localRequire;
208};
209require.register("regularjs/src/Regular.js", function(exports, require, module){
210
211var Lexer = require("./parser/Lexer.js");
212var Parser = require("./parser/Parser.js");
213var dom = require("./dom.js");
214var config = require("./config.js");
215var Group = require('./group.js');
216var _ = require('./util');
217var extend = require('./helper/extend.js');
218var Event = require('./helper/event.js');
219var combine = require('./helper/combine.js');
220var Watcher = require('./helper/watcher.js');
221var parse = require('./helper/parse.js');
222var doc = typeof document==='undefined'? {} : document;
223var env = require('./env.js');
224
225
226/**
227* `Regular` is regularjs's NameSpace and BaseClass. Every Component is inherited from it
228*
229* @class Regular
230* @module Regular
231* @constructor
232* @param {Object} options specification of the component
233*/
234var Regular = function(options){
235 var prevRunning = env.isRunning;
236 env.isRunning = true;
237 var node, template;
238
239 options = options || {};
240 options.data = options.data || {};
241 options.computed = options.computed || {};
242 if(this.data) _.extend(options.data, this.data);
243 if(this.computed) _.extend(options.computed, this.computed);
244 _.extend(this, options, true);
245 if(this.$parent){
246 this.$parent._append(this);
247 }
248 this._children = [];
249 this.$refs = {};
250
251 template = this.template;
252
253 // template is a string (len < 40). we will find it container first
254 if((typeof template === 'string' && template.length < 40) && (node = dom.find(template))) {
255 template = node.innerHTML;
256 }
257 // if template is a xml
258 if(template && template.nodeType) template = template.innerHTML;
259 if(typeof template === 'string') this.template = new Parser(template).parse();
260
261 this.computed = handleComputed(this.computed);
262 this.$context = this.$context || this;
263 this.$root = this.$root || this;
264 // if have events
265 if(this.events){
266 this.$on(this.events);
267 this.events = null;
268 }
269
270 this.config && this.config(this.data);
271 // handle computed
272 if(template){
273 this.group = this.$compile(this.template, {namespace: options.namespace});
274 combine.node(this);
275 }
276
277
278 if(this.$root === this) this.$update();
279 this.$ready = true;
280 if(this.$context === this) this.$emit("$init");
281 if( this.init ) this.init(this.data);
282
283 // @TODO: remove, maybe , there is no need to update after init;
284 // if(this.$root === this) this.$update();
285 env.isRunning = prevRunning;
286
287 // children is not required;
288}
289
290
291var walkers = require('./walkers.js');
292walkers.Regular = Regular;
293
294
295// description
296// -------------------------
297// 1. Regular and derived Class use same filter
298_.extend(Regular, {
299 // private data stuff
300 _directives: { __regexp__:[] },
301 _plugins: {},
302 _exprCache:{},
303 _running: false,
304 _config: config,
305 _protoInheritCache: ['use', 'directive'] ,
306 __after__: function(supr, o) {
307
308 var template;
309 this.__after__ = supr.__after__;
310
311 if(o.name) Regular.component(o.name, this);
312 if(template = o.template){
313 var node, name;
314 if( typeof template === 'string' && template.length < 20 && ( node = dom.find( template )) ){
315 template = node.innerHTML;
316 if(name = dom.attr(node, 'name')) Regular.component(name, this);
317 }
318
319 if(template.nodeType) template = template.innerHTML;
320
321 if(typeof template === 'string'){
322 this.prototype.template = new Parser(template).parse();
323 }
324 }
325
326 if(o.computed) this.prototype.computed = handleComputed(o.computed);
327 // inherit directive and other config from supr
328 Regular._inheritConfig(this, supr);
329
330 },
331 /**
332 * Define a directive
333 *
334 * @method directive
335 * @return {Object} Copy of ...
336 */
337 directive: function(name, cfg){
338
339 if(_.typeOf(name) === "object"){
340 for(var k in name){
341 if(name.hasOwnProperty(k)) this.directive(k, name[k]);
342 }
343 return this;
344 }
345 var type = _.typeOf(name);
346 var directives = this._directives, directive;
347 if(cfg == null){
348 if( type === "string" && (directive = directives[name]) ) return directive;
349 else{
350 var regexp = directives.__regexp__;
351 for(var i = 0, len = regexp.length; i < len ; i++){
352 directive = regexp[i];
353 var test = directive.regexp.test(name);
354 if(test) return directive;
355 }
356 }
357 return undefined;
358 }
359 if(typeof cfg === 'function') cfg = { link: cfg }
360 if(type === 'string') directives[name] = cfg;
361 else if(type === 'regexp'){
362 cfg.regexp = name;
363 directives.__regexp__.push(cfg)
364 }
365 return this
366 },
367 plugin: function(name, fn){
368 var plugins = this._plugins;
369 if(fn == null) return plugins[name];
370 plugins[name] = fn;
371 return this;
372 },
373 use: function(fn){
374 if(typeof fn === "string") fn = Regular.plugin(fn);
375 if(typeof fn !== "function") return this;
376 fn(this, Regular);
377 return this;
378 },
379 // config the Regularjs's global
380 config: function(name, value){
381 var needGenLexer = false;
382 if(typeof name === "object"){
383 for(var i in name){
384 // if you config
385 if( i ==="END" || i==='BEGIN' ) needGenLexer = true;
386 config[i] = name[i];
387 }
388 }
389 if(needGenLexer) Lexer.setup();
390 },
391 expression: parse.expression,
392 parse: parse.parse,
393
394 Parser: Parser,
395 Lexer: Lexer,
396
397 _addProtoInheritCache: function(name){
398 if( Array.isArray( name ) ){
399 return name.forEach(Regular._addProtoInheritCache);
400 }
401 var cacheKey = "_" + name + "s"
402 Regular._protoInheritCache.push(name)
403 Regular[cacheKey] = {};
404 Regular[name] = function(key, cfg){
405 var cache = this[cacheKey];
406
407 if(typeof key === "object"){
408 for(var i in key){
409 if(key.hasOwnProperty(i)) this[name](i, key[i]);
410 }
411 return this;
412 }
413 if(cfg == null) return cache[key];
414 cache[key] = cfg;
415 return this;
416 }
417 },
418 _inheritConfig: function(self, supr){
419
420 // prototype inherit some Regular property
421 // so every Component will have own container to serve directive, filter etc..
422 var defs = Regular._protoInheritCache;
423 var keys = _.slice(defs);
424 keys.forEach(function(key){
425 self[key] = supr[key];
426 var cacheKey = '_' + key + 's';
427 if(supr[cacheKey]) self[cacheKey] = _.createObject(supr[cacheKey]);
428 })
429 return self;
430 }
431
432});
433
434extend(Regular);
435
436Regular._addProtoInheritCache(["filter", "component"])
437
438
439Event.mixTo(Regular);
440Watcher.mixTo(Regular);
441
442Regular.implement({
443 init: function(){},
444 config: function(){},
445 destroy: function(){
446 // destroy event wont propgation;
447 if(this.$context === this) this.$emit("$destroy");
448 this.group && this.group.destroy(true);
449 this.group = null;
450 this.parentNode = null;
451 this._watchers = null;
452 this._children = [];
453 var parent = this.$parent;
454 if(parent){
455 var index = parent._children.indexOf(this);
456 parent._children.splice(index,1);
457 }
458 this.$parent = null;
459 this.$root = null;
460 this._handles = null;
461 this.$refs = null;
462 },
463
464 /**
465 * compile a block ast ; return a group;
466 * @param {Array} parsed ast
467 * @param {[type]} record
468 * @return {[type]}
469 */
470 $compile: function(ast, options){
471 options = options || {};
472 if(typeof ast === 'string'){
473 ast = new Parser(ast).parse()
474 }
475 var preNs = this.__ns__,
476 record = options.record,
477 records;
478 if(options.namespace) this.__ns__ = options.namespace;
479 if(record) this._record();
480 var group = this._walk(ast, options);
481 if(record){
482 records = this._release();
483 var self = this;
484 if(records.length){
485 // auto destroy all wather;
486 group.ondestroy = function(){ self.$unwatch(records); }
487 }
488 }
489 if(options.namespace) this.__ns__ = preNs;
490 return group;
491 },
492
493
494 /**
495 * create two-way binding with another component;
496 * *warn*:
497 * expr1 and expr2 must can operate set&get, for example: the 'a.b' or 'a[b + 1]' is set-able, but 'a.b + 1' is not,
498 * beacuse Regular dont know how to inverse set through the expression;
499 *
500 * if before $bind, two component's state is not sync, the component(passed param) will sync with the called component;
501 *
502 * *example: *
503 *
504 * ```javascript
505 * // in this example, we need to link two pager component
506 * var pager = new Pager({}) // pager compoennt
507 * var pager2 = new Pager({}) // another pager component
508 * pager.$bind(pager2, 'current'); // two way bind throw two component
509 * pager.$bind(pager2, 'total'); //
510 * // or just
511 * pager.$bind(pager2, {"current": "current", "total": "total"})
512 * ```
513 *
514 * @param {Regular} component the
515 * @param {String|Expression} expr1 required, self expr1 to operate binding
516 * @param {String|Expression} expr2 optional, other component's expr to bind with, if not passed, the expr2 will use the expr1;
517 * @return this;
518 */
519 $bind: function(component, expr1, expr2){
520 var type = _.typeOf(expr1);
521 if( expr1.type === 'expression' || type === 'string' ){
522 this._bind(component, expr1, expr2)
523 }else if( type === "array" ){ // multiply same path binding through array
524 for(var i = 0, len = expr1.length; i < len; i++){
525 this._bind(component, expr1[i]);
526 }
527 }else if(type === "object"){
528 for(var i in expr1) if(expr1.hasOwnProperty(i)){
529 this._bind(component, i, expr1[i]);
530 }
531 }
532 // digest
533 component.$update();
534 return this;
535 },
536 /**
537 * unbind one component( see $bind also)
538 *
539 * unbind will unbind all relation between two component
540 *
541 * @param {Regular} component [description]
542 * @return {This} this
543 */
544 $unbind: function(){
545 // todo
546 },
547 $get: function(expr){
548 return parse.expression(expr).get(this);
549 },
550 $inject: function(node, position){
551 var fragment = combine.node(this);
552 if(typeof node === 'string') node = dom.find(node);
553 if(!node) throw 'injected node is not found';
554 if(!fragment) return;
555 dom.inject(fragment, node, position);
556 this.$emit("$inject", node);
557 this.parentNode = Array.isArray(fragment)? fragment[0].parentNode: fragment.parentNode;
558 return this;
559 },
560 // private bind logic
561 _bind: function(component, expr1, expr2){
562
563 var self = this;
564 // basic binding
565
566 if(!component || !(component instanceof Regular)) throw "$bind() should pass Regular component as first argument";
567 if(!expr1) throw "$bind() should pass as least one expression to bind";
568
569 if(!expr2) expr2 = expr1;
570
571 expr1 = parse.expression( expr1 );
572 expr2 = parse.expression( expr2 );
573
574 // set is need to operate setting ;
575 if(expr2.set){
576 var wid1 = this.$watch( expr1, function(value){
577 component.$update(expr2, value)
578 });
579 component.$on('$destroy', function(){
580 self.$unwatch(wid1)
581 })
582 }
583 if(expr1.set){
584 var wid2 = component.$watch(expr2, function(value){
585 self.$update(expr1, value)
586 });
587 // when brother destroy, we unlink this watcher
588 this.$on('$destroy', component.$unwatch.bind(component,wid2))
589 }
590 // sync the component's state to called's state
591 expr2.set(component, expr1.get(this));
592 },
593 _walk: function(ast, arg1){
594 if( _.typeOf(ast) === 'array' ){
595 var res = [];
596
597 for(var i = 0, len = ast.length; i < len; i++){
598 res.push( this._walk(ast[i], arg1) );
599 }
600
601 return new Group(res);
602 }
603 if(typeof ast === 'string') return doc.createTextNode(ast)
604 return walkers[ast.type || "default"].call(this, ast, arg1);
605 },
606 _append: function(component){
607 this._children.push(component);
608 component.$root = this.$root;
609 component.$parent = this;
610 },
611 _handleEvent: function(elem, type, value, attrs){
612 var Component = this.constructor,
613 fire = typeof value !== "function"? _.handleEvent.call( this, value, type ) : value,
614 handler = Component.event(type), destroy;
615
616 if ( handler ) {
617 destroy = handler.call(this, elem, fire, attrs);
618 } else {
619 dom.on(elem, type, fire);
620 }
621 return handler ? destroy : function() {
622 dom.off(elem, type, fire);
623 }
624 },
625 // find filter
626 _f_: function(name){
627 var Component = this.constructor;
628 var filter = Component.filter(name);
629 if(typeof filter !== 'function') throw 'filter ' + name + 'is undefined';
630 return filter;
631 },
632 // simple accessor get
633 _sg_:function(path, defaults){
634 var computed = this.computed,
635 computedProperty = computed[path];
636 if(computedProperty){
637 if(computedProperty.get) return computedProperty.get(this);
638 else _.log("the computed '" + path + "' don't define the get function, get data."+path + " altnately", "error")
639 }
640 return defaults;
641
642 },
643 // simple accessor set
644 _ss_:function(path, value, data, op){
645 var computed = this.computed,
646 op = op || "=",
647 computedProperty = computed[path],
648 prev;
649
650 if(op!== '='){
651 prev = computedProperty? computedProperty.get(this): data[path];
652 switch(op){
653 case "+=":
654 value = prev + value;
655 break;
656 case "-=":
657 value = prev - value;
658 break;
659 case "*=":
660 value = prev * value;
661 break;
662 case "/=":
663 value = prev / value;
664 break;
665 case "%=":
666 value = prev % value;
667 break;
668 }
669 }
670
671 if(computedProperty) {
672 if(computedProperty.set) return computedProperty.set(this, value);
673 else _.log("the computed '" + path + "' don't define the set function, assign data."+path + " altnately", "error" )
674 }
675 data[path] = value;
676 return value;
677 }
678});
679
680Regular.prototype.inject = Regular.prototype.$inject;
681
682module.exports = Regular;
683
684
685
686var handleComputed = (function(){
687 // wrap the computed getter;
688 function wrapGet(get){
689 return function(context){
690 var ctx = context.$context;
691 return get.call(ctx, ctx.data );
692 }
693 }
694 // wrap the computed setter;
695 function wrapSet(set){
696 return function(context, value){
697 var ctx = context.$context;
698 set.call( ctx, value, ctx.data );
699 return value;
700 }
701 }
702
703 return function(computed){
704 if(!computed) return;
705 var parsedComputed = {}, handle, pair, type;
706 for(var i in computed){
707 handle = computed[i]
708 type = typeof handle;
709
710 if(handle.type === 'expression'){
711 parsedComputed[i] = handle;
712 continue;
713 }
714 if( type === "string" ){
715 parsedComputed[i] = parse.expression(handle)
716 }else{
717 pair = parsedComputed[i] = {type: 'expression'};
718 if(type === "function" ){
719 pair.get = wrapGet(handle);
720 }else{
721 if(handle.get) pair.get = wrapGet(handle.get);
722 if(handle.set) pair.set = wrapSet(handle.set);
723 }
724 }
725 }
726 return parsedComputed;
727 }
728})();
729
730});
731require.register("regularjs/src/util.js", function(exports, require, module){
732require('./helper/shim.js');
733var _ = module.exports;
734var entities = require('./helper/entities.js');
735var slice = [].slice;
736var o2str = ({}).toString;
737var win = typeof window !=='undefined'? window: global;
738
739
740_.noop = function(){};
741_.uid = (function(){
742 var _uid=0;
743 return function(){
744 return _uid++;
745 }
746})();
747
748_.varName = '_d_';
749_.setName = '_p_';
750_.ctxName = '_c_';
751
752_.rWord = /^[\$\w]+$/;
753_.rSimpleAccessor = /^[\$\w]+(\.[\$\w]+)*$/;
754
755_.nextTick = typeof setImmediate === 'function'?
756 setImmediate.bind(win) :
757 function(callback) {
758 setTimeout(callback, 0)
759 }
760
761
762
763var prefix = "var " + _.ctxName + "=context.$context||context;" + "var " + _.varName + "=context.data;";
764
765
766_.host = "data";
767
768
769_.slice = function(obj, start, end){
770 var res = [];
771 for(var i = start || 0, len = end || obj.length; i < len; i++){
772 var item = obj[i];
773 res.push(item)
774 }
775 return res;
776}
777
778_.typeOf = function (o) {
779 return o == null ? String(o) : ({}).toString.call(o).slice(8, -1).toLowerCase();
780}
781
782
783_.extend = function( o1, o2, override ){
784 if(_.typeOf(override) === 'array'){
785 for(var i = 0, len = override.length; i < len; i++ ){
786 var key = override[i];
787 o1[key] = o2[key];
788 }
789 }else{
790 for(var i in o2){
791 if( typeof o1[i] === "undefined" || override === true ){
792 o1[i] = o2[i]
793 }
794 }
795 }
796 return o1;
797}
798
799_.makePredicate = function makePredicate(words, prefix) {
800 if (typeof words === "string") {
801 words = words.split(" ");
802 }
803 var f = "",
804 cats = [];
805 out: for (var i = 0; i < words.length; ++i) {
806 for (var j = 0; j < cats.length; ++j){
807 if (cats[j][0].length === words[i].length) {
808 cats[j].push(words[i]);
809 continue out;
810 }
811 }
812 cats.push([words[i]]);
813 }
814 function compareTo(arr) {
815 if (arr.length === 1) return f += "return str === '" + arr[0] + "';";
816 f += "switch(str){";
817 for (var i = 0; i < arr.length; ++i){
818 f += "case '" + arr[i] + "':";
819 }
820 f += "return true}return false;";
821 }
822
823 // When there are more than three length categories, an outer
824 // switch first dispatches on the lengths, to save on comparisons.
825 if (cats.length > 3) {
826 cats.sort(function(a, b) {
827 return b.length - a.length;
828 });
829 f += "switch(str.length){";
830 for (var i = 0; i < cats.length; ++i) {
831 var cat = cats[i];
832 f += "case " + cat[0].length + ":";
833 compareTo(cat);
834 }
835 f += "}";
836
837 // Otherwise, simply generate a flat `switch` statement.
838 } else {
839 compareTo(words);
840 }
841 return new Function("str", f);
842}
843
844
845_.trackErrorPos = (function (){
846 // linebreak
847 var lb = /\r\n|[\n\r\u2028\u2029]/g;
848 function findLine(lines, pos){
849 var tmpLen = 0;
850 for(var i = 0,len = lines.length; i < len; i++){
851 var lineLen = (lines[i] || "").length;
852 if(tmpLen + lineLen > pos) return {num: i, line: lines[i], start: pos - tmpLen};
853 // 1 is for the linebreak
854 tmpLen = tmpLen + lineLen + 1;
855 }
856
857 }
858 return function(input, pos){
859 if(pos > input.length-1) pos = input.length-1;
860 lb.lastIndex = 0;
861 var lines = input.split(lb);
862 var line = findLine(lines,pos);
863 var len = line.line.length;
864
865 var min = line.start - 10;
866 if(min < 0) min = 0;
867
868 var max = line.start + 10;
869 if(max > len) max = len;
870
871 var remain = line.line.slice(min, max);
872 var prefix = (line.num+1) + "> " + (min > 0? "..." : "")
873 var postfix = max < len ? "...": "";
874
875 return prefix + remain + postfix + "\n" + new Array(line.start + prefix.length + 1).join(" ") + "^";
876 }
877})();
878
879
880var ignoredRef = /\((\?\!|\?\:|\?\=)/g;
881_.findSubCapture = function (regStr) {
882 var left = 0,
883 right = 0,
884 len = regStr.length,
885 ignored = regStr.match(ignoredRef); // ignored uncapture
886 if(ignored) ignored = ignored.length
887 else ignored = 0;
888 for (; len--;) {
889 var letter = regStr.charAt(len);
890 if (len === 0 || regStr.charAt(len - 1) !== "\\" ) {
891 if (letter === "(") left++;
892 if (letter === ")") right++;
893 }
894 }
895 if (left !== right) throw "RegExp: "+ regStr + "'s bracket is not marched";
896 else return left - ignored;
897};
898
899
900_.escapeRegExp = function( str){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
901 return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
902 return '\\' + match;
903 });
904};
905
906
907var rEntity = new RegExp("&(" + Object.keys(entities).join('|') + ');', 'gi');
908
909_.convertEntity = function(chr){
910
911 return ("" + chr).replace(rEntity, function(all, capture){
912 return String.fromCharCode(entities[capture])
913 });
914
915}
916
917
918// simple get accessor
919
920_.createObject = function(o, props){
921 function Foo() {}
922 Foo.prototype = o;
923 var res = new Foo;
924 if(props) _.extend(res, props);
925 return res;
926}
927
928_.createProto = function(fn, o){
929 function Foo() { this.constructor = fn;}
930 Foo.prototype = o;
931 return (fn.prototype = new Foo());
932}
933
934
935/**
936clone
937*/
938_.clone = function clone(obj){
939 var type = _.typeOf(obj);
940 if(type === 'array'){
941 var cloned = [];
942 for(var i=0,len = obj.length; i< len;i++){
943 cloned[i] = obj[i]
944 }
945 return cloned;
946 }
947 if(type === 'object'){
948 var cloned = {};
949 for(var i in obj) if(obj.hasOwnProperty(i)){
950 cloned[i] = obj[i];
951 }
952 return cloned;
953 }
954 return obj;
955 }
956
957
958_.equals = function(now, old){
959 var type = _.typeOf(now);
960 if(type === 'array'){
961 var splices = ld(now, old||[]);
962 return splices;
963 }
964 if(type === 'number' && typeof old === 'number'&& isNaN(now) && isNaN(old)) return true
965 return now === old;
966}
967
968
969//Levenshtein_distance
970//=================================================
971//1. http://en.wikipedia.org/wiki/Levenshtein_distance
972//2. github.com:polymer/observe-js
973
974var ld = (function(){
975 function equals(a,b){
976 return a === b;
977 }
978 function ld(array1, array2){
979 var n = array1.length;
980 var m = array2.length;
981 var matrix = [];
982 for(var i = 0; i <= n; i++){
983 matrix.push([i]);
984 }
985 for(var j=1;j<=m;j++){
986 matrix[0][j]=j;
987 }
988 for(var i = 1; i <= n; i++){
989 for(var j = 1; j <= m; j++){
990 if(equals(array1[i-1], array2[j-1])){
991 matrix[i][j] = matrix[i-1][j-1];
992 }else{
993 matrix[i][j] = Math.min(
994 matrix[i-1][j]+1, //delete
995 matrix[i][j-1]+1//add
996 )
997 }
998 }
999 }
1000 return matrix;
1001 }
1002 function whole(arr2, arr1) {
1003 var matrix = ld(arr1, arr2)
1004 var n = arr1.length;
1005 var i = n;
1006 var m = arr2.length;
1007 var j = m;
1008 var edits = [];
1009 var current = matrix[i][j];
1010 while(i>0 || j>0){
1011 // the last line
1012 if (i === 0) {
1013 edits.unshift(3);
1014 j--;
1015 continue;
1016 }
1017 // the last col
1018 if (j === 0) {
1019 edits.unshift(2);
1020 i--;
1021 continue;
1022 }
1023 var northWest = matrix[i - 1][j - 1];
1024 var west = matrix[i - 1][j];
1025 var north = matrix[i][j - 1];
1026
1027 var min = Math.min(north, west, northWest);
1028
1029 if (min === west) {
1030 edits.unshift(2); //delete
1031 i--;
1032 current = west;
1033 } else if (min === northWest ) {
1034 if (northWest === current) {
1035 edits.unshift(0); //no change
1036 } else {
1037 edits.unshift(1); //update
1038 current = northWest;
1039 }
1040 i--;
1041 j--;
1042 } else {
1043 edits.unshift(3); //add
1044 j--;
1045 current = north;
1046 }
1047 }
1048 var LEAVE = 0;
1049 var ADD = 3;
1050 var DELELE = 2;
1051 var UPDATE = 1;
1052 var n = 0;m=0;
1053 var steps = [];
1054 var step = {index: null, add:0, removed:[]};
1055
1056 for(var i=0;i<edits.length;i++){
1057 if(edits[i] > 0 ){ // NOT LEAVE
1058 if(step.index === null){
1059 step.index = m;
1060 }
1061 } else { //LEAVE
1062 if(step.index != null){
1063 steps.push(step)
1064 step = {index: null, add:0, removed:[]};
1065 }
1066 }
1067 switch(edits[i]){
1068 case LEAVE:
1069 n++;
1070 m++;
1071 break;
1072 case ADD:
1073 step.add++;
1074 m++;
1075 break;
1076 case DELELE:
1077 step.removed.push(arr1[n])
1078 n++;
1079 break;
1080 case UPDATE:
1081 step.add++;
1082 step.removed.push(arr1[n])
1083 n++;
1084 m++;
1085 break;
1086 }
1087 }
1088 if(step.index != null){
1089 steps.push(step)
1090 }
1091 return steps
1092 }
1093 return whole;
1094 })();
1095
1096
1097
1098_.throttle = function throttle(func, wait){
1099 var wait = wait || 100;
1100 var context, args, result;
1101 var timeout = null;
1102 var previous = 0;
1103 var later = function() {
1104 previous = +new Date;
1105 timeout = null;
1106 result = func.apply(context, args);
1107 context = args = null;
1108 };
1109 return function() {
1110 var now = + new Date;
1111 var remaining = wait - (now - previous);
1112 context = this;
1113 args = arguments;
1114 if (remaining <= 0 || remaining > wait) {
1115 clearTimeout(timeout);
1116 timeout = null;
1117 previous = now;
1118 result = func.apply(context, args);
1119 context = args = null;
1120 } else if (!timeout) {
1121 timeout = setTimeout(later, remaining);
1122 }
1123 return result;
1124 };
1125};
1126
1127// hogan escape
1128// ==============
1129_.escape = (function(){
1130 var rAmp = /&/g,
1131 rLt = /</g,
1132 rGt = />/g,
1133 rApos = /\'/g,
1134 rQuot = /\"/g,
1135 hChars = /[&<>\"\']/;
1136
1137 return function(str) {
1138 return hChars.test(str) ?
1139 str
1140 .replace(rAmp, '&amp;')
1141 .replace(rLt, '&lt;')
1142 .replace(rGt, '&gt;')
1143 .replace(rApos, '&#39;')
1144 .replace(rQuot, '&quot;') :
1145 str;
1146 }
1147})();
1148
1149_.cache = function(max){
1150 max = max || 1000;
1151 var keys = [],
1152 cache = {};
1153 return {
1154 set: function(key, value) {
1155 if (keys.length > this.max) {
1156 cache[keys.shift()] = undefined;
1157 }
1158 //
1159 if(cache[key] === undefined){
1160 keys.push(key);
1161 }
1162 cache[key] = value;
1163 return value;
1164 },
1165 get: function(key) {
1166 if (key === undefined) return cache;
1167 return cache[key];
1168 },
1169 max: max,
1170 len:function(){
1171 return keys.length;
1172 }
1173 };
1174}
1175
1176// setup the raw Expression
1177_.touchExpression = function(expr){
1178 if(expr.type === 'expression'){
1179 if(!expr.get){
1180 expr.get = new Function("context", prefix + "return (" + expr.body + ")");
1181 expr.body = null;
1182 if(expr.setbody){
1183 expr.set = function(ctx, value){
1184 if(expr.setbody){
1185 expr.set = new Function('context', _.setName , prefix + expr.setbody);
1186 expr.setbody = null;
1187 }
1188 return expr.set(ctx, value);
1189 }
1190 }
1191 }
1192 }
1193 return expr;
1194}
1195
1196
1197// handle the same logic on component's `on-*` and element's `on-*`
1198// return the fire object
1199_.handleEvent = function(value, type ){
1200 var self = this, evaluate;
1201 if(value.type === 'expression'){ // if is expression, go evaluated way
1202 evaluate = value.get;
1203 }
1204 if(evaluate){
1205 return function fire(obj){
1206 self.data.$event = obj;
1207 var res = evaluate(self);
1208 if(res === false && obj && obj.preventDefault) obj.preventDefault();
1209 delete self.data.$event;
1210 self.$update();
1211 }
1212 }else{
1213 return function fire(){
1214 var args = slice.call(arguments)
1215 args.unshift(value);
1216 self.$emit.apply(self.$context, args);
1217 self.$update();
1218 }
1219 }
1220}
1221
1222// only call once
1223_.once = function(fn){
1224 var time = 0;
1225 return function(){
1226 if( time++ === 0) fn.apply(this, arguments);
1227 }
1228}
1229
1230
1231
1232
1233
1234
1235
1236
1237_.log = function(msg, type){
1238 if(typeof console !== "undefined") console[type || "log"](msg);
1239}
1240
1241
1242
1243
1244//http://www.w3.org/html/wg/drafts/html/master/single-page.html#void-elements
1245_.isVoidTag = _.makePredicate("area base br col embed hr img input keygen link menuitem meta param source track wbr r-content");
1246_.isBooleanAttr = _.makePredicate('selected checked disabled readOnly required open autofocus controls autoplay compact loop defer multiple');
1247
1248_.isFalse - function(){return false}
1249_.isTrue - function(){return true}
1250
1251
1252_.assert = function(test, msg){
1253 if(!test) throw msg;
1254}
1255
1256
1257
1258_.defineProperty = function(){
1259
1260}
1261
1262
1263});
1264require.register("regularjs/src/walkers.js", function(exports, require, module){
1265var node = require("./parser/node.js");
1266var dom = require("./dom.js");
1267var animate = require("./helper/animate.js");
1268var Group = require('./group.js');
1269var _ = require('./util');
1270var combine = require('./helper/combine.js');
1271
1272var walkers = module.exports = {};
1273
1274walkers.list = function(ast){
1275
1276 var Regular = walkers.Regular;
1277 var placeholder = document.createComment("Regular list"),
1278 namespace = this.__ns__;
1279 // proxy Component to implement list item, so the behaviar is similar with angular;
1280 var Section = Regular.extend( {
1281 template: ast.body,
1282 $context: this.$context,
1283 // proxy the event to $context
1284 $on: this.$context.$on.bind(this.$context),
1285 $off: this.$context.$off.bind(this.$context),
1286 $emit: this.$context.$emit.bind(this.$context)
1287 });
1288 Regular._inheritConfig(Section, this.constructor);
1289
1290 // var fragment = dom.fragment();
1291 // fragment.appendChild(placeholder);
1292 var self = this;
1293 var group = new Group();
1294 group.push(placeholder);
1295 var indexName = ast.variable + '_index';
1296 var variable = ast.variable;
1297 // group.push(placeholder);
1298
1299
1300 function update(newValue, splices){
1301 newValue = newValue || [];
1302 if(!splices || !splices.length) return;
1303 var cur = placeholder;
1304 var m = 0, len = newValue.length,
1305 mIndex = splices[0].index;
1306
1307 for(var i = 0; i < splices.length; i++){ //init
1308 var splice = splices[i];
1309 var index = splice.index; // beacuse we use a comment for placeholder
1310
1311 for(var k = m; k < index; k++){ // no change
1312 var sect = group.get( k + 1 );
1313 sect.data[indexName] = k;
1314 }
1315 for(var j = 0, jlen = splice.removed.length; j< jlen; j++){ //removed
1316 var removed = group.children.splice( index + 1, 1)[0];
1317 removed.destroy(true);
1318 }
1319
1320 for(var o = index; o < index + splice.add; o++){ //add
1321 // prototype inherit
1322 var item = newValue[o];
1323 var data = _.createObject(self.data);
1324 data[indexName] = o;
1325 data[variable] = item;
1326
1327 //@TODO
1328 var section = new Section({data: data, $parent: self , namespace: namespace});
1329
1330
1331 // autolink
1332 var insert = combine.last(group.get(o));
1333 // animate.inject(combine.node(section),insert,'after')
1334 if(insert.parentNode){
1335 animate.inject(combine.node(section),insert, 'after');
1336 }
1337 // insert.parentNode.insertBefore(combine.node(section), insert.nextSibling);
1338 group.children.splice( o + 1 , 0, section);
1339 }
1340 m = index + splice.add - splice.removed.length;
1341 m = m < 0? 0 : m;
1342
1343 }
1344 if(m < len){
1345 for(var i = m; i < len; i++){
1346 var pair = group.get(i + 1);
1347 pair.data[indexName] = i;
1348 }
1349 }
1350 }
1351
1352 this.$watch(ast.sequence, update, { init: true });
1353 return group;
1354}
1355
1356walkers.template = function(ast){
1357 var content = ast.content, compiled;
1358 var placeholder = document.createComment('template');
1359 var compiled, namespace = this.__ns__;
1360 // var fragment = dom.fragment();
1361 // fragment.appendChild(placeholder);
1362 var group = new Group();
1363 group.push(placeholder);
1364 if(content){
1365 var self = this;
1366 this.$watch(content, function(value){
1367 if( compiled = group.get(1)){
1368 compiled.destroy(true);
1369 group.children.pop();
1370 }
1371 group.push( compiled = self.$compile(value, {record: true, namespace: namespace}) );
1372 if(placeholder.parentNode) animate.inject(combine.node(compiled), placeholder, 'before')
1373 }, {
1374 init: true
1375 });
1376 }
1377 return group;
1378};
1379
1380
1381// how to resolve this problem
1382var ii = 0;
1383walkers['if'] = function(ast, options){
1384 var self = this, consequent, alternate;
1385 if(options && options.element){ // attribute inteplation
1386 var update = function(nvalue){
1387 if(!!nvalue){
1388 if(alternate) combine.destroy(alternate)
1389 if(ast.consequent) consequent = self.$compile(ast.consequent, {record: true, element: options.element });
1390 }else{
1391 if(consequent) combine.destroy(consequent)
1392 if(ast.alternate) alternate = self.$compile(ast.alternate, {record: true, element: options.element});
1393 }
1394 }
1395 this.$watch(ast.test, update, { force: true });
1396 return {
1397 destroy: function(){
1398 if(consequent) combine.destroy(consequent);
1399 else if(alternate) combine.destroy(alternate);
1400 }
1401 }
1402 }
1403
1404
1405 var test, consequent, alternate, node;
1406 var placeholder = document.createComment("Regular if" + ii++);
1407 var group = new Group();
1408 group.push(placeholder);
1409 var preValue = null, namespace= this.__ns__;
1410
1411
1412 var update = function (nvalue, old){
1413 var value = !!nvalue;
1414 if(value === preValue) return;
1415 preValue = value;
1416 if(group.children[1]){
1417 group.children[1].destroy(true);
1418 group.children.pop();
1419 }
1420 if(value){ //true
1421 if(ast.consequent && ast.consequent.length){
1422 consequent = self.$compile( ast.consequent , {record:true, namespace: namespace })
1423 // placeholder.parentNode && placeholder.parentNode.insertBefore( node, placeholder );
1424 group.push(consequent);
1425 if(placeholder.parentNode){
1426 animate.inject(combine.node(consequent), placeholder, 'before');
1427 }
1428 }
1429 }else{ //false
1430 if(ast.alternate && ast.alternate.length){
1431 alternate = self.$compile(ast.alternate, {record:true, namespace: namespace});
1432 group.push(alternate);
1433 if(placeholder.parentNode){
1434 animate.inject(combine.node(alternate), placeholder, 'before');
1435 }
1436 }
1437 }
1438 }
1439 this.$watch(ast.test, update, {force: true, init: true});
1440
1441 return group;
1442}
1443
1444
1445walkers.expression = function(ast){
1446 var node = document.createTextNode("");
1447 this.$watch(ast, function(newval){
1448 dom.text(node, "" + (newval == null? "": "" + newval) );
1449 })
1450 return node;
1451}
1452walkers.text = function(ast){
1453 var node = document.createTextNode(_.convertEntity(ast.text));
1454 return node;
1455}
1456
1457
1458var eventReg = /^on-(.+)$/
1459
1460/**
1461 * walkers element (contains component)
1462 */
1463walkers.element = function(ast){
1464 var attrs = ast.attrs,
1465 component, self = this,
1466 Constructor=this.constructor,
1467 children = ast.children,
1468 namespace = this.__ns__, ref, group,
1469 Component = Constructor.component(ast.tag);
1470
1471
1472 if(ast.tag === 'svg') var namespace = "svg";
1473
1474
1475 if(children && children.length){
1476 group = this.$compile(children, {namespace: namespace });
1477 }
1478
1479
1480 if(Component){
1481 var data = {},events;
1482 for(var i = 0, len = attrs.length; i < len; i++){
1483 var attr = attrs[i];
1484 var value = attr.value||"";
1485 _.touchExpression(value);
1486 var name = attr.name;
1487 var etest = name.match(eventReg);
1488 // bind event proxy
1489 if(etest){
1490 events = events || {};
1491 events[etest[1]] = _.handleEvent.call(this, value, etest[1]);
1492 continue;
1493 }
1494
1495 if(value.type !== 'expression'){
1496 data[attr.name] = value;
1497 }else{
1498 data[attr.name] = value.get(self);
1499 }
1500 if( attr.name === 'ref' && value != null){
1501 ref = value.type === 'expression'? value.get(self): value;
1502 }
1503
1504 }
1505
1506 var $body;
1507 if(ast.children) $body = this.$compile(ast.children);
1508 var component = new Component({data: data, events: events, $body: $body, $parent: this, namespace: namespace});
1509 if(ref && self.$context.$refs) self.$context.$refs[ref] = component;
1510 for(var i = 0, len = attrs.length; i < len; i++){
1511 var attr = attrs[i];
1512 var value = attr.value||"";
1513 if(value.type === 'expression' && attr.name.indexOf('on-')===-1){
1514 this.$watch(value, component.$update.bind(component, attr.name))
1515 if(value.set) component.$watch(attr.name, self.$update.bind(self, value))
1516 }
1517 }
1518 if(ref){
1519 component.$on('destroy', function(){
1520 if(self.$context.$refs) self.$context.$refs[ref] = null;
1521 })
1522 }
1523 return component;
1524 }else if(ast.tag === 'r-content' && this.$body){
1525 return this.$body;
1526 }
1527
1528 var element = dom.create(ast.tag, namespace, attrs);
1529 // context element
1530
1531 var child;
1532
1533 if(group && !_.isVoidTag(ast.tag)){
1534 dom.inject( combine.node(group) , element)
1535 }
1536
1537 // sort before
1538 attrs.sort(function(a1, a2){
1539 var d1 = Constructor.directive(a1.name),
1540 d2 = Constructor.directive(a2.name);
1541 if(d1 && d2) return (d2.priority || 1) - (d1.priority || 1);
1542 if(d1) return 1;
1543 if(d2) return -1;
1544 if(a2.name === "type") return 1;
1545 return -1;
1546 })
1547 // may distinct with if else
1548 var destroies = walkAttributes.call(this, attrs, element, destroies);
1549
1550
1551
1552 var res = {
1553 type: "element",
1554 group: group,
1555 node: function(){
1556 return element;
1557 },
1558 last: function(){
1559 return element;
1560 },
1561 destroy: function(first){
1562 if( first ){
1563 animate.remove( element, group? group.destroy.bind( group ): _.noop );
1564 }
1565 // destroy ref
1566 if( destroies.length ) {
1567 destroies.forEach(function( destroy ){
1568 if( destroy ){
1569 if( typeof destroy.destroy === 'function' ){
1570 destroy.destroy()
1571 }else{
1572 destroy();
1573 }
1574 }
1575 })
1576 }
1577 }
1578 }
1579 return res;
1580}
1581
1582function walkAttributes(attrs, element){
1583 var bindings = []
1584 for(var i = 0, len = attrs.length; i < len; i++){
1585 var binding = this._walk(attrs[i], {element: element, fromElement: true, attrs: attrs})
1586 if(binding) bindings.push(binding);
1587 }
1588 return bindings;
1589}
1590
1591walkers.attribute = function(ast ,options){
1592 var attr = ast;
1593 var Component = this.constructor;
1594 var self = this;
1595 var element = options.element;
1596 var name = attr.name,
1597 value = attr.value || "", directive = Component.directive(name);
1598
1599 _.touchExpression(value);
1600
1601
1602 if(directive && directive.link){
1603 var binding = directive.link.call(self, element, value, name, options.attrs);
1604 if(typeof binding === 'function') binding = {destroy: binding};
1605 return binding;
1606 }else{
1607 if( name === 'ref' && value != null && options.fromElement){
1608 var ref = value.type === 'expression'? value.get(self): value;
1609 var refs = this.$context.$refs;
1610 if(refs){
1611 refs[ref] = element
1612 return {
1613 destroy: function(){
1614 refs[ref] = null;
1615 }
1616 }
1617 }
1618 }
1619 if(value.type === 'expression' ){
1620
1621 this.$watch(value, function(nvalue, old){
1622 dom.attr(element, name, nvalue);
1623 }, {init: true});
1624 }else{
1625 if(_.isBooleanAttr(name)){
1626 dom.attr(element, name, true);
1627 }else{
1628 dom.attr(element, name, value);
1629 }
1630 }
1631 if(!options.fromElement){
1632 return {
1633 destroy: function(){
1634 dom.attr(element, name, null);
1635 }
1636 }
1637 }
1638 }
1639
1640}
1641
1642
1643});
1644require.register("regularjs/src/env.js", function(exports, require, module){
1645// some fixture test;
1646// ---------------
1647var _ = require('./util');
1648exports.svg = (function(){
1649 return typeof document !== "undefined" && document.implementation.hasFeature( "http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1" );
1650})();
1651
1652
1653exports.transition = (function(){
1654
1655})();
1656
1657// whether have component in initializing
1658exports.exprCache = _.cache(100);
1659exports.isRunning = false;
1660
1661});
1662require.register("regularjs/src/index.js", function(exports, require, module){
1663module.exports = require("./Regular.js");
1664
1665require("./directive/base.js");
1666require("./directive/animation.js");
1667require("./module/timeout.js");
1668
1669module.exports.dom = require("./dom.js");
1670module.exports.util = require("./util.js");
1671module.exports.env = require("./env.js");
1672
1673
1674});
1675require.register("regularjs/src/dom.js", function(exports, require, module){
1676
1677// thanks for angular && mootools for some concise&cross-platform implemention
1678// =====================================
1679
1680// The MIT License
1681// Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
1682
1683// ---
1684// license: MIT-style license. http://mootools.net
1685
1686var dom = module.exports;
1687var env = require("./env.js");
1688var _ = require("./util");
1689var tNode = document.createElement('div')
1690var addEvent, removeEvent;
1691var noop = function(){}
1692
1693var namespaces = {
1694 html: "http://www.w3.org/1999/xhtml",
1695 svg: "http://www.w3.org/2000/svg"
1696}
1697
1698dom.body = document.body;
1699
1700dom.doc = document;
1701
1702// camelCase
1703function camelCase(str){
1704 return ("" + str).replace(/-\D/g, function(match){
1705 return match.charAt(1).toUpperCase();
1706 });
1707}
1708
1709
1710dom.tNode = tNode;
1711
1712if(tNode.addEventListener){
1713 addEvent = function(node, type, fn) {
1714 node.addEventListener(type, fn, false);
1715 }
1716 removeEvent = function(node, type, fn) {
1717 node.removeEventListener(type, fn, false)
1718 }
1719}else{
1720 addEvent = function(node, type, fn) {
1721 node.attachEvent('on' + type, fn);
1722 }
1723 removeEvent = function(node, type, fn) {
1724 node.detachEvent('on' + type, fn);
1725 }
1726}
1727
1728
1729dom.msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
1730if (isNaN(dom.msie)) {
1731 dom.msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
1732}
1733
1734dom.find = function(sl){
1735 if(document.querySelector) {
1736 try{
1737 return document.querySelector(sl);
1738 }catch(e){
1739
1740 }
1741 }
1742 if(sl.indexOf('#')!==-1) return document.getElementById( sl.slice(1) );
1743}
1744
1745dom.inject = function(node, refer, position){
1746
1747 position = position || 'bottom';
1748
1749 if(Array.isArray(node)){
1750 var tmp = node;
1751 node = dom.fragment();
1752 for(var i = 0,len = tmp.length; i < len ;i++){
1753 node.appendChild(tmp[i]);
1754 }
1755 }
1756
1757 var firstChild, next;
1758 switch(position){
1759 case 'bottom':
1760 refer.appendChild( node );
1761 break;
1762 case 'top':
1763 if( firstChild = refer.firstChild ){
1764 refer.insertBefore( node, refer.firstChild );
1765 }else{
1766 refer.appendChild( node );
1767 }
1768 break;
1769 case 'after':
1770 if( next = refer.nextSibling ){
1771 next.parentNode.insertBefore( node, next );
1772 }else{
1773 refer.parentNode.appendChild( node );
1774 }
1775 break;
1776 case 'before':
1777 refer.parentNode.insertBefore( node, refer );
1778 }
1779}
1780
1781
1782dom.id = function(id){
1783 return document.getElementById(id);
1784}
1785
1786// createElement
1787dom.create = function(type, ns, attrs){
1788 if(ns === 'svg'){
1789 if(!env.svg) throw Error('the env need svg support')
1790 ns = namespaces.svg;
1791 }
1792 return !ns? document.createElement(type): document.createElementNS(ns, type);
1793}
1794
1795// documentFragment
1796dom.fragment = function(){
1797 return document.createDocumentFragment();
1798}
1799
1800
1801
1802var specialAttr = {
1803 'class': function(node, value){
1804 ('className' in node && (node.namespaceURI === namespaces.html || !node.namespaceURI)) ?
1805 node.className = (value || '') : node.setAttribute('class', value);
1806 },
1807 'for': function(node, value){
1808 ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
1809 },
1810 'style': function(node, value){
1811 (node.style) ? node.style.cssText = value : node.setAttribute('style', value);
1812 },
1813 'value': function(node, value){
1814 node.value = (value != null) ? value : '';
1815 }
1816}
1817
1818
1819// attribute Setter & Getter
1820dom.attr = function(node, name, value){
1821 if (_.isBooleanAttr(name)) {
1822 if (typeof value !== 'undefined') {
1823 if (!!value) {
1824 node[name] = true;
1825 node.setAttribute(name, name);
1826 // lt ie7 . the javascript checked setting is in valid
1827 //http://bytes.com/topic/javascript/insights/799167-browser-quirk-dynamically-appended-checked-checkbox-does-not-appear-checked-ie
1828 if(dom.msie && dom.msie <=7 ) node.defaultChecked = true
1829 } else {
1830 node[name] = false;
1831 node.removeAttribute(name);
1832 }
1833 } else {
1834 return (node[name] ||
1835 (node.attributes.getNamedItem(name)|| noop).specified) ? name : undefined;
1836 }
1837 } else if (typeof (value) !== 'undefined') {
1838 // if in specialAttr;
1839 if(specialAttr[name]) specialAttr[name](node, value);
1840 else if(value === null) node.removeAttribute(name)
1841 else node.setAttribute(name, value);
1842 } else if (node.getAttribute) {
1843 // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
1844 // some elements (e.g. Document) don't have get attribute, so return undefined
1845 var ret = node.getAttribute(name, 2);
1846 // normalize non-existing attributes to undefined (as jQuery)
1847 return ret === null ? undefined : ret;
1848 }
1849}
1850
1851
1852dom.on = function(node, type, handler){
1853 var types = type.split(' ');
1854 handler.real = function(ev){
1855 handler.call(node, new Event(ev));
1856 }
1857 types.forEach(function(type){
1858 type = fixEventName(node, type);
1859 addEvent(node, type, handler.real);
1860 });
1861}
1862dom.off = function(node, type, handler){
1863 var types = type.split(' ');
1864 handler = handler.real || handler;
1865 types.forEach(function(type){
1866 type = fixEventName(node, type);
1867 removeEvent(node, type, handler);
1868 })
1869}
1870
1871
1872dom.text = (function (){
1873 var map = {};
1874 if (dom.msie && dom.msie < 9) {
1875 map[1] = 'innerText';
1876 map[3] = 'nodeValue';
1877 } else {
1878 map[1] = map[3] = 'textContent';
1879 }
1880
1881 return function (node, value) {
1882 var textProp = map[node.nodeType];
1883 if (value == null) {
1884 return textProp ? node[textProp] : '';
1885 }
1886 node[textProp] = value;
1887 }
1888})();
1889
1890
1891dom.html = function( node, html ){
1892 if(typeof html === "undefined"){
1893 return node.innerHTML;
1894 }else{
1895 node.innerHTML = html;
1896 }
1897}
1898
1899dom.replace = function(node, replaced){
1900 if(replaced.parentNode) replaced.parentNode.replaceChild(node, replaced);
1901}
1902
1903dom.remove = function(node){
1904 if(node.parentNode) node.parentNode.removeChild(node);
1905}
1906
1907// css Settle & Getter from angular
1908// =================================
1909// it isnt computed style
1910dom.css = function(node, name, value){
1911 if( _.typeOf(name) === "object" ){
1912 for(var i in name){
1913 if( name.hasOwnProperty(i) ){
1914 dom.css( node, i, name[i] );
1915 }
1916 }
1917 return;
1918 }
1919 if ( typeof value !== "undefined" ) {
1920
1921 name = camelCase(name);
1922 if(name) node.style[name] = value;
1923
1924 } else {
1925
1926 var val;
1927 if (dom.msie <= 8) {
1928 // this is some IE specific weirdness that jQuery 1.6.4 does not sure why
1929 val = node.currentStyle && node.currentStyle[name];
1930 if (val === '') val = 'auto';
1931 }
1932 val = val || node.style[name];
1933 if (dom.msie <= 8) {
1934 val = val === '' ? undefined : val;
1935 }
1936 return val;
1937 }
1938}
1939
1940dom.addClass = function(node, className){
1941 var current = node.className || "";
1942 if ((" " + current + " ").indexOf(" " + className + " ") === -1) {
1943 node.className = current? ( current + " " + className ) : className;
1944 }
1945}
1946
1947dom.delClass = function(node, className){
1948 var current = node.className || "";
1949 node.className = (" " + current + " ").replace(" " + className + " ", " ").trim();
1950}
1951
1952dom.hasClass = function(node, className){
1953 var current = node.className || "";
1954 return (" " + current + " ").indexOf(" " + className + " ") !== -1;
1955}
1956
1957
1958
1959// simple Event wrap
1960
1961//http://stackoverflow.com/questions/11068196/ie8-ie7-onchange-event-is-emited-only-after-repeated-selection
1962function fixEventName(elem, name){
1963 return (name === 'change' && dom.msie < 9 &&
1964 (elem && elem.tagName && elem.tagName.toLowerCase()==='input' &&
1965 (elem.type === 'checkbox' || elem.type === 'radio')
1966 )
1967 )? 'click': name;
1968}
1969
1970var rMouseEvent = /^(?:click|dblclick|contextmenu|DOMMouseScroll|mouse(?:\w+))$/
1971var doc = document;
1972doc = (!doc.compatMode || doc.compatMode === 'CSS1Compat') ? doc.documentElement : doc.body;
1973function Event(ev){
1974 ev = ev || window.event;
1975 if(ev._fixed) return ev;
1976 this.event = ev;
1977 this.target = ev.target || ev.srcElement;
1978
1979 var type = this.type = ev.type;
1980 var button = this.button = ev.button;
1981
1982 // if is mouse event patch pageX
1983 if(rMouseEvent.test(type)){ //fix pageX
1984 this.pageX = (ev.pageX != null) ? ev.pageX : ev.clientX + doc.scrollLeft;
1985 this.pageY = (ev.pageX != null) ? ev.pageY : ev.clientY + doc.scrollTop;
1986 if (type === 'mouseover' || type === 'mouseout'){// fix relatedTarget
1987 var related = ev.relatedTarget || ev[(type === 'mouseover' ? 'from' : 'to') + 'Element'];
1988 while (related && related.nodeType === 3) related = related.parentNode;
1989 this.relatedTarget = related;
1990 }
1991 }
1992 // if is mousescroll
1993 if (type === 'DOMMouseScroll' || type === 'mousewheel'){
1994 // ff ev.detail: 3 other ev.wheelDelta: -120
1995 this.wheelDelta = (ev.wheelDelta) ? ev.wheelDelta / 120 : -(ev.detail || 0) / 3;
1996 }
1997
1998 // fix which
1999 this.which = ev.which || ev.keyCode;
2000 if( !this.which && button !== undefined){
2001 // http://api.jquery.com/event.which/ use which
2002 this.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
2003 }
2004 this._fixed = true;
2005}
2006
2007_.extend(Event.prototype, {
2008 immediateStop: _.isFalse,
2009 stop: function(){
2010 this.preventDefault().stopPropgation();
2011 },
2012 preventDefault: function(){
2013 if (this.event.preventDefault) this.event.preventDefault();
2014 else this.event.returnValue = false;
2015 return this;
2016 },
2017 stopPropgation: function(){
2018 if (this.event.stopPropagation) this.event.stopPropagation();
2019 else this.event.cancelBubble = true;
2020 return this;
2021 },
2022 stopImmediatePropagation: function(){
2023 if(this.event.stopImmediatePropagation) this.event.stopImmediatePropagation();
2024 }
2025})
2026
2027
2028dom.nextFrame = (function(){
2029 var request = window.requestAnimationFrame ||
2030 window.webkitRequestAnimationFrame ||
2031 window.mozRequestAnimationFrame||
2032 function(callback){
2033 setTimeout(callback, 16)
2034 }
2035
2036 var cancel = window.cancelAnimationFrame ||
2037 window.webkitCancelAnimationFrame ||
2038 window.mozCancelAnimationFrame ||
2039 window.webkitCancelRequestAnimationFrame ||
2040 function(tid){
2041 clearTimeout(tid)
2042 }
2043
2044 return function(callback){
2045 var id = request(callback);
2046 return function(){ cancel(id); }
2047 }
2048})();
2049
2050// 3ks for angular's raf service
2051var k;
2052dom.nextReflow = function(callback){
2053 dom.nextFrame(function(){
2054 k = document.body.offsetWidth;
2055 callback();
2056 })
2057}
2058
2059
2060
2061
2062});
2063require.register("regularjs/src/group.js", function(exports, require, module){
2064var _ = require('./util');
2065var combine = require('./helper/combine')
2066
2067function Group(list){
2068 this.children = list || [];
2069}
2070
2071
2072_.extend(Group.prototype, {
2073 destroy: function(first){
2074 combine.destroy(this.children, first);
2075 if(this.ondestroy) this.ondestroy();
2076 this.children = null;
2077 },
2078 get: function(i){
2079 return this.children[i]
2080 },
2081 push: function(item){
2082 this.children.push( item );
2083 }
2084
2085})
2086
2087
2088
2089module.exports = Group;
2090
2091
2092
2093});
2094require.register("regularjs/src/config.js", function(exports, require, module){
2095
2096module.exports = {
2097'BEGIN': '{{',
2098'END': '}}'
2099}
2100});
2101require.register("regularjs/src/parser/Lexer.js", function(exports, require, module){
2102var _ = require("../util.js");
2103var config = require("../config.js");
2104
2105// some custom tag will conflict with the Lexer progress
2106var conflictTag = {"}": "{", "]": "["}, map1, map2;
2107// some macro for lexer
2108var macro = {
2109 'NAME': /(?:[:_A-Za-z][-\.:_0-9A-Za-z]*)/,
2110 'IDENT': /[\$_A-Za-z][_0-9A-Za-z\$]*/,
2111 'SPACE': /[\r\n\f ]/
2112}
2113
2114
2115var test = /a|(b)/.exec("a");
2116var testSubCapure = test && test[1] === undefined?
2117 function(str){ return str !== undefined }
2118 :function(str){return !!str};
2119
2120function wrapHander(handler){
2121 return function(all){
2122 return {type: handler, value: all }
2123 }
2124}
2125
2126function Lexer(input, opts){
2127 if(conflictTag[config.END]){
2128 this.markStart = conflictTag[config.END];
2129 this.markEnd = config.END;
2130 }
2131
2132
2133 this.input = (input||"").trim();
2134 this.opts = opts || {};
2135 this.map = this.opts.mode !== 2? map1: map2;
2136 this.states = ["INIT"];
2137 if(this.opts.state) this.states.push( this.opts.state );
2138}
2139
2140var lo = Lexer.prototype
2141
2142
2143lo.lex = function(str){
2144 str = (str || this.input).trim();
2145 var tokens = [], split, test,mlen, token, state;
2146 this.input = str,
2147 this.marks = 0;
2148 // init the pos index
2149 this.index=0;
2150 var i = 0;
2151 while(str){
2152 i++
2153 state = this.state();
2154 split = this.map[state]
2155 test = split.TRUNK.exec(str);
2156 if(!test){
2157 this.error('Unrecoginized Token');
2158 }
2159 mlen = test[0].length;
2160 str = str.slice(mlen)
2161 token = this._process.call(this, test, split, str)
2162 if(token) tokens.push(token)
2163 this.index += mlen;
2164 // if(state == 'TAG' || state == 'JST') str = this.skipspace(str);
2165 }
2166
2167 tokens.push({type: 'EOF'});
2168
2169 return tokens;
2170}
2171
2172lo.error = function(msg){
2173 throw "Parse Error: " + msg + ':\n' + _.trackErrorPos(this.input, this.index);
2174}
2175
2176lo._process = function(args, split,str){
2177 // console.log(args.join(","), this.state())
2178 var links = split.links, marched = false, token;
2179
2180 for(var len = links.length, i=0;i<len ;i++){
2181 var link = links[i],
2182 handler = link[2],
2183 index = link[0];
2184 // if(args[6] === '>' && index === 6) console.log('haha')
2185 if(testSubCapure(args[index])) {
2186 marched = true;
2187 if(handler){
2188 token = handler.apply(this, args.slice(index, index + link[1]))
2189 if(token) token.pos = this.index;
2190 }
2191 break;
2192 }
2193 }
2194 if(!marched){ // in ie lt8 . sub capture is "" but ont
2195 switch(str.charAt(0)){
2196 case "<":
2197 this.enter("TAG");
2198 break;
2199 default:
2200 this.enter("JST");
2201 break;
2202 }
2203 }
2204 return token;
2205}
2206lo.enter = function(state){
2207 this.states.push(state)
2208 return this;
2209}
2210
2211lo.state = function(){
2212 var states = this.states;
2213 return states[states.length-1];
2214}
2215
2216lo.leave = function(state){
2217 var states = this.states;
2218 if(!state || states[states.length-1] === state) states.pop()
2219}
2220
2221
2222Lexer.setup = function(){
2223 macro.END = config.END;
2224 macro.BEGIN = config.BEGIN;
2225 //
2226 map1 = genMap([
2227 // INIT
2228 rules.ENTER_JST,
2229 rules.ENTER_TAG,
2230 rules.TEXT,
2231
2232 //TAG
2233 rules.TAG_NAME,
2234 rules.TAG_OPEN,
2235 rules.TAG_CLOSE,
2236 rules.TAG_PUNCHOR,
2237 rules.TAG_ENTER_JST,
2238 rules.TAG_UNQ_VALUE,
2239 rules.TAG_STRING,
2240 rules.TAG_SPACE,
2241 rules.TAG_COMMENT,
2242
2243 // JST
2244 rules.JST_OPEN,
2245 rules.JST_CLOSE,
2246 rules.JST_COMMENT,
2247 rules.JST_EXPR_OPEN,
2248 rules.JST_IDENT,
2249 rules.JST_SPACE,
2250 rules.JST_LEAVE,
2251 rules.JST_NUMBER,
2252 rules.JST_PUNCHOR,
2253 rules.JST_STRING,
2254 rules.JST_COMMENT
2255 ])
2256
2257 // ignored the tag-relative token
2258 map2 = genMap([
2259 // INIT no < restrict
2260 rules.ENTER_JST2,
2261 rules.TEXT,
2262 // JST
2263 rules.JST_COMMENT,
2264 rules.JST_OPEN,
2265 rules.JST_CLOSE,
2266 rules.JST_EXPR_OPEN,
2267 rules.JST_IDENT,
2268 rules.JST_SPACE,
2269 rules.JST_LEAVE,
2270 rules.JST_NUMBER,
2271 rules.JST_PUNCHOR,
2272 rules.JST_STRING,
2273 rules.JST_COMMENT
2274 ])
2275}
2276
2277
2278function genMap(rules){
2279 var rule, map = {}, sign;
2280 for(var i = 0, len = rules.length; i < len ; i++){
2281 rule = rules[i];
2282 sign = rule[2] || 'INIT';
2283 ( map[sign] || (map[sign] = {rules:[], links:[]}) ).rules.push(rule);
2284 }
2285 return setup(map);
2286}
2287
2288function setup(map){
2289 var split, rules, trunks, handler, reg, retain, rule;
2290 function replaceFn(all, one){
2291 return typeof macro[one] === 'string'?
2292 _.escapeRegExp(macro[one])
2293 : String(macro[one]).slice(1,-1);
2294 }
2295
2296 for(var i in map){
2297
2298 split = map[i];
2299 split.curIndex = 1;
2300 rules = split.rules;
2301 trunks = [];
2302
2303 for(var j = 0,len = rules.length; j<len; j++){
2304 rule = rules[j];
2305 reg = rule[0];
2306 handler = rule[1];
2307
2308 if(typeof handler === 'string'){
2309 handler = wrapHander(handler);
2310 }
2311 if(_.typeOf(reg) === 'regexp') reg = reg.toString().slice(1, -1);
2312
2313 reg = reg.replace(/\{(\w+)\}/g, replaceFn)
2314 retain = _.findSubCapture(reg) + 1;
2315 split.links.push([split.curIndex, retain, handler]);
2316 split.curIndex += retain;
2317 trunks.push(reg);
2318 }
2319 split.TRUNK = new RegExp("^(?:(" + trunks.join(")|(") + "))")
2320 }
2321 return map;
2322}
2323
2324var rules = {
2325
2326 // 1. INIT
2327 // ---------------
2328
2329 // mode1's JST ENTER RULE
2330 ENTER_JST: [/[^\x00<]*?(?={BEGIN})/, function(all){
2331 this.enter('JST');
2332 if(all) return {type: 'TEXT', value: all}
2333 }],
2334
2335 // mode2's JST ENTER RULE
2336 ENTER_JST2: [/[^\x00]*?(?={BEGIN})/, function(all){
2337 this.enter('JST');
2338 if(all) return {type: 'TEXT', value: all}
2339 }],
2340
2341 ENTER_TAG: [/[^\x00<>]*?(?=<)/, function(all){
2342 this.enter('TAG');
2343 if(all) return {type: 'TEXT', value: all}
2344 }],
2345
2346 TEXT: [/[^\x00]+/, 'TEXT'],
2347
2348 // 2. TAG
2349 // --------------------
2350 TAG_NAME: [/{NAME}/, 'NAME', 'TAG'],
2351 TAG_UNQ_VALUE: [/[^&"'=><`\r\n\f ]+/, 'UNQ', 'TAG'],
2352
2353 TAG_OPEN: [/<({NAME})\s*/, function(all, one){
2354 return {type: 'TAG_OPEN', value: one}
2355 }, 'TAG'],
2356 TAG_CLOSE: [/<\/({NAME})[\r\n\f ]*>/, function(all, one){
2357 this.leave();
2358 return {type: 'TAG_CLOSE', value: one }
2359 }, 'TAG'],
2360
2361 // mode2's JST ENTER RULE
2362 TAG_ENTER_JST: [/(?={BEGIN})/, function(){
2363 this.enter('JST');
2364 }, 'TAG'],
2365
2366
2367 TAG_PUNCHOR: [/[\>\/=&]/, function(all){
2368 if(all === '>') this.leave();
2369 return {type: all, value: all }
2370 }, 'TAG'],
2371 TAG_STRING: [ /'([^']*)'|"([^"]*)"/, function(all, one, two){ //"'
2372 var value = one || two || "";
2373
2374 return {type: 'STRING', value: value}
2375 }, 'TAG'],
2376
2377 TAG_SPACE: [/{SPACE}+/, null, 'TAG'],
2378 TAG_COMMENT: [/<\!--([^\x00]*?)--\>/, null ,'TAG'],
2379
2380 // 3. JST
2381 // -------------------
2382
2383 JST_OPEN: ['{BEGIN}#{SPACE}*({IDENT})', function(all, name){
2384 return {
2385 type: 'OPEN',
2386 value: name
2387 }
2388 }, 'JST'],
2389 JST_LEAVE: [/{END}/, function(){
2390 if(!this.markEnd || !this.marks ){
2391 this.leave('JST');
2392 return {type: 'END'}
2393 }else{
2394 this.marks--;
2395 return {type: this.markEnd, value: this.markEnd}
2396 }
2397 }, 'JST'],
2398 JST_CLOSE: [/{BEGIN}\s*\/({IDENT})\s*{END}/, function(all, one){
2399 this.leave('JST');
2400 return {
2401 type: 'CLOSE',
2402 value: one
2403 }
2404 }, 'JST'],
2405 JST_COMMENT: [/{BEGIN}\!([^\x00]*?)\!{END}/, function(){
2406 this.leave();
2407 }, 'JST'],
2408 JST_EXPR_OPEN: ['{BEGIN}',function(all, one){
2409 if(all === this.markStart){
2410 if(this.marks){
2411 return {type: this.markStart, value: this.markStart };
2412 }else{
2413 this.marks++;
2414 }
2415 }
2416 var escape = one === '=';
2417 return {
2418 type: 'EXPR_OPEN',
2419 escape: escape
2420 }
2421 }, 'JST'],
2422 JST_IDENT: ['{IDENT}', 'IDENT', 'JST'],
2423 JST_SPACE: [/[ \r\n\f]+/, null, 'JST'],
2424 JST_PUNCHOR: [/[=!]?==|[-=><+*\/%\!]?\=|\|\||&&|\@\(|\.\.|[<\>\[\]\(\)\-\|\{}\+\*\/%?:\.!,]/, function(all){
2425 return { type: all, value: all }
2426 },'JST'],
2427
2428 JST_STRING: [ /'([^']*)'|"([^"]*)"/, function(all, one, two){ //"'
2429 return {type: 'STRING', value: one || two || ""}
2430 }, 'JST'],
2431 JST_NUMBER: [/(?:[0-9]*\.[0-9]+|[0-9]+)(e\d+)?/, function(all){
2432 return {type: 'NUMBER', value: parseFloat(all, 10)};
2433 }, 'JST']
2434}
2435
2436
2437// setup when first config
2438Lexer.setup();
2439
2440
2441
2442module.exports = Lexer;
2443
2444
2445
2446});
2447require.register("regularjs/src/parser/node.js", function(exports, require, module){
2448module.exports = {
2449 element: function(name, attrs, children){
2450 return {
2451 type: 'element',
2452 tag: name,
2453 attrs: attrs,
2454 children: children
2455 }
2456 },
2457 attribute: function(name, value){
2458 return {
2459 type: 'attribute',
2460 name: name,
2461 value: value
2462 }
2463 },
2464 "if": function(test, consequent, alternate){
2465 return {
2466 type: 'if',
2467 test: test,
2468 consequent: consequent,
2469 alternate: alternate
2470 }
2471 },
2472 list: function(sequence, variable, body){
2473 return {
2474 type: 'list',
2475 sequence: sequence,
2476 variable: variable,
2477 body: body
2478 }
2479 },
2480 expression: function( body, setbody, constant ){
2481 return {
2482 type: "expression",
2483 body: body,
2484 constant: constant || false,
2485 setbody: setbody || false
2486 }
2487 },
2488 text: function(text){
2489 return {
2490 type: "text",
2491 text: text
2492 }
2493 },
2494 template: function(template){
2495 return {
2496 type: 'template',
2497 content: template
2498 }
2499 }
2500}
2501
2502});
2503require.register("regularjs/src/parser/Parser.js", function(exports, require, module){
2504var _ = require("../util.js");
2505var node = require("./node.js");
2506var Lexer = require("./Lexer.js");
2507var varName = _.varName;
2508var ctxName = _.ctxName;
2509var isPath = _.makePredicate("STRING IDENT NUMBER");
2510var isKeyWord = _.makePredicate("true false undefined null this Array Date JSON Math NaN RegExp decodeURI decodeURIComponent encodeURI encodeURIComponent parseFloat parseInt Object");
2511
2512
2513
2514
2515function Parser(input, opts){
2516 opts = opts || {};
2517
2518 this.input = input;
2519 this.tokens = new Lexer(input, opts).lex();
2520 this.pos = 0;
2521 this.noComputed = opts.noComputed;
2522 this.length = this.tokens.length;
2523}
2524
2525
2526var op = Parser.prototype;
2527
2528
2529op.parse = function(){
2530 this.pos = 0;
2531 var res= this.program();
2532 if(this.ll().type === 'TAG_CLOSE'){
2533 this.error("You may got a unclosed Tag")
2534 }
2535 return res;
2536}
2537
2538op.ll = function(k){
2539 k = k || 1;
2540 if(k < 0) k = k + 1;
2541 var pos = this.pos + k - 1;
2542 if(pos > this.length - 1){
2543 return this.tokens[this.length-1];
2544 }
2545 return this.tokens[pos];
2546}
2547 // lookahead
2548op.la = function(k){
2549 return (this.ll(k) || '').type;
2550}
2551
2552op.match = function(type, value){
2553 var ll;
2554 if(!(ll = this.eat(type, value))){
2555 ll = this.ll();
2556 this.error('expect [' + type + (value == null? '':':'+ value) + ']" -> got "[' + ll.type + (value==null? '':':'+ll.value) + ']', ll.pos)
2557 }else{
2558 return ll;
2559 }
2560}
2561
2562op.error = function(msg, pos){
2563 msg = "Parse Error: " + msg + ':\n' + _.trackErrorPos(this.input, typeof pos === 'number'? pos: this.ll().pos||0);
2564 throw new Error(msg);
2565}
2566
2567op.next = function(k){
2568 k = k || 1;
2569 this.pos += k;
2570}
2571op.eat = function(type, value){
2572 var ll = this.ll();
2573 if(typeof type !== 'string'){
2574 for(var len = type.length ; len--;){
2575 if(ll.type === type[len]) {
2576 this.next();
2577 return ll;
2578 }
2579 }
2580 }else{
2581 if( ll.type === type && (typeof value === 'undefined' || ll.value === value) ){
2582 this.next();
2583 return ll;
2584 }
2585 }
2586 return false;
2587}
2588
2589// program
2590// :EOF
2591// | (statement)* EOF
2592op.program = function(){
2593 var statements = [], ll = this.ll();
2594 while(ll.type !== 'EOF' && ll.type !=='TAG_CLOSE'){
2595
2596 statements.push(this.statement());
2597 ll = this.ll();
2598 }
2599 // if(ll.type === 'TAG_CLOSE') this.error("You may have unmatched Tag")
2600 return statements;
2601}
2602
2603// statement
2604// : xml
2605// | jst
2606// | text
2607op.statement = function(){
2608 var ll = this.ll();
2609 switch(ll.type){
2610 case 'NAME':
2611 case 'TEXT':
2612 var text = ll.value;
2613 this.next();
2614 while(ll = this.eat(['NAME', 'TEXT'])){
2615 text += ll.value;
2616 }
2617 return node.text(text);
2618 case 'TAG_OPEN':
2619 return this.xml();
2620 case 'OPEN':
2621 return this.directive();
2622 case 'EXPR_OPEN':
2623 return this.interplation();
2624 case 'PART_OPEN':
2625 return this.template();
2626 default:
2627 this.error('Unexpected token: '+ this.la())
2628 }
2629}
2630
2631// xml
2632// stag statement* TAG_CLOSE?(if self-closed tag)
2633op.xml = function(){
2634 var name, attrs, children, selfClosed;
2635 name = this.match('TAG_OPEN').value;
2636 attrs = this.attrs();
2637 selfClosed = this.eat('/')
2638 this.match('>');
2639 if( !selfClosed && !_.isVoidTag(name) ){
2640 children = this.program();
2641 if(!this.eat('TAG_CLOSE', name)) this.error('expect </'+name+'> got'+ 'no matched closeTag')
2642 }
2643 return node.element(name, attrs, children);
2644}
2645
2646// xentity
2647// -rule(wrap attribute)
2648// -attribute
2649//
2650// __example__
2651// name = 1 |
2652// ng-hide |
2653// on-click={{}} |
2654// {{#if name}}on-click={{xx}}{{#else}}on-tap={{}}{{/if}}
2655
2656op.xentity = function(ll){
2657 var name = ll.value, value;
2658 if(ll.type === 'NAME'){
2659 if( this.eat("=") ) value = this.attvalue();
2660 return node.attribute( name, value );
2661 }else{
2662 if( name !== 'if') this.error("current version. ONLY RULE #if #else #elseif is valid in tag, the rule #" + name + ' is invalid');
2663 return this['if'](true);
2664 }
2665
2666}
2667
2668// stag ::= '<' Name (S attr)* S? '>'
2669// attr ::= Name Eq attvalue
2670op.attrs = function(isAttribute){
2671 var eat
2672 if(!isAttribute){
2673 eat = ["NAME", "OPEN"]
2674 }else{
2675 eat = ["NAME"]
2676 }
2677
2678 var attrs = [], ll;
2679 while (ll = this.eat(eat)){
2680 attrs.push(this.xentity( ll ))
2681 }
2682 return attrs;
2683}
2684
2685// attvalue
2686// : STRING
2687// | NAME
2688op.attvalue = function(){
2689 var ll = this.ll();
2690 switch(ll.type){
2691 case "NAME":
2692 case "UNQ":
2693 case "STRING":
2694 this.next();
2695 var value = ll.value;
2696 if(~value.indexOf('{{')){
2697 var constant = true;
2698 var parsed = new Parser(value, { mode: 2 }).parse();
2699 if(parsed.length === 1 && parsed[0].type === 'expression') return parsed[0];
2700 var body = [];
2701 parsed.forEach(function(item){
2702 if(!item.constant) constant=false;
2703 body.push(item.body || "'" + item.text + "'");
2704 });
2705 body = "[" + body.join(",") + "].join('')";
2706 value = node.expression(body, null, constant);
2707 }
2708 return value;
2709 case "EXPR_OPEN":
2710 return this.interplation();
2711 default:
2712 this.error('Unexpected token: '+ this.la())
2713 }
2714}
2715
2716
2717// {{#}}
2718op.directive = function(){
2719 var name = this.ll().value;
2720 this.next();
2721 if(typeof this[name] === 'function'){
2722 return this[name]()
2723 }else{
2724 this.error('Undefined directive['+ name +']');
2725 }
2726}
2727
2728// {{}}
2729op.interplation = function(){
2730 this.match('EXPR_OPEN');
2731 var res = this.expression(true);
2732 this.match('END');
2733 return res;
2734}
2735
2736// {{~}}
2737op.include = function(){
2738 var content = this.expression();
2739 this.match('END');
2740 return node.template(content);
2741}
2742
2743// {{#if}}
2744op["if"] = function(tag){
2745 var test = this.expression();
2746 var consequent = [], alternate=[];
2747
2748 var container = consequent;
2749 var statement = !tag? "statement" : "attrs";
2750
2751 this.match('END');
2752
2753 var ll, close;
2754 while( ! (close = this.eat('CLOSE')) ){
2755 ll = this.ll();
2756 if( ll.type === 'OPEN' ){
2757 switch( ll.value ){
2758 case 'else':
2759 container = alternate;
2760 this.next();
2761 this.match( 'END' );
2762 break;
2763 case 'elseif':
2764 this.next();
2765 alternate.push( this["if"](tag) );
2766 return node['if']( test, consequent, alternate );
2767 default:
2768 container.push( this[statement](true) );
2769 }
2770 }else{
2771 container.push(this[statement](true));
2772 }
2773 }
2774 // if statement not matched
2775 if(close.value !== "if") this.error('Unmatched if directive')
2776 return node["if"](test, consequent, alternate);
2777}
2778
2779
2780// @mark mustache syntax have natrure dis, canot with expression
2781// {{#list}}
2782op.list = function(){
2783 // sequence can be a list or hash
2784 var sequence = this.expression(), variable, ll;
2785 var consequent = [], alternate=[];
2786 var container = consequent;
2787
2788 this.match('IDENT', 'as');
2789
2790 variable = this.match('IDENT').value;
2791
2792 this.match('END');
2793
2794 while( !(ll = this.eat('CLOSE')) ){
2795 if(this.eat('OPEN', 'else')){
2796 container = alternate;
2797 this.match('END');
2798 }else{
2799 container.push(this.statement());
2800 }
2801 }
2802 if(ll.value !== 'list') this.error('expect ' + '{{/list}} got ' + '{{/' + ll.value + '}}', ll.pos );
2803 return node.list(sequence, variable, consequent, alternate);
2804}
2805
2806
2807op.expression = function(){
2808 var expression;
2809 if(this.eat('@(')){ //once bind
2810 expression = this.expr();
2811 expression.once = true;
2812 this.match(')')
2813 }else{
2814 expression = this.expr();
2815 }
2816 return expression;
2817}
2818
2819op.expr = function(){
2820 this.depend = [];
2821
2822 var buffer = this.filter()
2823
2824 var body = buffer.get || buffer;
2825 var setbody = buffer.set;
2826 return node.expression(body, setbody, !this.depend.length);
2827}
2828
2829
2830// filter
2831// assign ('|' filtername[':' args]) *
2832op.filter = function(){
2833 var left = this.assign();
2834 var ll = this.eat('|');
2835 var buffer, attr;
2836 if(ll){
2837 buffer = [
2838 "(function(){",
2839 "var ", attr = "_f_", "=", left.get, ";"]
2840 do{
2841
2842 buffer.push(attr + " = "+ctxName+"._f_('" + this.match('IDENT').value+ "')(" + attr) ;
2843 if(this.eat(':')){
2844 buffer.push(", "+ this.arguments("|").join(",") + ");")
2845 }else{
2846 buffer.push(');');
2847 }
2848
2849 }while(ll = this.eat('|'));
2850 buffer.push("return " + attr + "})()");
2851 return this.getset(buffer.join(""));
2852 }
2853 return left;
2854}
2855
2856// assign
2857// left-hand-expr = condition
2858op.assign = function(){
2859 var left = this.condition(), ll;
2860 if(ll = this.eat(['=', '+=', '-=', '*=', '/=', '%='])){
2861 if(!left.set) this.error('invalid lefthand expression in assignment expression');
2862 return this.getset( left.set.replace("_p_", this.condition().get).replace("'='", "'"+ll.type+"'"), left.set);
2863 // return this.getset('(' + left.get + ll.type + this.condition().get + ')', left.set);
2864 }
2865 return left;
2866}
2867
2868// or
2869// or ? assign : assign
2870op.condition = function(){
2871
2872 var test = this.or();
2873 if(this.eat('?')){
2874 return this.getset([test.get + "?",
2875 this.assign().get,
2876 this.match(":").type,
2877 this.assign().get].join(""));
2878 }
2879
2880 return test;
2881}
2882
2883// and
2884// and && or
2885op.or = function(){
2886
2887 var left = this.and();
2888
2889 if(this.eat('||')){
2890 return this.getset(left.get + '||' + this.or().get);
2891 }
2892
2893 return left;
2894}
2895// equal
2896// equal && and
2897op.and = function(){
2898
2899 var left = this.equal();
2900
2901 if(this.eat('&&')){
2902 return this.getset(left.get + '&&' + this.and().get);
2903 }
2904 return left;
2905}
2906// relation
2907//
2908// equal == relation
2909// equal != relation
2910// equal === relation
2911// equal !== relation
2912op.equal = function(){
2913 var left = this.relation(), ll;
2914 // @perf;
2915 if( ll = this.eat(['==','!=', '===', '!=='])){
2916 return this.getset(left.get + ll.type + this.equal().get);
2917 }
2918 return left
2919}
2920// relation < additive
2921// relation > additive
2922// relation <= additive
2923// relation >= additive
2924// relation in additive
2925op.relation = function(){
2926 var left = this.additive(), ll;
2927 // @perf
2928 if(ll = (this.eat(['<', '>', '>=', '<=']) || this.eat('IDENT', 'in') )){
2929 return this.getset(left.get + ll.value + this.relation().get);
2930 }
2931 return left
2932}
2933// additive :
2934// multive
2935// additive + multive
2936// additive - multive
2937op.additive = function(){
2938 var left = this.multive() ,ll;
2939 if(ll= this.eat(['+','-']) ){
2940 return this.getset(left.get + ll.value + this.additive().get);
2941 }
2942 return left
2943}
2944// multive :
2945// unary
2946// multive * unary
2947// multive / unary
2948// multive % unary
2949op.multive = function(){
2950 var left = this.range() ,ll;
2951 if( ll = this.eat(['*', '/' ,'%']) ){
2952 return this.getset(left.get + ll.type + this.multive().get);
2953 }
2954 return left;
2955}
2956
2957op.range = function(){
2958 var left = this.unary(), ll, right;
2959
2960 if(ll = this.eat('..')){
2961 right = this.unary();
2962 var body =
2963 "(function(start,end){var res = [],step=end>start?1:-1; for(var i = start; end>start?i <= end: i>=end; i=i+step){res.push(i); } return res })("+left.get+","+right.get+")"
2964 return this.getset(body);
2965 }
2966
2967 return left;
2968}
2969
2970
2971
2972// lefthand
2973// + unary
2974// - unary
2975// ~ unary
2976// ! unary
2977op.unary = function(){
2978 var ll;
2979 if(ll = this.eat(['+','-','~', '!'])){
2980 return this.getset('(' + ll.type + this.unary().get + ')') ;
2981 }else{
2982 return this.member()
2983 }
2984}
2985
2986// call[lefthand] :
2987// member args
2988// member [ expression ]
2989// member . ident
2990
2991op.member = function(base, last, pathes){
2992 var ll, path;
2993
2994 var onlySimpleAccessor = false;
2995 if(!base){ //first
2996 path = this.primary();
2997 var type = typeof path;
2998 if(type === 'string'){
2999 pathes = [];
3000 pathes.push( path );
3001 last = path;
3002 base = ctxName + "._sg_('" + path + "', " + varName + "['" + path + "'])";
3003 onlySimpleAccessor = true;
3004 }else{ //Primative Type
3005 if(path.get === 'this'){
3006 base = ctxName;
3007 pathes = ['this'];
3008 }else{
3009 pathes = null;
3010 base = path.get;
3011 }
3012 }
3013 }else{ // not first enter
3014 if(typeof last === 'string' && isPath( last) ){ // is valid path
3015 pathes.push(last);
3016 }else{
3017 if(pathes && pathes.length) this.depend.push(pathes);
3018 pathes = null;
3019 }
3020 }
3021 if(ll = this.eat(['[', '.', '('])){
3022 switch(ll.type){
3023 case '.':
3024 // member(object, property, computed)
3025 var tmpName = this.match('IDENT').value;
3026 base += "['" + tmpName + "']";
3027 return this.member( base, tmpName, pathes );
3028 case '[':
3029 // member(object, property, computed)
3030 path = this.assign();
3031 base += "[" + path.get + "]";
3032 this.match(']')
3033 return this.member(base, path, pathes);
3034 case '(':
3035 // call(callee, args)
3036 var args = this.arguments().join(',');
3037 base = base+"(" + args +")";
3038 this.match(')')
3039 return this.member(base, null, pathes);
3040 }
3041 }
3042 if( pathes && pathes.length ) this.depend.push( pathes );
3043 var res = {get: base};
3044 if(last){
3045 if(onlySimpleAccessor) res.set = ctxName + "._ss_('" + path + "'," + _.setName + "," + _.varName + ", '=')";
3046 else res.set = base + '=' + _.setName;
3047 }
3048 return res;
3049}
3050
3051/**
3052 *
3053 */
3054op.arguments = function(end){
3055 end = end || ')'
3056 var args = [];
3057 do{
3058 if(this.la() !== end){
3059 args.push(this.assign().get)
3060 }
3061 }while( this.eat(','));
3062 return args
3063}
3064
3065
3066// primary :
3067// this
3068// ident
3069// literal
3070// array
3071// object
3072// ( expression )
3073
3074op.primary = function(){
3075 var ll = this.ll();
3076 switch(ll.type){
3077 case "{":
3078 return this.object();
3079 case "[":
3080 return this.array();
3081 case "(":
3082 return this.paren();
3083 // literal or ident
3084 case 'STRING':
3085 this.next();
3086 return this.getset("'" + ll.value + "'")
3087 case 'NUMBER':
3088 this.next();
3089 return this.getset(""+ll.value);
3090 case "IDENT":
3091 this.next();
3092 if(isKeyWord(ll.value)){
3093 return this.getset( ll.value );
3094 }
3095 return ll.value;
3096 default:
3097 this.error('Unexpected Token: ' + ll.type);
3098 }
3099}
3100
3101// object
3102// {propAssign [, propAssign] * [,]}
3103
3104// propAssign
3105// prop : assign
3106
3107// prop
3108// STRING
3109// IDENT
3110// NUMBER
3111
3112op.object = function(){
3113 var code = [this.match('{').type];
3114
3115 var ll = this.eat( ['STRING', 'IDENT', 'NUMBER'] );
3116 while(ll){
3117 code.push("'" + ll.value + "'" + this.match(':').type);
3118 var get = this.assign().get;
3119 code.push(get);
3120 ll = null;
3121 if(this.eat(",") && (ll = this.eat(['STRING', 'IDENT', 'NUMBER'])) ) code.push(",");
3122 }
3123 code.push(this.match('}').type);
3124 return {get: code.join("")}
3125}
3126
3127// array
3128// [ assign[,assign]*]
3129op.array = function(){
3130 var code = [this.match('[').type], item;
3131 while(item = this.assign()){
3132 code.push(item.get);
3133 if(this.eat(',')) code.push(",");
3134 else break;
3135 }
3136 code.push(this.match(']').type);
3137 return {get: code.join("")};
3138}
3139
3140// '(' expression ')'
3141op.paren = function(){
3142 this.match('(');
3143 var res = this.filter()
3144 res.get = '(' + res.get + ')';
3145 this.match(')');
3146 return res;
3147}
3148
3149op.getset = function(get, set){
3150 return {
3151 get: get,
3152 set: set
3153 }
3154}
3155
3156
3157
3158module.exports = Parser;
3159
3160});
3161require.register("regularjs/src/helper/extend.js", function(exports, require, module){
3162// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
3163// Backbone may be freely distributed under the MIT license.
3164// For all details and documentation:
3165// http://backbonejs.org
3166
3167// klass: a classical JS OOP façade
3168// https://github.com/ded/klass
3169// License MIT (c) Dustin Diaz 2014
3170
3171// inspired by backbone's extend and klass
3172var _ = require("../util.js"),
3173 fnTest = /xy/.test(function(){"xy";}) ? /\bsupr\b/:/.*/,
3174 isFn = function(o){return typeof o === "function"};
3175
3176
3177function wrap(k, fn, supro) {
3178 return function () {
3179 var tmp = this.supr;
3180 this.supr = supro[k];
3181 var ret = fn.apply(this, arguments);
3182 this.supr = tmp;
3183 return ret;
3184 }
3185}
3186
3187function process( what, o, supro ) {
3188 for ( var k in o ) {
3189 if (o.hasOwnProperty(k)) {
3190
3191 what[k] = isFn( o[k] ) && isFn( supro[k] ) &&
3192 fnTest.test( o[k] ) ? wrap(k, o[k], supro) : o[k];
3193 }
3194 }
3195}
3196
3197module.exports = function extend(o){
3198 o = o || {};
3199 var supr = this, proto,
3200 supro = supr && supr.prototype || {};
3201 if(typeof o === 'function'){
3202 proto = o.prototype;
3203 o.implement = implement;
3204 o.extend = extend;
3205 return o;
3206 }
3207
3208 function fn() {
3209 supr.apply(this, arguments);
3210 }
3211
3212 proto = _.createProto(fn, supro);
3213
3214 function implement(o){
3215 process(proto, o, supro);
3216 return this;
3217 }
3218
3219
3220
3221 fn.implement = implement
3222 fn.implement(o)
3223 if(supr.__after__) supr.__after__.call(fn, supr, o);
3224 fn.extend = extend;
3225 return fn;
3226}
3227
3228
3229});
3230require.register("regularjs/src/helper/shim.js", function(exports, require, module){
3231// shim for es5
3232var slice = [].slice;
3233var tstr = ({}).toString;
3234
3235function extend(o1, o2 ){
3236 for(var i in o2) if( o1[i] === undefined){
3237 o1[i] = o2[i]
3238 }
3239}
3240
3241// String proto ;
3242extend(String.prototype, {
3243 trim: function(){
3244 return this.replace(/^\s+|\s+$/g, '');
3245 }
3246});
3247
3248
3249// Array proto;
3250extend(Array.prototype, {
3251 indexOf: function(obj, from){
3252 from = from || 0;
3253 for (var i = from, len = this.length; i < len; i++) {
3254 if (this[i] === obj) return i;
3255 }
3256 return -1;
3257 },
3258 forEach: function(callback, context){
3259 for (var i = 0, len = this.length; i < len; i++) {
3260 callback.call(context, this[i], i, this);
3261 }
3262 },
3263 filter: function(callback, context){
3264 var res = [];
3265 for (var i = 0, length = this.length; i < length; i++) {
3266 var pass = callback.call(context, this[i], i, this);
3267 if(pass) res.push(this[i]);
3268 }
3269 return res;
3270 },
3271 map: function(callback, context){
3272 var res = [];
3273 for (var i = 0, length = this.length; i < length; i++) {
3274 res.push(callback.call(context, this[i], i, this));
3275 }
3276 return res;
3277 }
3278});
3279
3280// Function proto;
3281extend(Function.prototype, {
3282 bind: function(context){
3283 var fn = this;
3284 var preArgs = slice.call(arguments, 1);
3285 return function(){
3286 var args = preArgs.concat(slice.call(arguments));
3287 return fn.apply(context, args);
3288 }
3289 }
3290})
3291
3292// Object
3293extend(Object, {
3294 keys: function(obj){
3295 var keys = [];
3296 for(var i in obj) if(obj.hasOwnProperty(i)){
3297 keys.push(i);
3298 }
3299 return keys;
3300 }
3301})
3302
3303// Date
3304extend(Date, {
3305 now: function(){
3306 return +new Date;
3307 }
3308})
3309// Array
3310extend(Array, {
3311 isArray: function(arr){
3312 return tstr.call(arr) === "[object Array]";
3313 }
3314})
3315
3316});
3317require.register("regularjs/src/helper/parse.js", function(exports, require, module){
3318var exprCache = require('../env').exprCache;
3319var _ = require("../util");
3320var Parser = require("../parser/Parser.js");
3321module.exports = {
3322 expression: function(expr, simple){
3323 // @TODO cache
3324 if( typeof expr === 'string' && ( expr = expr.trim() ) ){
3325 expr = exprCache.get( expr ) || exprCache.set( expr, new Parser( expr, { state: 'JST', mode: 2 } ).expression() )
3326 }
3327 if(expr) return _.touchExpression( expr );
3328 },
3329 parse: function(template){
3330 return new Parser(template).parse();
3331 }
3332}
3333
3334
3335});
3336require.register("regularjs/src/helper/watcher.js", function(exports, require, module){
3337var _ = require('../util.js');
3338var parseExpression = require('./parse.js').expression;
3339
3340
3341function Watcher(){}
3342
3343var methods = {
3344 $watch: function(expr, fn, options){
3345 var get, once, test, rlen; //records length
3346 if(!this._watchers) this._watchers = [];
3347 options = options || {};
3348 if(options === true){
3349 options = { deep: true }
3350 }
3351 var uid = _.uid('w_');
3352 if(Array.isArray(expr)){
3353 var tests = [];
3354 for(var i = 0,len = expr.length; i < len; i++){
3355 tests.push(parseExpression(expr[i]).get)
3356 }
3357 var prev = [];
3358 test = function(context){
3359 var equal = true;
3360 for(var i =0, len = tests.length; i < len; i++){
3361 var splice = tests[i](context);
3362 if(!_.equals(splice, prev[i])){
3363 equal = false;
3364 prev[i] = _.clone(splice);
3365 }
3366 }
3367 return equal? false: prev;
3368 }
3369 }else{
3370 expr = this.$expression? this.$expression(expr) : parseExpression(expr);
3371 get = expr.get;
3372 once = expr.once || expr.constant;
3373 }
3374
3375 var watcher = {
3376 id: uid,
3377 get: get,
3378 fn: fn,
3379 once: once,
3380 force: options.force,
3381 test: test,
3382 deep: options.deep
3383 }
3384
3385 this._watchers.push( watcher );
3386
3387 rlen = this._records && this._records.length;
3388 if(rlen) this._records[rlen-1].push(uid)
3389 // init state.
3390 if(options.init === true){
3391 this.$phase = 'digest';
3392 this._checkSingleWatch( watcher, this._watchers.length-1 );
3393 this.$phase = null;
3394 }
3395 return uid;
3396 },
3397 $unwatch: function(uid){
3398 if(!this._watchers) this._watchers = [];
3399 if(Array.isArray(uid)){
3400 for(var i =0, len = uid.length; i < len; i++){
3401 this.$unwatch(uid[i]);
3402 }
3403 }else{
3404 var watchers = this._watchers, watcher, wlen;
3405 if(!uid || !watchers || !(wlen = watchers.length)) return;
3406 for(;wlen--;){
3407 watcher = watchers[wlen];
3408 if(watcher && watcher.id === uid ){
3409 watchers.splice(wlen, 1);
3410 }
3411 }
3412 }
3413 },
3414 /**
3415 * the whole digest loop ,just like angular, it just a dirty-check loop;
3416 * @param {String} path now regular process a pure dirty-check loop, but in parse phase,
3417 * Regular's parser extract the dependencies, in future maybe it will change to dirty-check combine with path-aware update;
3418 * @return {Void}
3419 */
3420
3421 $digest: function(){
3422 if(this.$phase === 'digest') return;
3423 this.$phase = 'digest';
3424 var dirty = false, n =0;
3425 while(dirty = this._digest()){
3426
3427 if((++n) > 20){ // max loop
3428 throw 'there may a circular dependencies reaches'
3429 }
3430 }
3431 if( n > 0 && this.$emit) this.$emit("$update");
3432 this.$phase = null;
3433 },
3434 // private digest logic
3435 _digest: function(){
3436 // if(this.context) return this.context.$digest();
3437 // if(this.$emit) this.$emit('digest');
3438 var watchers = this._watchers;
3439 var dirty = false, children, watcher, watcherDirty;
3440 if(watchers && watchers.length){
3441 for(var i = 0, len = watchers.length;i < len; i++){
3442 watcher = watchers[i];
3443 watcherDirty = this._checkSingleWatch(watcher, i);
3444 if(watcherDirty) dirty = true;
3445 }
3446 }
3447 // check children's dirty.
3448 children = this._children;
3449 if(children && children.length){
3450 for(var m = 0, mlen = children.length; m < mlen; m++){
3451 if(children[m]._digest()) dirty = true;
3452 }
3453 }
3454 return dirty;
3455 },
3456 // check a single one watcher
3457 _checkSingleWatch: function(watcher, i){
3458 var dirty = false;
3459 if(!watcher) return;
3460 if(watcher.test) { //multi
3461 var result = watcher.test(this);
3462 if(result){
3463 dirty = true;
3464 watcher.fn.apply(this, result)
3465 }
3466 }else{
3467
3468 var now = watcher.get(this);
3469 var last = watcher.last;
3470 var eq = true;
3471
3472 if(_.typeOf( now ) === 'object' && watcher.deep){
3473 if(!watcher.last){
3474 eq = false;
3475 }else{
3476 for(var j in now){
3477 if(watcher.last[j] !== now[j]){
3478 eq = false;
3479 break;
3480 }
3481 }
3482 if(eq !== false){
3483 for(var n in last){
3484 if(last[n] !== now[n]){
3485 eq = false;
3486 break;
3487 }
3488 }
3489 }
3490 }
3491 }else{
3492 eq = _.equals(now, watcher.last);
3493 }
3494 if(eq === false || watcher.force){ // in some case. if undefined, we must force digest.
3495 eq = false;
3496 watcher.force = null;
3497 dirty = true;
3498 watcher.fn.call(this, now, watcher.last);
3499 if(typeof now !== 'object'|| watcher.deep){
3500 watcher.last = _.clone(now);
3501 }else{
3502 watcher.last = now;
3503 }
3504 }else{ // if eq == true
3505 if( _.typeOf(eq) === 'array' && eq.length ){
3506 watcher.last = _.clone(now);
3507 watcher.fn.call(this, now, eq);
3508 dirty = true;
3509 }else{
3510 eq = true;
3511 }
3512 }
3513 // @TODO
3514 if(dirty && watcher.once) this._watchers.splice(i, 1);
3515
3516 return dirty;
3517 }
3518 },
3519
3520 /**
3521 * **tips**: whatever param you passed in $update, after the function called, dirty-check(digest) phase will enter;
3522 *
3523 * @param {Function|String|Expression} path
3524 * @param {Whatever} value optional, when path is Function, the value is ignored
3525 * @return {this} this
3526 */
3527 $update: function(path, value){
3528 if(path != null){
3529 var type = _.typeOf(path);
3530 if( type === 'string' || path.type === 'expression' ){
3531 path = parseExpression(path);
3532 path.set(this, value);
3533 }else if(type === 'function'){
3534 path.call(this, this.data);
3535 }else{
3536 for(var i in path) {
3537 if(path.hasOwnProperty(i)){
3538 this.data[i] = path[i];
3539 }
3540 }
3541 }
3542 }
3543 if(this.$root) this.$root.$digest()
3544 },
3545 // auto collect watchers for logic-control.
3546 _record: function(){
3547 if(!this._records) this._records = [];
3548 this._records.push([]);
3549 },
3550 _release: function(){
3551 return this._records.pop();
3552 }
3553}
3554
3555
3556_.extend(Watcher.prototype, methods)
3557
3558
3559Watcher.mixTo = function(obj){
3560 obj = typeof obj === "function" ? obj.prototype : obj;
3561 return _.extend(obj, methods)
3562}
3563
3564module.exports = Watcher;
3565});
3566require.register("regularjs/src/helper/event.js", function(exports, require, module){
3567// simplest event emitter 60 lines
3568// ===============================
3569var slice = [].slice, _ = require("../util.js");
3570var buildin = ['$inject', "$init", "$destroy", "$update"];
3571var API = {
3572 $on: function(event, fn) {
3573 if(typeof event === "object"){
3574 for (var i in event) {
3575 this.$on(i, event[i]);
3576 }
3577 }else{
3578 // @patch: for list
3579 var context = this;
3580 var handles = context._handles || (context._handles = {}),
3581 calls = handles[event] || (handles[event] = []);
3582 calls.push(fn);
3583 }
3584 return this;
3585 },
3586 $off: function(event, fn) {
3587 var context = this;
3588 if(!context._handles) return;
3589 if(!event) this._handles = {};
3590 var handles = context._handles,
3591 calls;
3592
3593 if (calls = handles[event]) {
3594 if (!fn) {
3595 handles[event] = [];
3596 return context;
3597 }
3598 for (var i = 0, len = calls.length; i < len; i++) {
3599 if (fn === calls[i]) {
3600 calls.splice(i, 1);
3601 return context;
3602 }
3603 }
3604 }
3605 return context;
3606 },
3607 // bubble event
3608 $emit: function(event){
3609 // @patch: for list
3610 var context = this;
3611 var handles = context._handles, calls, args, type;
3612 if(!event) return;
3613 var args = slice.call(arguments, 1);
3614 var type = event;
3615
3616 if(!handles) return context;
3617 // @deprecated 0.3.0
3618 // will be removed when completely remove the old events('destroy' 'init') support
3619
3620 /*@remove 0.4.0*/
3621 var isBuildin = ~buildin.indexOf(type);
3622 if(calls = handles[type.slice(1)]){
3623 for (var j = 0, len = calls.length; j < len; j++) {
3624 calls[j].apply(context, args)
3625 }
3626 }
3627 /*/remove*/
3628
3629 if (!(calls = handles[type])) return context;
3630 for (var i = 0, len = calls.length; i < len; i++) {
3631 calls[i].apply(context, args)
3632 }
3633 // if(calls.length) context.$update();
3634 return context;
3635 },
3636 // capture event
3637 $broadcast: function(){
3638
3639 }
3640}
3641// container class
3642function Event() {
3643 if (arguments.length) this.$on.apply(this, arguments);
3644}
3645_.extend(Event.prototype, API)
3646
3647Event.mixTo = function(obj){
3648 obj = typeof obj === "function" ? obj.prototype : obj;
3649 _.extend(obj, API)
3650}
3651module.exports = Event;
3652});
3653require.register("regularjs/src/helper/animate.js", function(exports, require, module){
3654var _ = require("../util");
3655var dom = require("../dom.js");
3656var animate = {};
3657var env = require("../env.js");
3658
3659
3660var
3661 transitionEnd = 'transitionend',
3662 animationEnd = 'animationend',
3663 transitionProperty = 'transition',
3664 animationProperty = 'animation';
3665
3666if(!('ontransitionend' in window)){
3667 if('onwebkittransitionend' in window) {
3668
3669 // Chrome/Saf (+ Mobile Saf)/Android
3670 transitionEnd += ' webkitTransitionEnd';
3671 transitionProperty = 'webkitTransition'
3672 } else if('onotransitionend' in dom.tNode || navigator.appName === 'Opera') {
3673
3674 // Opera
3675 transitionEnd += ' oTransitionEnd';
3676 transitionProperty = 'oTransition';
3677 }
3678}
3679if(!('onanimationend' in window)){
3680 if ('onwebkitanimationend' in window){
3681 // Chrome/Saf (+ Mobile Saf)/Android
3682 animationEnd += ' webkitAnimationEnd';
3683 animationProperty = 'webkitAnimation';
3684
3685 }else if ('onoanimationend' in dom.tNode){
3686 // Opera
3687 animationEnd += ' oAnimationEnd';
3688 animationProperty = 'oAnimation';
3689 }
3690}
3691
3692/**
3693 * inject node with animation
3694 * @param {[type]} node [description]
3695 * @param {[type]} refer [description]
3696 * @param {[type]} direction [description]
3697 * @return {[type]} [description]
3698 */
3699animate.inject = function( node, refer ,direction, callback ){
3700 callback = callback || _.noop;
3701 if( Array.isArray(node) ){
3702 var fragment = dom.fragment();
3703 var count=0;
3704
3705 for(var i = 0,len = node.length;i < len; i++ ){
3706 fragment.appendChild(node[i]);
3707 }
3708 dom.inject(fragment, refer, direction);
3709
3710 var enterCallback = function (){
3711 count++;
3712 if( count === len ) callback();
3713 }
3714 if(len === count) callback();
3715 for( i = 0; i < len; i++ ){
3716 if(node[i].onenter){
3717 node[i].onenter(enterCallback);
3718 }else{
3719 enterCallback();
3720 }
3721 }
3722 }else{
3723 dom.inject( node, refer, direction );
3724 if(node.onenter){
3725 node.onenter(callback)
3726 }else{
3727 callback();
3728 }
3729 // if( node.nodeType === 1 && callback !== false ){
3730 // return startClassAnimate( node, 'r-enter', callback , 2);
3731 // }
3732 // ignored else
3733
3734 }
3735}
3736
3737/**
3738 * remove node with animation
3739 * @param {[type]} node [description]
3740 * @param {Function} callback [description]
3741 * @return {[type]} [description]
3742 */
3743animate.remove = function(node, callback){
3744 callback = callback || _.noop;
3745 if(node.onleave){
3746 node.onleave(function(){
3747 dom.remove(node);
3748 })
3749 }else{
3750 dom.remove(node)
3751 callback && callback();
3752 }
3753}
3754
3755
3756
3757animate.startClassAnimate = function ( node, className, callback, mode ){
3758 var activeClassName, timeout, tid, onceAnim;
3759 if( (!animationEnd && !transitionEnd) || env.isRunning ){
3760 return callback();
3761 }
3762
3763
3764 onceAnim = _.once(function onAnimateEnd(){
3765 if(tid) clearTimeout(tid);
3766
3767 if(mode === 2) {
3768 dom.delClass(node, activeClassName);
3769 }
3770 if(mode !== 3){ // mode hold the class
3771 dom.delClass(node, className);
3772 }
3773 dom.off(node, animationEnd, onceAnim)
3774 dom.off(node, transitionEnd, onceAnim)
3775
3776 callback();
3777
3778 });
3779 if(mode === 2){ // auto removed
3780 dom.addClass( node, className );
3781
3782 activeClassName = className.split(/\s+/).map(function(name){
3783 return name + '-active';
3784 }).join(" ");
3785
3786 dom.nextReflow(function(){
3787 dom.addClass( node, activeClassName );
3788 timeout = getMaxTimeout( node );
3789 tid = setTimeout( onceAnim, timeout );
3790 });
3791
3792 }else{
3793
3794 dom.nextReflow(function(){
3795 dom.addClass( node, className );
3796 timeout = getMaxTimeout( node );
3797 tid = setTimeout( onceAnim, timeout );
3798 });
3799
3800 }
3801
3802
3803 dom.on( node, animationEnd, onceAnim )
3804 dom.on( node, transitionEnd, onceAnim )
3805 return onceAnim;
3806}
3807
3808
3809animate.startStyleAnimate = function(node, styles, callback){
3810 var timeout, onceAnim, tid;
3811
3812 dom.nextReflow(function(){
3813 dom.css( node, styles );
3814 timeout = getMaxTimeout( node );
3815 tid = setTimeout( onceAnim, timeout );
3816 });
3817
3818
3819 onceAnim = _.once(function onAnimateEnd(){
3820 if(tid) clearTimeout(tid);
3821
3822 dom.off(node, animationEnd, onceAnim)
3823 dom.off(node, transitionEnd, onceAnim)
3824
3825 callback();
3826
3827 });
3828
3829 dom.on( node, animationEnd, onceAnim )
3830 dom.on( node, transitionEnd, onceAnim )
3831
3832 return onceAnim;
3833}
3834
3835
3836/**
3837 * get maxtimeout
3838 * @param {Node} node
3839 * @return {[type]} [description]
3840 */
3841function getMaxTimeout(node){
3842 var timeout = 0,
3843 tDuration = 0,
3844 tDelay = 0,
3845 aDuration = 0,
3846 aDelay = 0,
3847 ratio = 5 / 3,
3848 styles ;
3849
3850 if(window.getComputedStyle){
3851
3852 styles = window.getComputedStyle(node),
3853 tDuration = getMaxTime( styles[transitionProperty + 'Duration']) || tDuration;
3854 tDelay = getMaxTime( styles[transitionProperty + 'Delay']) || tDelay;
3855 aDuration = getMaxTime( styles[animationProperty + 'Duration']) || aDuration;
3856 aDelay = getMaxTime( styles[animationProperty + 'Delay']) || aDelay;
3857 timeout = Math.max( tDuration+tDelay, aDuration + aDelay );
3858
3859 }
3860 return timeout * 1000 * ratio;
3861}
3862
3863function getMaxTime(str){
3864
3865 var maxTimeout = 0, time;
3866
3867 if(!str) return 0;
3868
3869 str.split(",").forEach(function(str){
3870
3871 time = parseFloat(str);
3872 if( time > maxTimeout ) maxTimeout = time;
3873
3874 });
3875
3876 return maxTimeout;
3877}
3878
3879module.exports = animate;
3880});
3881require.register("regularjs/src/helper/combine.js", function(exports, require, module){
3882// some nested operation in ast
3883// --------------------------------
3884
3885var dom = require("../dom.js");
3886
3887var combine = module.exports = {
3888
3889 // get the initial dom in object
3890 node: function(item){
3891 var children,node;
3892 if(item.element) return item.element;
3893 if(typeof item.node === "function") return item.node();
3894 if(typeof item.nodeType === "number") return item;
3895 if(item.group) return combine.node(item.group)
3896 if(children = item.children){
3897 if(children.length === 1){
3898
3899 return combine.node(children[0]);
3900 }
3901 var nodes = [];
3902 for(var i = 0, len = children.length; i < len; i++ ){
3903 node = combine.node(children[i]);
3904 if(Array.isArray(node)){
3905 nodes.push.apply(nodes, node)
3906 }else{
3907 nodes.push(node)
3908 }
3909 }
3910 return nodes;
3911 }
3912 },
3913
3914 // get the last dom in object(for insertion operation)
3915 last: function(item){
3916 var children = item.children;
3917
3918 if(typeof item.last === "function") return item.last();
3919 if(typeof item.nodeType === "number") return item;
3920
3921 if(children && children.length) return combine.last(children[children.length - 1]);
3922 if(item.group) return combine.last(item.group);
3923
3924 },
3925
3926 destroy: function(item, first){
3927 if(!item) return;
3928 if(Array.isArray(item)){
3929 for(var i = 0, len = item.length; i < len; i++ ){
3930 combine.destroy(item[i], first);
3931 }
3932 }
3933 var children = item.children;
3934 if(typeof item.destroy === "function") return item.destroy(first);
3935 if(typeof item.nodeType === "number" && first) dom.remove(item);
3936 if(children && children.length){
3937 combine.destroy(children, true);
3938 item.children = null;
3939 }
3940 }
3941
3942}
3943});
3944require.register("regularjs/src/helper/entities.js", function(exports, require, module){
3945// http://stackoverflow.com/questions/1354064/how-to-convert-characters-to-html-entities-using-plain-javascript
3946var entities = {
3947 'quot':34,
3948 'amp':38,
3949 'apos':39,
3950 'lt':60,
3951 'gt':62,
3952 'nbsp':160,
3953 'iexcl':161,
3954 'cent':162,
3955 'pound':163,
3956 'curren':164,
3957 'yen':165,
3958 'brvbar':166,
3959 'sect':167,
3960 'uml':168,
3961 'copy':169,
3962 'ordf':170,
3963 'laquo':171,
3964 'not':172,
3965 'shy':173,
3966 'reg':174,
3967 'macr':175,
3968 'deg':176,
3969 'plusmn':177,
3970 'sup2':178,
3971 'sup3':179,
3972 'acute':180,
3973 'micro':181,
3974 'para':182,
3975 'middot':183,
3976 'cedil':184,
3977 'sup1':185,
3978 'ordm':186,
3979 'raquo':187,
3980 'frac14':188,
3981 'frac12':189,
3982 'frac34':190,
3983 'iquest':191,
3984 'Agrave':192,
3985 'Aacute':193,
3986 'Acirc':194,
3987 'Atilde':195,
3988 'Auml':196,
3989 'Aring':197,
3990 'AElig':198,
3991 'Ccedil':199,
3992 'Egrave':200,
3993 'Eacute':201,
3994 'Ecirc':202,
3995 'Euml':203,
3996 'Igrave':204,
3997 'Iacute':205,
3998 'Icirc':206,
3999 'Iuml':207,
4000 'ETH':208,
4001 'Ntilde':209,
4002 'Ograve':210,
4003 'Oacute':211,
4004 'Ocirc':212,
4005 'Otilde':213,
4006 'Ouml':214,
4007 'times':215,
4008 'Oslash':216,
4009 'Ugrave':217,
4010 'Uacute':218,
4011 'Ucirc':219,
4012 'Uuml':220,
4013 'Yacute':221,
4014 'THORN':222,
4015 'szlig':223,
4016 'agrave':224,
4017 'aacute':225,
4018 'acirc':226,
4019 'atilde':227,
4020 'auml':228,
4021 'aring':229,
4022 'aelig':230,
4023 'ccedil':231,
4024 'egrave':232,
4025 'eacute':233,
4026 'ecirc':234,
4027 'euml':235,
4028 'igrave':236,
4029 'iacute':237,
4030 'icirc':238,
4031 'iuml':239,
4032 'eth':240,
4033 'ntilde':241,
4034 'ograve':242,
4035 'oacute':243,
4036 'ocirc':244,
4037 'otilde':245,
4038 'ouml':246,
4039 'divide':247,
4040 'oslash':248,
4041 'ugrave':249,
4042 'uacute':250,
4043 'ucirc':251,
4044 'uuml':252,
4045 'yacute':253,
4046 'thorn':254,
4047 'yuml':255,
4048 'fnof':402,
4049 'Alpha':913,
4050 'Beta':914,
4051 'Gamma':915,
4052 'Delta':916,
4053 'Epsilon':917,
4054 'Zeta':918,
4055 'Eta':919,
4056 'Theta':920,
4057 'Iota':921,
4058 'Kappa':922,
4059 'Lambda':923,
4060 'Mu':924,
4061 'Nu':925,
4062 'Xi':926,
4063 'Omicron':927,
4064 'Pi':928,
4065 'Rho':929,
4066 'Sigma':931,
4067 'Tau':932,
4068 'Upsilon':933,
4069 'Phi':934,
4070 'Chi':935,
4071 'Psi':936,
4072 'Omega':937,
4073 'alpha':945,
4074 'beta':946,
4075 'gamma':947,
4076 'delta':948,
4077 'epsilon':949,
4078 'zeta':950,
4079 'eta':951,
4080 'theta':952,
4081 'iota':953,
4082 'kappa':954,
4083 'lambda':955,
4084 'mu':956,
4085 'nu':957,
4086 'xi':958,
4087 'omicron':959,
4088 'pi':960,
4089 'rho':961,
4090 'sigmaf':962,
4091 'sigma':963,
4092 'tau':964,
4093 'upsilon':965,
4094 'phi':966,
4095 'chi':967,
4096 'psi':968,
4097 'omega':969,
4098 'thetasym':977,
4099 'upsih':978,
4100 'piv':982,
4101 'bull':8226,
4102 'hellip':8230,
4103 'prime':8242,
4104 'Prime':8243,
4105 'oline':8254,
4106 'frasl':8260,
4107 'weierp':8472,
4108 'image':8465,
4109 'real':8476,
4110 'trade':8482,
4111 'alefsym':8501,
4112 'larr':8592,
4113 'uarr':8593,
4114 'rarr':8594,
4115 'darr':8595,
4116 'harr':8596,
4117 'crarr':8629,
4118 'lArr':8656,
4119 'uArr':8657,
4120 'rArr':8658,
4121 'dArr':8659,
4122 'hArr':8660,
4123 'forall':8704,
4124 'part':8706,
4125 'exist':8707,
4126 'empty':8709,
4127 'nabla':8711,
4128 'isin':8712,
4129 'notin':8713,
4130 'ni':8715,
4131 'prod':8719,
4132 'sum':8721,
4133 'minus':8722,
4134 'lowast':8727,
4135 'radic':8730,
4136 'prop':8733,
4137 'infin':8734,
4138 'ang':8736,
4139 'and':8743,
4140 'or':8744,
4141 'cap':8745,
4142 'cup':8746,
4143 'int':8747,
4144 'there4':8756,
4145 'sim':8764,
4146 'cong':8773,
4147 'asymp':8776,
4148 'ne':8800,
4149 'equiv':8801,
4150 'le':8804,
4151 'ge':8805,
4152 'sub':8834,
4153 'sup':8835,
4154 'nsub':8836,
4155 'sube':8838,
4156 'supe':8839,
4157 'oplus':8853,
4158 'otimes':8855,
4159 'perp':8869,
4160 'sdot':8901,
4161 'lceil':8968,
4162 'rceil':8969,
4163 'lfloor':8970,
4164 'rfloor':8971,
4165 'lang':9001,
4166 'rang':9002,
4167 'loz':9674,
4168 'spades':9824,
4169 'clubs':9827,
4170 'hearts':9829,
4171 'diams':9830,
4172 'OElig':338,
4173 'oelig':339,
4174 'Scaron':352,
4175 'scaron':353,
4176 'Yuml':376,
4177 'circ':710,
4178 'tilde':732,
4179 'ensp':8194,
4180 'emsp':8195,
4181 'thinsp':8201,
4182 'zwnj':8204,
4183 'zwj':8205,
4184 'lrm':8206,
4185 'rlm':8207,
4186 'ndash':8211,
4187 'mdash':8212,
4188 'lsquo':8216,
4189 'rsquo':8217,
4190 'sbquo':8218,
4191 'ldquo':8220,
4192 'rdquo':8221,
4193 'bdquo':8222,
4194 'dagger':8224,
4195 'Dagger':8225,
4196 'permil':8240,
4197 'lsaquo':8249,
4198 'rsaquo':8250,
4199 'euro':8364
4200}
4201
4202
4203
4204module.exports = entities;
4205});
4206require.register("regularjs/src/directive/base.js", function(exports, require, module){
4207// Regular
4208var _ = require("../util.js");
4209var dom = require("../dom.js");
4210var animate = require("../helper/animate.js");
4211var Regular = require("../Regular.js");
4212
4213
4214
4215require("./event.js");
4216require("./form.js");
4217
4218
4219// **warn**: class inteplation will override this directive
4220
4221Regular.directive('r-class', function(elem, value){
4222 this.$watch(value, function(nvalue){
4223 var className = ' '+ elem.className.replace(/\s+/g, ' ') +' ';
4224 for(var i in nvalue) if(nvalue.hasOwnProperty(i)){
4225 className = className.replace(' ' + i + ' ',' ');
4226 if(nvalue[i] === true){
4227 className += i+' ';
4228 }
4229 }
4230 elem.className = className.trim();
4231 },true);
4232
4233});
4234
4235// **warn**: style inteplation will override this directive
4236
4237Regular.directive('r-style', function(elem, value){
4238 this.$watch(value, function(nvalue){
4239 for(var i in nvalue) if(nvalue.hasOwnProperty(i)){
4240 dom.css(elem, i, nvalue[i]);
4241 }
4242 },true);
4243});
4244
4245// when expression is evaluate to true, the elem will add display:none
4246// Example: <div r-hide={{items.length > 0}}></div>
4247
4248Regular.directive('r-hide', function(elem, value){
4249 var preBool = null, compelete;
4250 this.$watch(value, function(nvalue){
4251 var bool = !!nvalue;
4252 if(bool === preBool) return;
4253 preBool = bool;
4254 if(bool){
4255 if(elem.onleave){
4256 compelete = elem.onleave(function(){
4257 elem.style.display = "none"
4258 compelete = null;
4259 })
4260 }else{
4261 elem.style.display = "none"
4262 }
4263
4264 }else{
4265 if(compelete) compelete();
4266 elem.style.display = "";
4267 if(elem.onenter){
4268 elem.onenter();
4269 }
4270 }
4271 });
4272
4273});
4274
4275// unescaped inteplation. xss is not be protect
4276Regular.directive('r-html', function(elem, value){
4277 this.$watch(value, function(nvalue){
4278 nvalue = nvalue || "";
4279 dom.html(elem, nvalue)
4280 }, {force: true});
4281});
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292});
4293require.register("regularjs/src/directive/form.js", function(exports, require, module){
4294// Regular
4295var _ = require("../util.js");
4296var dom = require("../dom.js");
4297var Regular = require("../Regular.js");
4298
4299var modelHandlers = {
4300 "text": initText,
4301 "select": initSelect,
4302 "checkbox": initCheckBox,
4303 "radio": initRadio
4304}
4305
4306
4307// @TODO
4308
4309
4310// two-way binding with r-model
4311// works on input, textarea, checkbox, radio, select
4312
4313Regular.directive("r-model", function(elem, value){
4314 var tag = elem.tagName.toLowerCase();
4315 var sign = tag;
4316 if(sign === "input") sign = elem.type || "text";
4317 else if(sign === "textarea") sign = "text";
4318 if(typeof value === "string") value = Regular.expression(value);
4319
4320 if( modelHandlers[sign] ) return modelHandlers[sign].call(this, elem, value);
4321 else if(tag === "input"){
4322 return modelHandlers.text.call(this, elem, value);
4323 }
4324});
4325
4326
4327
4328// binding <select>
4329
4330function initSelect( elem, parsed){
4331 var self = this;
4332 var inProgress = false;
4333 this.$watch(parsed, function(newValue){
4334 if(inProgress) return;
4335 var children = _.slice(elem.getElementsByTagName('option'))
4336 children.forEach(function(node, index){
4337 if(node.value == newValue){
4338 elem.selectedIndex = index;
4339 }
4340 })
4341 });
4342
4343 function handler(){
4344 parsed.set(self, this.value);
4345 inProgress = true;
4346 self.$update();
4347 inProgress = false;
4348 }
4349
4350 dom.on(elem, "change", handler);
4351
4352 if(parsed.get(self) === undefined && elem.value){
4353 parsed.set(self, elem.value);
4354 }
4355 return function destroy(){
4356 dom.off(elem, "change", handler);
4357 }
4358}
4359
4360// input,textarea binding
4361
4362function initText(elem, parsed){
4363 var inProgress = false;
4364 var self = this;
4365 this.$watch(parsed, function(newValue){
4366 if(inProgress){ return; }
4367 if(elem.value !== newValue) elem.value = newValue == null? "": "" + newValue;
4368 });
4369
4370 // @TODO to fixed event
4371 var handler = function handler(ev){
4372 var that = this;
4373 if(ev.type==='cut' || ev.type==='paste'){
4374 _.nextTick(function(){
4375 var value = that.value
4376 parsed.set(self, value);
4377 inProgress = true;
4378 self.$update();
4379 })
4380 }else{
4381 var value = that.value
4382 parsed.set(self, value);
4383 inProgress = true;
4384 self.$update();
4385 }
4386 inProgress = false;
4387 };
4388
4389 if(dom.msie !== 9 && "oninput" in dom.tNode ){
4390 elem.addEventListener("input", handler );
4391 }else{
4392 dom.on(elem, "paste", handler)
4393 dom.on(elem, "keyup", handler)
4394 dom.on(elem, "cut", handler)
4395 dom.on(elem, "change", handler)
4396 }
4397 if(parsed.get(self) === undefined && elem.value){
4398 parsed.set(self, elem.value);
4399 }
4400 return function destroy(){
4401 if(dom.msie !== 9 && "oninput" in dom.tNode ){
4402 elem.removeEventListener("input", handler );
4403 }else{
4404 dom.off(elem, "paste", handler)
4405 dom.off(elem, "keyup", handler)
4406 dom.off(elem, "cut", handler)
4407 dom.off(elem, "change", handler)
4408 }
4409 }
4410}
4411
4412
4413// input:checkbox binding
4414
4415function initCheckBox(elem, parsed){
4416 var inProgress = false;
4417 var self = this;
4418 this.$watch(parsed, function(newValue){
4419 if(inProgress) return;
4420 dom.attr(elem, 'checked', !!newValue);
4421 });
4422
4423 var handler = function handler(){
4424 var value = this.checked;
4425 parsed.set(self, value);
4426 inProgress= true;
4427 self.$update();
4428 inProgress = false;
4429 }
4430 if(parsed.set) dom.on(elem, "change", handler)
4431
4432 if(parsed.get(self) === undefined){
4433 parsed.set(self, !!elem.checked);
4434 }
4435
4436 return function destroy(){
4437 if(parsed.set) dom.off(elem, "change", handler)
4438 }
4439}
4440
4441
4442// input:radio binding
4443
4444function initRadio(elem, parsed){
4445 var self = this;
4446 var inProgress = false;
4447 this.$watch(parsed, function( newValue ){
4448 if(inProgress) return;
4449 if(newValue == elem.value) elem.checked = true;
4450 });
4451
4452
4453 var handler = function handler(){
4454 var value = this.value;
4455 parsed.set(self, value);
4456 inProgress= true;
4457 self.$update();
4458 inProgress = false;
4459 }
4460 if(parsed.set) dom.on(elem, "change", handler)
4461 // beacuse only after compile(init), the dom structrue is exsit.
4462 if(parsed.get(self) === undefined){
4463 if(elem.checked) parsed.set(self, elem.value);
4464 }
4465
4466 return function destroy(){
4467 if(parsed.set) dom.off(elem, "change", handler)
4468 }
4469}
4470
4471});
4472require.register("regularjs/src/directive/animation.js", function(exports, require, module){
4473var // packages
4474 _ = require("../util.js"),
4475 animate = require("../helper/animate.js"),
4476 dom = require("../dom.js"),
4477 Regular = require("../Regular.js");
4478
4479
4480var // variables
4481 rClassName = /^[-\w]+(\s[-\w]+)*$/,
4482 rCommaSep = /[\r\n\f ]*,[\r\n\f ]*(?=\w+\:)/, // dont split comma in Expression
4483 rStyles = /^\{.*\}$/, // for Simpilfy
4484 rSpace = /\s+/, // for Simpilfy
4485 WHEN_COMMAND = "when",
4486 EVENT_COMMAND = "on",
4487 THEN_COMMAND = "then";
4488
4489/**
4490 * Animation Plugin
4491 * @param {Component} Component
4492 */
4493
4494
4495function createSeed(type){
4496
4497 var steps = [], current = 0, callback = _.noop;
4498 var key;
4499
4500 var out = {
4501 type: type,
4502 start: function(cb){
4503 key = _.uid();
4504 if(typeof cb === "function") callback = cb;
4505 if(current> 0 ){
4506 current = 0 ;
4507 }else{
4508 out.step();
4509 }
4510 return out.compelete;
4511 },
4512 compelete: function(){
4513 key = null;
4514 callback && callback();
4515 callback = _.noop;
4516 current = 0;
4517 },
4518 step: function(){
4519 if(steps[current]) steps[current ]( out.done.bind(out, key) );
4520 },
4521 done: function(pkey){
4522 if(pkey !== key) return; // means the loop is down
4523 if( current < steps.length - 1 ) {
4524 current++;
4525 out.step();
4526 }else{
4527 out.compelete();
4528 }
4529 },
4530 push: function(step){
4531 steps.push(step)
4532 }
4533 }
4534
4535 return out;
4536}
4537
4538Regular._addProtoInheritCache("animation")
4539
4540
4541// builtin animation
4542Regular.animation({
4543 "wait": function( step ){
4544 var timeout = parseInt( step.param ) || 0
4545 return function(done){
4546 // _.log("delay " + timeout)
4547 setTimeout( done, timeout );
4548 }
4549 },
4550 "class": function(step){
4551 var tmp = step.param.split(","),
4552 className = tmp[0] || "",
4553 mode = parseInt(tmp[1]) || 1;
4554
4555 return function(done){
4556 // _.log(className)
4557 animate.startClassAnimate( step.element, className , done, mode );
4558 }
4559 },
4560 "call": function(step){
4561 var fn = Regular.expression(step.param).get, self = this;
4562 return function(done){
4563 // _.log(step.param, 'call')
4564 fn(self);
4565 self.$update();
4566 done()
4567 }
4568 },
4569 "emit": function(step){
4570 var param = step.param;
4571 var self = this;
4572 return function(done){
4573 self.$emit(param, step);
4574 done();
4575 }
4576 },
4577 // style: left {{10}}pxkk,
4578 style: function(step){
4579 var styles = {},
4580 param = step.param,
4581 pairs = param.split(","), valid;
4582 pairs.forEach(function(pair){
4583 pair = pair.trim();
4584 if(pair){
4585 var tmp = pair.split( rSpace ),
4586 name = tmp.shift(),
4587 value = tmp.join(" ");
4588
4589 if( !name || !value ) throw "invalid style in command: style";
4590 styles[name] = value;
4591 valid = true;
4592 }
4593 })
4594
4595 return function(done){
4596 if(valid){
4597 animate.startStyleAnimate(step.element, styles, done);
4598 }else{
4599 done();
4600 }
4601 }
4602 }
4603})
4604
4605
4606
4607// hancdle the r-animation directive
4608// el : the element to process
4609// value: the directive value
4610function processAnimate( element, value ){
4611 value = value.trim();
4612
4613 var composites = value.split(";"),
4614 composite, context = this, seeds = [], seed, destroies = [], destroy,
4615 command, param , current = 0, tmp, animator, self = this;
4616
4617 function reset( type ){
4618 seed && seeds.push( seed )
4619 seed = createSeed( type );
4620 }
4621
4622 function whenCallback(start, value){
4623 if( !!value ) start()
4624 }
4625
4626 function animationDestroy(element){
4627 return function(){
4628 element.onenter = undefined;
4629 element.onleave = undefined;
4630 }
4631 }
4632
4633 for( var i = 0, len = composites.length; i < len; i++ ){
4634
4635 composite = composites[i];
4636 tmp = composite.split(":");
4637 command = tmp[0] && tmp[0].trim();
4638 param = tmp[1] && tmp[1].trim();
4639
4640 if( !command ) continue;
4641
4642 if( command === WHEN_COMMAND ){
4643 reset("when");
4644 this.$watch(param, whenCallback.bind( this, seed.start ) );
4645 continue;
4646 }
4647
4648 if( command === EVENT_COMMAND){
4649 reset(param);
4650 if(param === "leave"){
4651 element.onleave = seed.start;
4652 }else if(param === "enter"){
4653 element.onenter = seed.start;
4654 }else{
4655 destroy = this._handleEvent( element, param, seed.start );
4656 }
4657
4658 destroies.push( destroy? destroy : animationDestroy(element) );
4659 destroy = null;
4660 continue
4661 }
4662
4663 var animator = Regular.animation(command)
4664 if( animator && seed ){
4665 seed.push(
4666 animator.call(this,{
4667 element: element,
4668 done: seed.done,
4669 param: param
4670 })
4671 )
4672 }else{
4673 throw "you need start with `on` or `event` in r-animation";
4674 }
4675 }
4676
4677 if(destroies.length){
4678 return function(){
4679 destroies.forEach(function(destroy){
4680 destroy();
4681 })
4682 }
4683 }
4684}
4685
4686
4687Regular.directive( "r-animation", processAnimate)
4688
4689
4690
4691});
4692require.register("regularjs/src/directive/event.js", function(exports, require, module){
4693/**
4694 * event directive bundle
4695 *
4696 */
4697var _ = require("../util.js");
4698var dom = require("../dom.js");
4699var Regular = require("../Regular.js");
4700
4701Regular._addProtoInheritCache("event");
4702
4703Regular.event( "enter" , function(elem, fire) {
4704 function update( ev ) {
4705 if ( ev.which === 13 ) {
4706 ev.preventDefault();
4707 fire(ev);
4708 }
4709 }
4710 dom.on( elem, "keypress", update );
4711
4712 return function() {
4713 dom.off( elem, "keypress", update );
4714 }
4715})
4716
4717
4718Regular.directive( /^on-\w+$/, function( elem, value, name , attrs) {
4719 if ( !name || !value ) return;
4720 var type = name.split("-")[1];
4721 return this._handleEvent( elem, type, value, attrs );
4722});
4723// TODO.
4724/**
4725- $('dx').delegate()
4726*/
4727Regular.directive( /^delegate-\w+$/, function( elem, value, name, attrs ) {
4728 var root = this.$root;
4729 var _delegates = root._delegates || ( root._delegates = {} );
4730 if ( !name || !value ) return;
4731 var type = name.split("-")[1];
4732 var fire = _.handleEvent.call(this, value, type);
4733
4734 function delegateEvent(ev){
4735 matchParent(ev, _delegates[type]);
4736 }
4737
4738 if( !_delegates[type] ){
4739 _delegates[type] = [];
4740
4741 root.$on( "$inject", function( newParent ){
4742 var preParent = this.parentNode;
4743 if( preParent ){
4744 dom.off(preParent, type, delegateEvent);
4745 }
4746 dom.on(newParent, type, delegateEvent);
4747 })
4748
4749 root.$on("$destroy", function(){
4750 if(root.parentNode) dom.off(root.parentNode, type, delegateEvent)
4751 root._delegates[type] = null;
4752 })
4753 }
4754 var delegate = {
4755 element: elem,
4756 fire: fire
4757 }
4758 _delegates[type].push( delegate );
4759
4760 return function(){
4761 var delegates = _delegates[type];
4762 if(!delegates || !delegates.length) return;
4763 for( var i = 0, len = delegates.length; i < len; i++ ){
4764 if( delegates[i] === delegate ) delegates.splice(i, 1);
4765 }
4766 }
4767
4768});
4769
4770
4771function matchParent(ev , delegates){
4772 var target = ev.target;
4773 while(target && target !== dom.doc){
4774 for( var i = 0, len = delegates.length; i < len; i++ ){
4775 if(delegates[i].element === target){
4776 delegates[i].fire(ev);
4777 }
4778 }
4779 target = target.parentNode;
4780 }
4781}
4782});
4783require.register("regularjs/src/module/timeout.js", function(exports, require, module){
4784var Regular = require("../Regular.js");
4785
4786/**
4787 * Timeout Module
4788 * @param {Component} Component
4789 */
4790function TimeoutModule(Component){
4791
4792 Component.implement({
4793 /**
4794 * just like setTimeout, but will enter digest automately
4795 * @param {Function} fn
4796 * @param {Number} delay
4797 * @return {Number} timeoutid
4798 */
4799 $timeout: function(fn, delay){
4800 delay = delay || 0;
4801 return setTimeout(function(){
4802 fn.call(this);
4803 this.$update(); //enter digest
4804 }.bind(this), delay);
4805 },
4806 /**
4807 * just like setInterval, but will enter digest automately
4808 * @param {Function} fn
4809 * @param {Number} interval
4810 * @return {Number} intervalid
4811 */
4812 $interval: function(fn, interval){
4813 interval = interval || 1000/60;
4814 return setInterval(function(){
4815 fn.call(this);
4816 this.$update(); //enter digest
4817 }.bind(this), interval);
4818 }
4819 });
4820}
4821
4822
4823Regular.plugin('timeout', TimeoutModule);
4824});
4825require.alias("regularjs/src/index.js", "regularjs/index.js");
\No newline at end of file