ecui
Version:
Enterprise Classic User Interface.
442 lines (394 loc) • 14.8 kB
JavaScript
/*
Decorate - 装饰器插件。
*/
//{if 0}//
(function () {
var core = ecui,
dom = core.dom,
ext = core.ext,
string = core.string,
ui = core.ui,
util = core.util,
undefined,
DOCUMENT = document,
MATH = Math,
REGEXP = RegExp,
FLOOR = MATH.floor,
USER_AGENT = navigator.userAgent,
ieVersion = /msie (\d+\.\d)/i.test(USER_AGENT) ? DOCUMENT.documentMode || (REGEXP.$1 - 0) : undefined,
addClass = dom.addClass,
createDom = dom.create,
getStyle = dom.getStyle,
insertBefore = dom.insertBefore,
insertHTML = dom.insertHTML,
removeClass = dom.removeClass,
removeDom = dom.remove,
toCamelCase = string.toCamelCase,
inherits = util.inherits,
$bind = core.$bind,
isContentBox = core.isContentBox,
UI_CONTROL = ui.Control,
UI_CONTROL_CLASS = UI_CONTROL.prototype;
//{/if}//
//{if $phase == "define"}//
/**
* 装饰器插件加载。
* @public
*
* @param {ecui.ui.Control} control 需要应用插件的控件
* @param {string} value 插件的参数
*/
var EXT_DECORATE = ext.decorate = function (control, value) {
value.replace(/([A-Za-z0-9\-]+)\s*\(\s*([^)]+)\)/g, function ($0, $1, $2) {
// 获取装饰器函数
$1 = EXT_DECORATE[toCamelCase($1.charAt(0).toUpperCase() + $1.slice(1))];
// 获取需要调用的装饰器列表
$2 = $2.split(/\s+/);
// 以下使用 el 计数
for (var i = 0; $0 = $2[i++]; ) {
new $1(control, $0);
}
});
};
/**
* 初始化装饰器,将其附着在控件外围。
* @public
*
* @param {ecui.ui.Control|ecui.ext.decorate.Decorator} control 需要装饰的控件
* @param {string} primary 装饰器的基本样式
* @param {Array} list 需要生成的区块样式名称集合
*/
var DECORATOR = EXT_DECORATE.Decorator = function (control, primary, list) {
//__transform__id_i
var id = control.getUID(),
o = (this._oInner = DECORATOR[id] || control).getOuter();
insertBefore(this._eMain = createDom(this._sPrimary = primary), o).appendChild(o);
$bind(this._eMain, control);
control.clearCache();
DECORATOR[id] = this;
if (!DECORATOR_OLD_METHODS[id]) {
// 给控件的方法设置代理访问
id = DECORATOR_OLD_METHODS[id] = {};
for (o in DECORATOR_PROXY) {
id[o] = control[o];
control[o] = DECORATOR_PROXY[o];
}
}
if (list) {
for (id = 0; o = list[id]; ) {
list[id++] =
'<div class="' + primary + '-' + o +
'" style="position:absolute;top:0px;left:0px"></div>';
}
insertHTML(this._eMain, 'BEFOREEND', list.join(''));
}
},
DECORATOR_CLASS = DECORATOR.prototype,
DECORATOR_PROXY = {},
DECORATOR_OLD_METHODS = {};
//{else}//
/**
* 清除所有的装饰器效果,同时清除所有的代理函数。
* @public
*
* @param {ecui.ui.Control} control ECUI 控件
*/
DECORATOR.clear = function (control) {
var id = control.getUID(),
o;
// 清除所有的代理函数
for (o in DECORATOR_PROXY) {
delete control[o];
// 方法不在原型链上需要额外恢复
if (control[o] != DECORATOR_OLD_METHODS[id][o]) {
control[o] = DECORATOR_OLD_METHODS[id][o];
}
}
o = DECORATOR[id];
insertBefore(control.getOuter(), o._eMain);
removeDom(o._eMain);
for (; o != control; o = o._oInner) {
o.$dispose();
}
delete DECORATOR[id];
delete DECORATOR_OLD_METHODS[id];
};
/**
* 缓存装饰器的属性。
* @protected
*
* @param {CssStyle} style 主元素的 Css 样式对象
* @param {boolean} cacheSize 是否需要缓存控件的大小,如果控件是另一个控件的部件时,不缓存大小能加快渲染速度,默认缓存
*/
DECORATOR_CLASS.$cache = function (style, cacheSize) {
this._oInner.$cache(style, cacheSize, true);
UI_CONTROL_CLASS.$cache.call(this, getStyle(this._eMain), false);
this._oInner.$$position = 'relative';
this.$$position = style.position == 'absolute' ? 'absolute' : 'relative';
this.$$layout =
';top:' + style.top + ';left:' + style.left + ';display:' + style.display +
(ieVersion ? ';zoom:' + style.zoom : '');
};
/**
* 销毁装饰器的默认处理。
* @protected
*/
DECORATOR_CLASS.$dispose = function () {
this._eMain = null;
};
/**
* 装饰器大小变化事件的默认处理。
* @protected
*/
DECORATOR_CLASS.$resize = function () {
//__gzip_original__style
var style = this._eMain.style;
style.width = '';
if (!ieVersion) {
style.height = '';
}
this._oInner.$resize(true);
};
/**
* 设置装饰器的大小。
* @protected
*
* @param {number} width 宽度,如果不需要设置则将参数设置为等价于逻辑非的值
* @param {number} height 高度,如果不需要设置则省略此参数
*/
DECORATOR_CLASS.$setSize = function (width, height) {
//__gzip_original__style
//__gzip_original__inner
var style = this._eMain.style,
inner = this._oInner,
invalidWidth = UI_CONTROL_CLASS.$getBasicWidth.call(this),
invalidHeight = UI_CONTROL_CLASS.$getBasicHeight.call(this),
fixedSize = isContentBox();
inner.$setSize(width && width - invalidWidth, height && height - invalidHeight, true);
style.width = inner.getWidth(true) + (fixedSize ? 0 : invalidWidth) + 'px';
style.height = inner.getHeight(true) + (fixedSize ? 0 : invalidHeight) + 'px';
};
/**
* 为装饰器添加/移除一个扩展样式。
* @public
*
* @param {string} className 扩展样式名,以+号开头表示添加扩展样式,以-号开头表示移除扩展样式
*/
DECORATOR_CLASS.alterClass = function (className) {
var flag = className.charAt(0) == '+';
this._oInner.alterClass(className, true);
if (flag) {
className = '-' + className.slice(1);
}
(flag ? addClass : removeClass)(this._eMain, this._sPrimary + className);
};
/**
* 获取装饰器的当前样式。
* @public
*
* @return {string} 控件的当前样式
*/
DECORATOR_CLASS.getClass = function () {
return this._sPrimary;
};
/**
* 获取装饰器区域的高度。
* @public
*
* @return {number} 装饰器的高度
*/
DECORATOR_CLASS.getHeight = function () {
return this._oInner.getHeight(true) + UI_CONTROL_CLASS.$getBasicHeight.call(this);
};
/**
* 获取装饰器的最小高度。
* @public
*
* @return {number} 装饰器的最小高度
*/
DECORATOR_CLASS.getMinimumHeight = function () {
return this._oInner.getMinimumHeight(true) + UI_CONTROL_CLASS.$getBasicHeight.call(this);
};
/**
* 获取装饰器的最小宽度。
* @public
*
* @return {number} 装饰器的最小宽度
*/
DECORATOR_CLASS.getMinimumWidth = function () {
return this._oInner.getMinimumWidth(true) + UI_CONTROL_CLASS.$getBasicWidth.call(this);
};
/**
* 获取装饰器的外层元素。
* @public
*
* @return {HTMLElement} Element 对象
*/
DECORATOR_CLASS.getOuter = function () {
return this._eMain;
};
/**
* 获取装饰器区域的宽度。
* @public
*
* @return {number} 装饰器的宽度
*/
DECORATOR_CLASS.getWidth = function () {
return this._oInner.getWidth(true) + UI_CONTROL_CLASS.$getBasicWidth.call(this);
};
/**
* 装饰器初始化。
* @public
*/
DECORATOR_CLASS.init = function () {
this._eMain.style.cssText = 'position:' + this.$$position + this.$$layout;
this._oInner.getOuter(true).style.cssText += ';position:relative;top:auto;left:auto;display:block';
this._oInner.init(true);
};
/**
* 销毁控件的默认处理。
* 控件销毁时需要先销毁装饰器。
* @protected
*/
DECORATOR_PROXY.$dispose = function () {
DECORATOR.clear(this);
this.$dispose();
};
(function () {
function build(name, index) {
DECORATOR_PROXY[name] = function () {
var id = this.getUID(),
o = DECORATOR[id],
args = arguments;
return args[index] ? DECORATOR_OLD_METHODS[id][name].apply(this, args) : o[name].apply(o, args);
};
}
// 这里批量生成函数代理
for (
var i = 0, names = [
['$cache', 2], ['$resize', 0], ['$setSize', 2],
['alterClass', 1], ['getOuter', 0],
['getMinimumWidth', 0], ['getMinimumHeight', 0],
['getWidth', 0], ['getHeight', 0], ['init', 0]
];
i < 10;
) {
// 如果是代理进入的,会多出来一个参数作为标志位
build(names[i][0], names[i++][1]);
}
})();
//{/if}//
/*
LRDecorator - 左右扩展装饰器,将区域分为"左-控件-右"三部分,使用paddingLeft与paddingRight作为左右区域的宽度
*/
//{if $phase == "define"}//
/**
* 初始化左右扩展装饰器,将其附着在控件外围。
* @public
*
* @param {Control} control 需要装饰的控件
* @param {string} primary 装饰器的基本样式
*/
var LR_DECORATOR = EXT_DECORATE.LRDecorator = function (control, primary) {
DECORATOR.call(this, control, primary, ['left', 'right']);
};
//{else}//
/**
* 设置装饰器区域的大小
* @public
*
* @param {number} width 装饰器区域的宽度
* @param {number} height 装饰器区域的高度
*/
inherits(LR_DECORATOR, DECORATOR).$setSize = function (width, height) {
DECORATOR_CLASS.$setSize.call(this, width, height);
var o = this._eMain.lastChild,
text = ';top:' + this.$$paddingTop + 'px;height:' + this._oInner.getHeight(true) + 'px;width:';
o.style.cssText +=
text + this.$$paddingRight + 'px;left:' + (this.$$paddingLeft + this._oInner.getWidth(true)) + 'px';
o.previousSibling.style.cssText += text + this.$$paddingLeft + 'px';
};
//{/if}//
/*
TBDecorator - 上下扩展装饰器,将区域分为"上-控件-下"三部分,使用paddingTop与paddingBottom作为上下区域的高度
*/
//{if $phase == "define"}//
/**
* 初始化上下扩展装饰器,将其附着在控件外围。
* @public
*
* @param {Control} control 需要装饰的控件
* @param {string} primary 装饰器的基本样式
*/
var TB_DECORATOR = EXT_DECORATE.TBDecorator = function (control, primary) {
DECORATOR.call(this, control, primary, ['top', 'bottom']);
};
//{else}//
/**
* 设置装饰器区域的大小
* @public
*
* @param {number} width 装饰器区域的宽度
* @param {number} height 装饰器区域的高度
*/
inherits(TB_DECORATOR, DECORATOR).$setSize = function (width, height) {
DECORATOR_CLASS.$setSize.call(this, width, height);
var o = this._eMain.lastChild,
text = ';left:' + this.$$paddingLeft + 'px;width:' + this._oInner.getWidth(true) + 'px;height:';
o.style.cssText +=
text + this.$$paddingBottom + 'px;top:' + (this.$$paddingTop + this._oInner.getHeight(true)) + 'px';
o.previousSibling.style.cssText += text + this.$$paddingTop + 'px';
};
//{/if}//
/*
MagicDecorator - 九宫格扩展装饰器,将区域分为"左上-上-右上-左-控件-右-左下-下-右下"九部分,使用padding定义宽度与高度
*/
//{if $phase == "define"}//
/**
* 初始化九宫格扩展装饰器,将其附着在控件外围。
* @public
*
* @param {Control} control 需要装饰的控件
* @param {string} primary 装饰器的基本样式
*/
var MAGIC_DECORATOR = EXT_DECORATE.MagicDecorator = function (control, primary) {
DECORATOR.call(
this,
control,
primary,
['widget0', 'widget1', 'widget2', 'widget3', 'widget5', 'widget6', 'widget7', 'widget8']
);
};
//{else}//
/**
* 设置装饰器区域的大小
* @public
*
* @param {number} width 装饰器区域的宽度
* @param {number} height 装饰器区域的高度
*/
inherits(MAGIC_DECORATOR, DECORATOR).$setSize = function (width, height) {
DECORATOR_CLASS.$setSize.call(this, width, height);
var o = this._eMain.lastChild,
i = 9,
paddingTop = this.$$paddingTop,
paddingLeft = this.$$paddingLeft,
widthList = this._oInner.getWidth(true),
heightList = this._oInner.getHeight(true),
topList = [0, paddingTop, paddingTop + heightList],
leftList = [0, paddingLeft, paddingLeft + widthList];
widthList = [paddingLeft, widthList, this.$$paddingRight];
heightList = [paddingTop, heightList, this.$$paddingBottom];
for (; i--; ) {
if (i != 4) {
o.style.cssText +=
';top:' + topList[FLOOR(i / 3)] + 'px;left:' + leftList[i % 3] + 'px;width:' + widthList[i % 3] +
'px;height:' + heightList[FLOOR(i / 3)] + 'px';
o = o.previousSibling;
}
}
};
//{/if}//
//{if 0}//
})();
//{/if}//