cmps
Version:
cmps is not only a server tool but also a powerful tool to design & make your component/UI quickly and best.
1,777 lines (1,517 loc) • 149 kB
JavaScript
/**
@author leeluolee
@version 0.5.1
@homepage http://regularjs.github.io
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define(factory);
else if(typeof exports === 'object')
exports["Regular"] = factory();
else
root["Regular"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
var env = __webpack_require__(1);
var config = __webpack_require__(2);
var Regular = module.exports = __webpack_require__(3);
var Parser = Regular.Parser;
var Lexer = Regular.Lexer;
if(env.browser){
__webpack_require__(6);
__webpack_require__(7);
__webpack_require__(8);
Regular.dom = __webpack_require__(4);
}
Regular.env = env;
Regular.util = __webpack_require__(5);
Regular.parse = function(str, options){
options = options || {};
if(options.BEGIN || options.END){
if(options.BEGIN) config.BEGIN = options.BEGIN;
if(options.END) config.END = options.END;
Lexer.setup();
}
var ast = new Parser(str).parse();
return !options.stringify? ast : JSON.stringify(ast);
}
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
// some fixture test;
// ---------------
var _ = __webpack_require__(5);
exports.svg = (function(){
return typeof document !== "undefined" && document.implementation.hasFeature( "http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1" );
})();
exports.browser = typeof document !== "undefined" && document.nodeType;
// whether have component in initializing
exports.exprCache = _.cache(1000);
exports.isRunning = false;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
module.exports = {
'BEGIN': '{',
'END': '}',
'PRECOMPILE': false
}
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
var env = __webpack_require__(1);
var Lexer = __webpack_require__(12);
var Parser = __webpack_require__(13);
var config = __webpack_require__(2);
var _ = __webpack_require__(5);
var extend = __webpack_require__(14);
var combine = {};
if(env.browser){
var dom = __webpack_require__(4);
var walkers = __webpack_require__(9);
var Group = __webpack_require__(10);
var doc = dom.doc;
combine = __webpack_require__(15);
}
var events = __webpack_require__(16);
var Watcher = __webpack_require__(17);
var parse = __webpack_require__(18);
var filter = __webpack_require__(19);
/**
* `Regular` is regularjs's NameSpace and BaseClass. Every Component is inherited from it
*
* @class Regular
* @module Regular
* @constructor
* @param {Object} options specification of the component
*/
var Regular = function(definition, options){
var prevRunning = env.isRunning;
env.isRunning = true;
var node, template;
definition = definition || {};
var usePrototyeString = typeof this.template === 'string' && !definition.template;
options = options || {};
definition.data = definition.data || {};
definition.computed = definition.computed || {};
if( this.data ) _.extend( definition.data, this.data );
if( this.computed ) _.extend( definition.computed, this.computed );
var listeners = this._eventListeners || [];
var normListener;
// hanle initialized event binding
if( definition.events){
normListener = _.normListener(definition.events);
if(normListener.length){
listeners = listeners.concat(normListener)
}
delete definition.events;
}
_.extend(this, definition, true);
if(this.$parent){
this.$parent._append(this);
}
this._children = [];
this.$refs = {};
template = this.template;
// template is a string (len < 16). we will find it container first
if((typeof template === 'string' && template.length < 16) && (node = dom.find(template))) {
template = node.innerHTML;
}
// if template is a xml
if(template && template.nodeType) template = template.innerHTML;
if(typeof template === 'string') {
template = new Parser(template).parse();
if(usePrototyeString) {
// avoid multiply compile
this.constructor.prototype.template = template;
}else{
delete this.template;
}
}
this.computed = handleComputed(this.computed);
this.$root = this.$root || this;
// if have events
if(listeners && listeners.length){
listeners.forEach(function( item ){
this.$on(item.type, item.listener)
}.bind(this))
}
this.$emit("$config");
this.config && this.config(this.data);
this.$emit("$afterConfig");
var body = this._body;
this._body = null;
if(body && body.ast && body.ast.length){
this.$body = _.getCompileFn(body.ast, body.ctx , {
outer: this,
namespace: options.namespace,
extra: options.extra,
record: true
})
}
// handle computed
if(template){
this.group = this.$compile(template, {namespace: options.namespace});
combine.node(this);
}
if(!this.$parent) this.$update();
this.$ready = true;
this.$emit("$init");
if( this.init ) this.init(this.data);
this.$emit("$afterInit");
// @TODO: remove, maybe , there is no need to update after init;
// if(this.$root === this) this.$update();
env.isRunning = prevRunning;
// children is not required;
if (this.devtools) {
this.devtools.emit("init", this)
}
}
// check if regular devtools hook exists
var devtools = window.__REGULAR_DEVTOOLS_GLOBAL_HOOK__;
if (devtools) {
Regular.prototype.devtools = devtools;
}
walkers && (walkers.Regular = Regular);
// description
// -------------------------
// 1. Regular and derived Class use same filter
_.extend(Regular, {
// private data stuff
_directives: { __regexp__:[] },
_plugins: {},
_protoInheritCache: [ 'directive', 'use'] ,
__after__: function(supr, o) {
var template;
this.__after__ = supr.__after__;
// use name make the component global.
if(o.name) Regular.component(o.name, this);
// this.prototype.template = dom.initTemplate(o)
if(template = o.template){
var node, name;
if( typeof template === 'string' && template.length < 16 && ( node = dom.find( template )) ){
template = node ;
}
if(template && template.nodeType){
if(name = dom.attr(template, 'name')) Regular.component(name, this);
template = template.innerHTML;
}
if(typeof template === 'string' ){
this.prototype.template = config.PRECOMPILE? new Parser(template).parse(): template;
}
}
if(o.computed) this.prototype.computed = handleComputed(o.computed);
// inherit directive and other config from supr
Regular._inheritConfig(this, supr);
},
/**
* Define a directive
*
* @method directive
* @return {Object} Copy of ...
*/
directive: function(name, cfg){
if(_.typeOf(name) === "object"){
for(var k in name){
if(name.hasOwnProperty(k)) this.directive(k, name[k]);
}
return this;
}
var type = _.typeOf(name);
var directives = this._directives, directive;
if(cfg == null){
if( type === "string" && (directive = directives[name]) ) return directive;
else{
var regexp = directives.__regexp__;
for(var i = 0, len = regexp.length; i < len ; i++){
directive = regexp[i];
var test = directive.regexp.test(name);
if(test) return directive;
}
}
return undefined;
}
if(typeof cfg === 'function') cfg = { link: cfg }
if(type === 'string') directives[name] = cfg;
else if(type === 'regexp'){
cfg.regexp = name;
directives.__regexp__.push(cfg)
}
return this
},
plugin: function(name, fn){
var plugins = this._plugins;
if(fn == null) return plugins[name];
plugins[name] = fn;
return this;
},
use: function(fn){
if(typeof fn === "string") fn = Regular.plugin(fn);
if(typeof fn !== "function") return this;
fn(this, Regular);
return this;
},
// config the Regularjs's global
config: function(name, value){
var needGenLexer = false;
if(typeof name === "object"){
for(var i in name){
// if you config
if( i ==="END" || i==='BEGIN' ) needGenLexer = true;
config[i] = name[i];
}
}
if(needGenLexer) Lexer.setup();
},
expression: parse.expression,
Parser: Parser,
Lexer: Lexer,
_addProtoInheritCache: function(name, transform){
if( Array.isArray( name ) ){
return name.forEach(Regular._addProtoInheritCache);
}
var cacheKey = "_" + name + "s"
Regular._protoInheritCache.push(name)
Regular[cacheKey] = {};
if(Regular[name]) return;
Regular[name] = function(key, cfg){
var cache = this[cacheKey];
if(typeof key === "object"){
for(var i in key){
if(key.hasOwnProperty(i)) this[name](i, key[i]);
}
return this;
}
if(cfg == null) return cache[key];
cache[key] = transform? transform(cfg) : cfg;
return this;
}
},
_inheritConfig: function(self, supr){
// prototype inherit some Regular property
// so every Component will have own container to serve directive, filter etc..
var defs = Regular._protoInheritCache;
var keys = _.slice(defs);
keys.forEach(function(key){
self[key] = supr[key];
var cacheKey = '_' + key + 's';
if(supr[cacheKey]) self[cacheKey] = _.createObject(supr[cacheKey]);
})
return self;
}
});
extend(Regular);
Regular._addProtoInheritCache("component")
Regular._addProtoInheritCache("filter", function(cfg){
return typeof cfg === "function"? {get: cfg}: cfg;
})
events.mixTo(Regular);
Watcher.mixTo(Regular);
Regular.implement({
init: function(){},
config: function(){},
destroy: function(){
// destroy event wont propgation;
this.$emit("$destroy");
this._watchers = null;
this.group && this.group.destroy(true);
this.group = null;
this.parentNode = null;
this._children = [];
var parent = this.$parent;
if(parent){
var index = parent._children.indexOf(this);
parent._children.splice(index,1);
}
this.$parent = null;
this.$root = null;
this._handles = null;
this.$refs = null;
if (this.devtools) {
this.devtools.emit("destroy", this)
}
},
/**
* compile a block ast ; return a group;
* @param {Array} parsed ast
* @param {[type]} record
* @return {[type]}
*/
$compile: function(ast, options){
options = options || {};
if(typeof ast === 'string'){
ast = new Parser(ast).parse()
}
var preExt = this.__ext__,
record = options.record,
records;
if(options.extra) this.__ext__ = options.extra;
if(record) this._record();
var group = this._walk(ast, options);
if(record){
records = this._release();
var self = this;
if(records.length){
// auto destroy all wather;
group.ondestroy = function(){ self.$unwatch(records); }
}
}
if(options.extra) this.__ext__ = preExt;
return group;
},
/**
* create two-way binding with another component;
* *warn*:
* 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,
* beacuse Regular dont know how to inverse set through the expression;
*
* if before $bind, two component's state is not sync, the component(passed param) will sync with the called component;
*
* *example: *
*
* ```javascript
* // in this example, we need to link two pager component
* var pager = new Pager({}) // pager compoennt
* var pager2 = new Pager({}) // another pager component
* pager.$bind(pager2, 'current'); // two way bind throw two component
* pager.$bind(pager2, 'total'); //
* // or just
* pager.$bind(pager2, {"current": "current", "total": "total"})
* ```
*
* @param {Regular} component the
* @param {String|Expression} expr1 required, self expr1 to operate binding
* @param {String|Expression} expr2 optional, other component's expr to bind with, if not passed, the expr2 will use the expr1;
* @return this;
*/
$bind: function(component, expr1, expr2){
var type = _.typeOf(expr1);
if( expr1.type === 'expression' || type === 'string' ){
this._bind(component, expr1, expr2)
}else if( type === "array" ){ // multiply same path binding through array
for(var i = 0, len = expr1.length; i < len; i++){
this._bind(component, expr1[i]);
}
}else if(type === "object"){
for(var i in expr1) if(expr1.hasOwnProperty(i)){
this._bind(component, i, expr1[i]);
}
}
// digest
component.$update();
return this;
},
/**
* unbind one component( see $bind also)
*
* unbind will unbind all relation between two component
*
* @param {Regular} component [descriptionegular
* @return {This} this
*/
$unbind: function(){
// todo
},
$inject: combine.inject,
$mute: function(isMute){
isMute = !!isMute;
var needupdate = isMute === false && this._mute;
this._mute = !!isMute;
if(needupdate) this.$update();
return this;
},
// private bind logic
_bind: function(component, expr1, expr2){
var self = this;
// basic binding
if(!component || !(component instanceof Regular)) throw "$bind() should pass Regular component as first argument";
if(!expr1) throw "$bind() should pass as least one expression to bind";
if(!expr2) expr2 = expr1;
expr1 = parse.expression( expr1 );
expr2 = parse.expression( expr2 );
// set is need to operate setting ;
if(expr2.set){
var wid1 = this.$watch( expr1, function(value){
component.$update(expr2, value)
});
component.$on('$destroy', function(){
self.$unwatch(wid1)
})
}
if(expr1.set){
var wid2 = component.$watch(expr2, function(value){
self.$update(expr1, value)
});
// when brother destroy, we unlink this watcher
this.$on('$destroy', component.$unwatch.bind(component,wid2))
}
// sync the component's state to called's state
expr2.set(component, expr1.get(this));
},
_walk: function(ast, arg1){
if( _.typeOf(ast) === 'array' ){
var res = [];
for(var i = 0, len = ast.length; i < len; i++){
res.push( this._walk(ast[i], arg1) );
}
return new Group(res);
}
if(typeof ast === 'string') return doc.createTextNode(ast)
return walkers[ast.type || "default"].call(this, ast, arg1);
},
_append: function(component){
this._children.push(component);
component.$parent = this;
},
_handleEvent: function(elem, type, value, attrs){
var Component = this.constructor,
fire = typeof value !== "function"? _.handleEvent.call( this, value, type ) : value,
handler = Component.event(type), destroy;
if ( handler ) {
destroy = handler.call(this, elem, fire, attrs);
} else {
dom.on(elem, type, fire);
}
return handler ? destroy : function() {
dom.off(elem, type, fire);
}
},
// 1. 用来处理exprBody -> Function
// 2. list里的循环
_touchExpr: function(expr){
var rawget, ext = this.__ext__, touched = {};
if(expr.type !== 'expression' || expr.touched) return expr;
rawget = expr.get || (expr.get = new Function(_.ctxName, _.extName , _.prefix+ "return (" + expr.body + ")"));
touched.get = !ext? rawget: function(context){
return rawget(context, ext)
}
if(expr.setbody && !expr.set){
var setbody = expr.setbody;
expr.set = function(ctx, value, ext){
expr.set = new Function(_.ctxName, _.setName , _.extName, _.prefix + setbody);
return expr.set(ctx, value, ext);
}
expr.setbody = null;
}
if(expr.set){
touched.set = !ext? expr.set : function(ctx, value){
return expr.set(ctx, value, ext);
}
}
_.extend(touched, {
type: 'expression',
touched: true,
once: expr.once || expr.constant
})
return touched
},
// find filter
_f_: function(name){
var Component = this.constructor;
var filter = Component.filter(name);
if(!filter) throw Error('filter ' + name + ' is undefined');
return filter;
},
// simple accessor get
_sg_:function(path, defaults, ext){
if(typeof ext !== 'undefined'){
// if(path === "demos") debugger
var computed = this.computed,
computedProperty = computed[path];
if(computedProperty){
if(computedProperty.type==='expression' && !computedProperty.get) this._touchExpr(computedProperty);
if(computedProperty.get) return computedProperty.get(this);
else _.log("the computed '" + path + "' don't define the get function, get data."+path + " altnately", "warn")
}
}
if(typeof defaults === "undefined" || typeof path == "undefined" ){
return undefined;
}
return (ext && typeof ext[path] !== 'undefined')? ext[path]: defaults[path];
},
// simple accessor set
_ss_:function(path, value, data , op, computed){
var computed = this.computed,
op = op || "=", prev,
computedProperty = computed? computed[path]:null;
if(op !== '='){
prev = computedProperty? computedProperty.get(this): data[path];
switch(op){
case "+=":
value = prev + value;
break;
case "-=":
value = prev - value;
break;
case "*=":
value = prev * value;
break;
case "/=":
value = prev / value;
break;
case "%=":
value = prev % value;
break;
}
}
if(computedProperty) {
if(computedProperty.set) return computedProperty.set(this, value);
else _.log("the computed '" + path + "' don't define the set function, assign data."+path + " altnately", "warn" )
}
data[path] = value;
return value;
}
});
Regular.prototype.inject = function(){
_.log("use $inject instead of inject", "error");
return this.$inject.apply(this, arguments);
}
// only one builtin filter
Regular.filter(filter);
module.exports = Regular;
var handleComputed = (function(){
// wrap the computed getter;
function wrapGet(get){
return function(context){
return get.call(context, context.data );
}
}
// wrap the computed setter;
function wrapSet(set){
return function(context, value){
set.call( context, value, context.data );
return value;
}
}
return function(computed){
if(!computed) return;
var parsedComputed = {}, handle, pair, type;
for(var i in computed){
handle = computed[i]
type = typeof handle;
if(handle.type === 'expression'){
parsedComputed[i] = handle;
continue;
}
if( type === "string" ){
parsedComputed[i] = parse.expression(handle)
}else{
pair = parsedComputed[i] = {type: 'expression'};
if(type === "function" ){
pair.get = wrapGet(handle);
}else{
if(handle.get) pair.get = wrapGet(handle.get);
if(handle.set) pair.set = wrapSet(handle.set);
}
}
}
return parsedComputed;
}
})();
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
// thanks for angular && mootools for some concise&cross-platform implemention
// =====================================
// The MIT License
// Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
// ---
// license: MIT-style license. http://mootools.net
var dom = module.exports;
var env = __webpack_require__(1);
var _ = __webpack_require__(5);
var consts = __webpack_require__(11);
var tNode = document.createElement('div')
var addEvent, removeEvent;
var noop = function(){}
var namespaces = consts.NAMESPACE;
dom.body = document.body;
dom.doc = document;
// camelCase
function camelCase(str){
return ("" + str).replace(/-\D/g, function(match){
return match.charAt(1).toUpperCase();
});
}
dom.tNode = tNode;
if(tNode.addEventListener){
addEvent = function(node, type, fn) {
node.addEventListener(type, fn, false);
}
removeEvent = function(node, type, fn) {
node.removeEventListener(type, fn, false)
}
}else{
addEvent = function(node, type, fn) {
node.attachEvent('on' + type, fn);
}
removeEvent = function(node, type, fn) {
node.detachEvent('on' + type, fn);
}
}
dom.msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
if (isNaN(dom.msie)) {
dom.msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
}
dom.find = function(sl){
if(document.querySelector) {
try{
return document.querySelector(sl);
}catch(e){
}
}
if(sl.indexOf('#')!==-1) return document.getElementById( sl.slice(1) );
}
dom.inject = function(node, refer, position){
position = position || 'bottom';
if(!node) return ;
if(Array.isArray(node)){
var tmp = node;
node = dom.fragment();
for(var i = 0,len = tmp.length; i < len ;i++){
node.appendChild(tmp[i])
}
}
var firstChild, next;
switch(position){
case 'bottom':
refer.appendChild( node );
break;
case 'top':
if( firstChild = refer.firstChild ){
refer.insertBefore( node, refer.firstChild );
}else{
refer.appendChild( node );
}
break;
case 'after':
if( next = refer.nextSibling ){
next.parentNode.insertBefore( node, next );
}else{
refer.parentNode.appendChild( node );
}
break;
case 'before':
refer.parentNode.insertBefore( node, refer );
}
}
dom.id = function(id){
return document.getElementById(id);
}
// createElement
dom.create = function(type, ns, attrs){
if(ns === 'svg'){
if(!env.svg) throw Error('the env need svg support')
ns = namespaces.svg;
}
return !ns? document.createElement(type): document.createElementNS(ns, type);
}
// documentFragment
dom.fragment = function(){
return document.createDocumentFragment();
}
var specialAttr = {
'class': function(node, value){
('className' in node && (!node.namespaceURI || node.namespaceURI === namespaces.html )) ?
node.className = (value || '') : node.setAttribute('class', value);
},
'for': function(node, value){
('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
},
'style': function(node, value){
(node.style) ? node.style.cssText = value : node.setAttribute('style', value);
},
'value': function(node, value){
node.value = (value != null) ? value : '';
}
}
// attribute Setter & Getter
dom.attr = function(node, name, value){
if (_.isBooleanAttr(name)) {
if (typeof value !== 'undefined') {
if (!!value) {
node[name] = true;
node.setAttribute(name, name);
// lt ie7 . the javascript checked setting is in valid
//http://bytes.com/topic/javascript/insights/799167-browser-quirk-dynamically-appended-checked-checkbox-does-not-appear-checked-ie
if(dom.msie && dom.msie <=7 && name === 'checked' ) node.defaultChecked = true
} else {
node[name] = false;
node.removeAttribute(name);
}
} else {
return (node[name] ||
(node.attributes.getNamedItem(name)|| noop).specified) ? name : undefined;
}
} else if (typeof (value) !== 'undefined') {
// if in specialAttr;
if(specialAttr[name]) specialAttr[name](node, value);
else if(value === null) node.removeAttribute(name)
else node.setAttribute(name, value);
} else if (node.getAttribute) {
// the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
// some elements (e.g. Document) don't have get attribute, so return undefined
var ret = node.getAttribute(name, 2);
// normalize non-existing attributes to undefined (as jQuery)
return ret === null ? undefined : ret;
}
}
dom.on = function(node, type, handler){
var types = type.split(' ');
handler.real = function(ev){
var $event = new Event(ev);
$event.origin = node;
handler.call(node, $event);
}
types.forEach(function(type){
type = fixEventName(node, type);
addEvent(node, type, handler.real);
});
return dom;
}
dom.off = function(node, type, handler){
var types = type.split(' ');
handler = handler.real || handler;
types.forEach(function(type){
type = fixEventName(node, type);
removeEvent(node, type, handler);
})
}
dom.text = (function (){
var map = {};
if (dom.msie && dom.msie < 9) {
map[1] = 'innerText';
map[3] = 'nodeValue';
} else {
map[1] = map[3] = 'textContent';
}
return function (node, value) {
var textProp = map[node.nodeType];
if (value == null) {
return textProp ? node[textProp] : '';
}
node[textProp] = value;
}
})();
dom.html = function( node, html ){
if(typeof html === "undefined"){
return node.innerHTML;
}else{
node.innerHTML = html;
}
}
dom.replace = function(node, replaced){
if(replaced.parentNode) replaced.parentNode.replaceChild(node, replaced);
}
dom.remove = function(node){
if(node.parentNode) node.parentNode.removeChild(node);
}
// css Settle & Getter from angular
// =================================
// it isnt computed style
dom.css = function(node, name, value){
if( _.typeOf(name) === "object" ){
for(var i in name){
if( name.hasOwnProperty(i) ){
dom.css( node, i, name[i] );
}
}
return;
}
if ( typeof value !== "undefined" ) {
name = camelCase(name);
if(name) node.style[name] = value;
} else {
var val;
if (dom.msie <= 8) {
// this is some IE specific weirdness that jQuery 1.6.4 does not sure why
val = node.currentStyle && node.currentStyle[name];
if (val === '') val = 'auto';
}
val = val || node.style[name];
if (dom.msie <= 8) {
val = val === '' ? undefined : val;
}
return val;
}
}
dom.addClass = function(node, className){
var current = node.className || "";
if ((" " + current + " ").indexOf(" " + className + " ") === -1) {
node.className = current? ( current + " " + className ) : className;
}
}
dom.delClass = function(node, className){
var current = node.className || "";
node.className = (" " + current + " ").replace(" " + className + " ", " ").trim();
}
dom.hasClass = function(node, className){
var current = node.className || "";
return (" " + current + " ").indexOf(" " + className + " ") !== -1;
}
// simple Event wrap
//http://stackoverflow.com/questions/11068196/ie8-ie7-onchange-event-is-emited-only-after-repeated-selection
function fixEventName(elem, name){
return (name === 'change' && dom.msie < 9 &&
(elem && elem.tagName && elem.tagName.toLowerCase()==='input' &&
(elem.type === 'checkbox' || elem.type === 'radio')
)
)? 'click': name;
}
var rMouseEvent = /^(?:click|dblclick|contextmenu|DOMMouseScroll|mouse(?:\w+))$/
var doc = document;
doc = (!doc.compatMode || doc.compatMode === 'CSS1Compat') ? doc.documentElement : doc.body;
function Event(ev){
ev = ev || window.event;
if(ev._fixed) return ev;
this.event = ev;
this.target = ev.target || ev.srcElement;
var type = this.type = ev.type;
var button = this.button = ev.button;
// if is mouse event patch pageX
if(rMouseEvent.test(type)){ //fix pageX
this.pageX = (ev.pageX != null) ? ev.pageX : ev.clientX + doc.scrollLeft;
this.pageY = (ev.pageX != null) ? ev.pageY : ev.clientY + doc.scrollTop;
if (type === 'mouseover' || type === 'mouseout'){// fix relatedTarget
var related = ev.relatedTarget || ev[(type === 'mouseover' ? 'from' : 'to') + 'Element'];
while (related && related.nodeType === 3) related = related.parentNode;
this.relatedTarget = related;
}
}
// if is mousescroll
if (type === 'DOMMouseScroll' || type === 'mousewheel'){
// ff ev.detail: 3 other ev.wheelDelta: -120
this.wheelDelta = (ev.wheelDelta) ? ev.wheelDelta / 120 : -(ev.detail || 0) / 3;
}
// fix which
this.which = ev.which || ev.keyCode;
if( !this.which && button !== undefined){
// http://api.jquery.com/event.which/ use which
this.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
}
this._fixed = true;
}
_.extend(Event.prototype, {
stop: function(){
this.preventDefault().stopPropagation();
},
preventDefault: function(){
if (this.event.preventDefault) this.event.preventDefault();
else this.event.returnValue = false;
return this;
},
stopPropagation: function(){
if (this.event.stopPropagation) this.event.stopPropagation();
else this.event.cancelBubble = true;
return this;
},
stopImmediatePropagation: function(){
if(this.event.stopImmediatePropagation) this.event.stopImmediatePropagation();
}
})
dom.nextFrame = (function(){
var request = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame||
function(callback){
return setTimeout(callback, 16)
}
var cancel = window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
function(tid){
clearTimeout(tid)
}
return function(callback){
var id = request(callback);
return function(){ cancel(id); }
}
})();
// 3ks for angular's raf service
var k
dom.nextReflow = dom.msie? function(callback){
return dom.nextFrame(function(){
k = document.body.offsetWidth;
callback();
})
}: dom.nextFrame;
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {__webpack_require__(20)();
var _ = module.exports;
var entities = __webpack_require__(21);
var slice = [].slice;
var o2str = ({}).toString;
var win = typeof window !=='undefined'? window: global;
var MAX_PRIORITY = 9999;
_.noop = function(){};
_.uid = (function(){
var _uid=0;
return function(){
return _uid++;
}
})();
_.extend = function( o1, o2, override ){
for(var i in o2) if (o2.hasOwnProperty(i)){
if( o1[i] === undefined || override === true ){
o1[i] = o2[i]
}
}
return o1;
}
_.keys = function(obj){
if(Object.keys) return Object.keys(obj);
var res = [];
for(var i in obj) if(obj.hasOwnProperty(i)){
res.push(i);
}
return res;
}
_.varName = 'd';
_.setName = 'p_';
_.ctxName = 'c';
_.extName = 'e';
_.rWord = /^[\$\w]+$/;
_.rSimpleAccessor = /^[\$\w]+(\.[\$\w]+)*$/;
_.nextTick = typeof setImmediate === 'function'?
setImmediate.bind(win) :
function(callback) {
setTimeout(callback, 0)
}
_.prefix = "var " + _.varName + "=" + _.ctxName + ".data;" + _.extName + "=" + _.extName + "||'';";
_.slice = function(obj, start, end){
var res = [];
for(var i = start || 0, len = end || obj.length; i < len; i++){
var item = obj[i];
res.push(item)
}
return res;
}
_.typeOf = function (o) {
return o == null ? String(o) :o2str.call(o).slice(8, -1).toLowerCase();
}
_.makePredicate = function makePredicate(words, prefix) {
if (typeof words === "string") {
words = words.split(" ");
}
var f = "",
cats = [];
out: for (var i = 0; i < words.length; ++i) {
for (var j = 0; j < cats.length; ++j){
if (cats[j][0].length === words[i].length) {
cats[j].push(words[i]);
continue out;
}
}
cats.push([words[i]]);
}
function compareTo(arr) {
if (arr.length === 1) return f += "return str === '" + arr[0] + "';";
f += "switch(str){";
for (var i = 0; i < arr.length; ++i){
f += "case '" + arr[i] + "':";
}
f += "return true}return false;";
}
// When there are more than three length categories, an outer
// switch first dispatches on the lengths, to save on comparisons.
if (cats.length > 3) {
cats.sort(function(a, b) {
return b.length - a.length;
});
f += "switch(str.length){";
for (var i = 0; i < cats.length; ++i) {
var cat = cats[i];
f += "case " + cat[0].length + ":";
compareTo(cat);
}
f += "}";
// Otherwise, simply generate a flat `switch` statement.
} else {
compareTo(words);
}
return new Function("str", f);
}
_.trackErrorPos = (function (){
// linebreak
var lb = /\r\n|[\n\r\u2028\u2029]/g;
var minRange = 20, maxRange = 20;
function findLine(lines, pos){
var tmpLen = 0;
for(var i = 0,len = lines.length; i < len; i++){
var lineLen = (lines[i] || "").length;
if(tmpLen + lineLen > pos) {
return {num: i, line: lines[i], start: pos - i - tmpLen , prev:lines[i-1], next: lines[i+1] };
}
// 1 is for the linebreak
tmpLen = tmpLen + lineLen ;
}
}
function formatLine(str, start, num, target){
var len = str.length;
var min = start - minRange;
if(min < 0) min = 0;
var max = start + maxRange;
if(max > len) max = len;
var remain = str.slice(min, max);
var prefix = "[" +(num+1) + "] " + (min > 0? ".." : "")
var postfix = max < len ? "..": "";
var res = prefix + remain + postfix;
if(target) res += "\n" + new Array(start-min + prefix.length + 1).join(" ") + "^^^";
return res;
}
return function(input, pos){
if(pos > input.length-1) pos = input.length-1;
lb.lastIndex = 0;
var lines = input.split(lb);
var line = findLine(lines,pos);
var start = line.start, num = line.num;
return (line.prev? formatLine(line.prev, start, num-1 ) + '\n': '' ) +
formatLine(line.line, start, num, true) + '\n' +
(line.next? formatLine(line.next, start, num+1 ) + '\n': '' );
}
})();
var ignoredRef = /\((\?\!|\?\:|\?\=)/g;
_.findSubCapture = function (regStr) {
var left = 0,
right = 0,
len = regStr.length,
ignored = regStr.match(ignoredRef); // ignored uncapture
if(ignored) ignored = ignored.length
else ignored = 0;
for (; len--;) {
var letter = regStr.charAt(len);
if (len === 0 || regStr.charAt(len - 1) !== "\\" ) {
if (letter === "(") left++;
if (letter === ")") right++;
}
}
if (left !== right) throw "RegExp: "+ regStr + "'s bracket is not marched";
else return left - ignored;
};
_.escapeRegExp = function( str){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
return '\\' + match;
});
};
var rEntity = new RegExp("&(?:(#x[0-9a-fA-F]+)|(#[0-9]+)|(" + _.keys(entities).join('|') + '));', 'gi');
_.convertEntity = function(chr){
return ("" + chr).replace(rEntity, function(all, hex, dec, capture){
var charCode;
if( dec ) charCode = parseInt( dec.slice(1), 10 );
else if( hex ) charCode = parseInt( hex.slice(2), 16 );
else charCode = entities[capture]
return String.fromCharCode( charCode )
});
}
// simple get accessor
_.createObject = function(o, props){
function Foo() {}
Foo.prototype = o;
var res = new Foo;
if(props) _.extend(res, props);
return res;
}
_.createProto = function(fn, o){
function Foo() { this.constructor = fn;}
Foo.prototype = o;
return (fn.prototype = new Foo());
}
_.removeOne = function(list , filter){
var len = list.length;
for(;len--;){
if(filter(list[len])) {
list.splice(len, 1)
return;
}
}
}
/**
clone
*/
_.clone = function clone(obj){
var type = _.typeOf(obj);
if(type === 'array'){
var cloned = [];
for(var i=0,len = obj.length; i< len;i++){
cloned[i] = obj[i]
}
return cloned;
}
if(type === 'object'){
var cloned = {};
for(var i in obj) if(obj.hasOwnProperty(i)){
cloned[i] = obj[i];
}
return cloned;
}
return obj;
}
_.equals = function(now, old){
var type = typeof now;
if(type === 'number' && typeof old === 'number'&& isNaN(now) && isNaN(old)) return true
return now === old;
}
var dash = /-([a-z])/g;
_.camelCase = function(str){
return str.replace(dash, function(all, capture){
return capture.toUpperCase();
})
}
_.throttle = function throttle(func, wait){
var wait = wait || 100;
var context, args, result;
var timeout = null;
var previous = 0;
var later = function() {
previous = +new Date;
timeout = null;
result = func.apply(context, args);
context = args = null;
};
return function() {
var now = + new Date;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
context = args = null;
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
return result;
};
};
// hogan escape
// ==============
_.escape = (function(){
var rAmp = /&/g,
rLt = /</g,
rGt = />/g,
rApos = /\'/g,
rQuot = /\"/g,
hChars = /[&<>\"\']/;
return function(str) {
return hChars.test(str) ?
str
.replace(rAmp, '&')
.replace(rLt, '<')
.replace(rGt, '>')
.replace(rApos, ''')
.replace(rQuot, '"') :
str;
}
})();
_.cache = function(max){
max = max || 1000;
var keys = [],
cache = {};
return {
set: function(key, value) {
if (keys.length > this.max) {
cache[keys.shift()] = undefined;
}
//
if(cache[key] === undefined){
keys.push(key);
}
cache[key] = value;
return value;
},
get: function(key) {
if (key === undefined) return cache;
return cache[key];
},
max: max,
len:function(){
return keys.length;
}
};
}
// // setup the raw Expression
// _.touchExpression = function(expr){
// if(expr.type === 'expression'){
// }
// return expr;
// }
// handle the same logic on component's `on-*` and element's `on-*`
// return the fire object
_.handleEvent = function(value, type ){
var self = this, evaluate;
if(value.type === 'expression'){ // if is expression, go evaluated way
evaluate = value.get;
}
if(evaluate){
return function fire(obj){
self.$update(function(){
var data = this.data;
data.$event = obj;
var res = evaluate(self);
if(res === false && obj && obj.preventDefault) obj.preventDefault();
data.$event = undefined;
})
}
}else{
return function fire(){
var args = slice.call(arguments)
args.unshift(value);
self.$update(function(){
self.$emit.apply(self, args);
})
}
}
}
// only call once
_.once = function(fn){
var time = 0;
return function(){
if( time++ === 0) fn.apply(this, arguments);
}
}
_.fixObjStr = function(str){
if(str.trim().indexOf('{') !== 0){
return '{' + str + '}';
}
return str;
}
_.map= function(array, callback){
var res = [];
for (var i = 0, len = array.length; i < len; i++) {
res.push(callback(array[i], i));
}
return res;
}
function log(msg, type){
if(typeof console !== "undefined") console[type || "log"](msg);
}
_.log = log;
_.normListener = function( events ){
var eventListeners = [];
var pType = _.typeOf( events );
if( pType === 'array' ){
return events;
}else if ( pType === 'object' ){
for( var i in events ) if ( events.hasOwnProperty(i) ){
eventListeners.push({
type: i,
listener: events[i]
})
}
}
return eventListeners;
}
//http://www.w3.org/html/wg/drafts/html/master/single-page.html#void-elements
_.isVoidTag = _.makePredicate("area base br col embed hr img input keygen link menuitem meta param source track wbr r-content");
_.isBooleanAttr = _.makePredicate('selected checked disabled readonly required open autofocus controls autoplay compact loop defer multiple');
_.isExpr = function(expr){
return expr && expr.type === 'expression';
}
// @TODO: make it more strict
_.isGroup = function(group){
return group.inject || group.$inject;
}
_.getCompileFn = function(source, ctx, options){
return ctx.$compile.bind(ctx,source, options)
}
// remove directive param from AST
_.fixTagAST = function( tagAST, Component ){
if( tagAST.touched ) return;
var attrs = tagAST.attrs;
if( !attrs ) return;
// Maybe multiple directive need same param,
// We place all param in totalParamMap
var len = attrs.length;
if(!len) return;
var directives=[], otherAttrMap = {};
for(;len--;){
var attr = attrs[ len ];
// @IE fix IE9- input type can't assign after value
if(attr.name === 'type') attr.priority = MAX_PRIORITY+1;
var directive = Component.directive( attr.name );
if( directive ) {
attr.priority = directive.priority || 1;
attr.directive = true;
directives.push(attr);
}else if(attr.type === 'attribute'){
otherAttrMap[attr.name] = attr.value;
}
}
directives.forEach( function( attr ){
var directive = Component.directive(attr.name);
var param = directive.param;
if(param && param.length){
attr.param = {};
param.forEach(function( name ){
if( name in otherAttrMap ){
attr.param[name] = otherAttrMap[name] === undefined? true: otherAttrMap[name]
_.removeOne(attrs, function(attr){
return attr.name === name
})
}
})
}
});
attrs.sort(function(a1, a2){
var p1 = a1.priority;
var p2 = a2.priority;
if( p1 == null ) p1 = MAX_PRIORITY;
if( p2 == null ) p2 = MAX_PRIORITY;
return p2 - p1;
})
tagAST.touched = true;
}
_.findItem = function(list, filter){
if(!list || !list.length) return;
var len = list.length;
while(len--){
if(filter(list[len])) return list[len]
}
}
_.getParamObj = function(component, param){
var paramObj = {};
if(param) {
for(var i in param) if(param.hasOwnProperty(i)){
var value = param[i];
paramObj[i] = value && value.type==='expression'? component.$get(value): value;
}
}
return paramObj;
}
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
// Regular
var _ = __webpack_require__(5);
var dom = __webpack_require__(4);
var animate = __webpack_require__(22);
var Regular = __webpack_require__(3);
var consts = __webpack_require__(11);
var namespaces = consts.NAMESPACE;
__webpack_require__(23);
__webpack_require__(24);
module.exports = {
// **warn**: class inteplation will override this directive
'r-class': function(elem, value){
if(typeof value=== 'string'){
value = _.fixObjStr(value)
}
var isNotHtml = elem.namespaceURI && elem.namespaceURI !== namespaces.html ;
this.$watch(value, function(nvalue){
var className = isNotHtml? elem.getAttribute('class'): elem.className;
className = ' '+ (className||'').replace(/\s+/g, ' ') +' ';
for(var i in nvalue) if(nvalue.hasOwnProperty(i)){
className = className.replace(' ' + i + ' ',' ');
if(nvalue[i] === true){
className += i+' ';
}
}
className = className.trim();
if(isNotHtml){
dom.attr(elem, 'class', className)
}else{
elem.className = className
}
},true);
},
// **warn**: style inteplation will override this directive
'r-style': function(elem, value){
if(typeof value=== 'string'){
value = _.fixObjStr(value)
}
this.$watch(value, function(nvalue){
for(var i in nvalue) if(nvalue.hasOwnProperty(i)){
dom.css(elem, i, nvalue[i]);
}
},true);
},
// when expression is evaluate to true, the elem will add display:none
// Example: <div r-hide={{items.length > 0}}></div>
'r-hide': function(elem, value){
var preBool = null, compelete;
if( _.isExpr(value) || typeof value === "string"){
this.$watch(value, function(nvalue){
var bool = !!nvalue;
if(bool === preBool) return;
preBool = bool;
if(bool){
if(elem.onleave){
compelete = elem.onleave(function(){
elem.style.display = "none"
compelete = null;
})
}else{
elem.style.display = "none"
}
}else{
if(compelete) compelete();
elem.style.display = "";
if(elem.onenter){
elem.onenter();
}
}
});
}else if(!!value){
elem.style.display = "none";
}
},
'r-html': function(elem, value){
this.$watch(value, function(nvalue){
nvalue = nvalue || "";
dom.html(elem, nvalue)
}, {force: true});
},
'ref': {
accept: consts.COMPONENT_