/**
* @namespace Rsd
* @copyright redmicro all Copyright (c)
* @author Created by seeker910 on 14-3-18.
*/
/**
*
* @constructor Redjs
* @param config
* */
function Redjs(config) {
//console.debug(Date.now(),'redjs begin');
Rsd.apply(this, config || {});
/**
* redjs 框架正在加载
*/
this.isLoading = function isLoading()
{
//没有开始时间时间,表示未加载
if(this.__loadStartTime==undefined || this.__loadStartTime==undefined || !this.__loadStartTime)
{
return false;
}
//没有加载结束时间,表示加载中
return this.__loadEndTime==undefined || this.__loadEndTime == null || !this.__loadEndTime
};
/**
* @public
* @description 验证浏览是否兼容redjs框架
* @function
* @memberof Redjs
*/
this.validateBrowser = function validateBrowser() {
return typeof Element !== "undefined";
};
/**
* @public
* @description 兼容处理,定义EventListener对象
* @function
* @memberof Redjs
* */
this.defineEventListener = function defineEventListener() {
//"use strict";
if (this.validateBrowser() == false) {
return
}
(function () {
var _add = 'addEventListener';
if (Element.prototype.hasOwnProperty(_add)) {
return;
}
Element.prototype[_add] == function (name, fn, useCapture) {
if (this.addEventListener) {
this.addEventListener(name, fn, useCapture);
} else if (this.attachEvent) {
this.attachEvent('on' + name, fn)
}
else {
this['on' + name] = fn;
}
};
})();
(function () {
var _remove = 'removeEventListener';
if (Element.prototype.hasOwnProperty(_remove)) {
return;
}
Element.prototype[_remove] == function (name, fn, useCapture) {
if (this.removeEventListener) {
this.removeEventListener(name, fn, useCapture);
} else if (this.detachEvent) {
this.detachEvent('on' + name, fn)
}
else {
delete this['on' + name];
}
};
})();
};
/**
* @public
* @description 兼容处理,定义ClassList对象
* @function
* @memberof Redjs
* */
"use strict";
this.defineClassList = function defineClassList(type) {
//"use strict";
if (this.validateBrowser() == false) {
return
}
var classListPropertyName = "classList";
if (type.prototype.hasOwnProperty(classListPropertyName)) {
return;
}
var trim = /^\s+|\s+$/g;
var setClasses = function (elem, classes) {
elem.className = classes.join(" ");
};
var checkAndGetIndex = function (classes, token) {
if (token === "") {
throw "SYNTAX_ERR";
}
if (/\s/.test(token)) {
throw "INVALID_CHARACTER_ERR";
}
return classes.indexOf(token);
};
var classListGetter = function () {
var elem = this;
var classes;
if (typeof(elem.className) == '[object String]') {
classes = elem.className.replace(trim, "").split(/\s+/);
} else {
classes = [];
}
return {
length: classes.length,
item: function (i) {
return classes[i] || null;
},
contains: function (token) {
return checkAndGetIndex(classes, token) !== -1;
},
add: function (token) {
if (checkAndGetIndex(classes, token) === -1) {
classes.push(token);
this.length = classes.length;
setClasses(elem, classes);
}
},
remove: function (token) {
var index = checkAndGetIndex(classes, token);
if (index !== -1) {
classes.splice(index, 1);
this.length = classes.length;
setClasses(elem, classes);
}
},
toggle: function (token) {
if (checkAndGetIndex(classes, token) === -1) {
this.add(token);
} else {
this.remove(token);
}
},
toString: function () {
return elem.className;
}
};
};
if (Object.defineProperty) {
Object.defineProperty(type.prototype, classListPropertyName, {get: classListGetter, enumerable: true});
} else if (Object.prototype.__defineGetter__) {
type.prototype.__defineGetter__(classListPropertyName, classListGetter);
}
};
/**
*
*窗体自适应
* */
this.defineRem = function defineRem(maxWidth) {
var doc = document;
var _maxWidth = maxWidth || 640;
var docEl = doc.documentElement;
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if(this.isMobile())
{
this.___rem = 14;
if (clientWidth < _maxWidth) {
this.___rem = 14 * (clientWidth / _maxWidth);
}
}else
{
this.___rem = 12;
}
docEl.style.fontSize = this.___rem + 'px';
};
/*
* */
this.getRem = function getRem() {
if(this.isEmpty(this.___rem))
{
var docEl = doc.documentElement;
this.___rem = parseFloat(docEl.style.fontSize);
}
return this.___rem;
};
/**
* @public
* @description 兼容处理,定义全屏功能;在window对象上定义以下方法: window.isFullScreen(),window.requestFullScreen(),window.cancelFullScreen()
* @function
* @memberof Redjs
* */
"use strict";
this.defineFullScreen = function defineFullScreen() {
/*
Native FullScreen JavaScript API
Assumes Mozilla naming conventions instead of W3C for now
*/
var fullScreenApi = {
supportsFullScreen: false,
isFullScreen: function () {
return false;
},
requestFullScreen: function () {
},
cancelFullScreen: function () {
},
fullScreenEventName: '',
prefix: ''
};
var browserPrefixes = 'webkit moz o ms khtml'.split(' ');
// check for native support
if (typeof document.cancelFullScreen != 'undefined') {
fullScreenApi.supportsFullScreen = true;
}
else
{
// check for fullscreen support by vendor prefix
for (var i = 0, il = browserPrefixes.length; i < il; i++) {
fullScreenApi.prefix = browserPrefixes[i];
if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined')
{
fullScreenApi.supportsFullScreen = true;
break;
}
}
}
// update methods to do something useful
if (fullScreenApi.supportsFullScreen) {
fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
fullScreenApi.isFullScreen = function () {
switch (this.prefix) {
case '':
return document.fullScreen;
case 'webkit':
return document.webkitIsFullScreen;
default:
return document[this.prefix + 'FullScreen'];
}
}
fullScreenApi.requestFullScreen = function (el) {
return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
}
fullScreenApi.cancelFullScreen = function (el) {
return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
}
}
// 将方法注册到 jQuery中
if (typeof jQuery != 'undefined') {
jQuery.fn.requestFullScreen = function () {
return this.each(function () {
var el = jQuery(this);
if (fullScreenApi.supportsFullScreen) {
fullScreenApi.requestFullScreen(el);
}
});
};
}
// export api
this.apply(window, fullScreenApi);
};
/**
*
* @returns
*/
this.fullScreen = function fullScreen(element) {
if (window.supportsFullScreen == false) {
alert('SORRY: Your browser does not support FullScreen');
return;
}
if (window.isFullScreen()) {
window.cancelFullScreen(element||document.body);
}
else {
window.requestFullScreen(element||document.body);
}
return window.isFullScreen();
}
/**
* @public
* @description重写 window.console 对象
* @function
* @memberof Redjs
* */
this.defineConsole = function defineConsole() {
if (!window.console) {
var console = {};
console.info = function (message) {
//alert(message);
};
console.log = function (message) {
alert(message);
};
console.warn = function (message) {
alert(message);
};
console.error = function (message) {
alert(message);
};
window.console = console;
}
};
/**
* @public
* @description 创建一个前端程序
* @function
* @memberof Redjs
* */
"use strict";
this.createApplication = function createApplication(config) {
var me = Rsd || this;
if (me.isEmpty(config)) {
console.error("配置不得为空")
return;
}
if(me.app)
{
window.alert('当前页面redjs application已创建,不可重复创建。');
}
me.isDebug = config.isDebug ? true : false;
me.isDemo = config.isDemo ? true : false;
config.launch = config.launch || function () {
alert('config launch funtion is null.')
};
var _config = me.apply(me.app,config);
_config.appName = config.appName || 'unamed_application';
_config.appFolder = config.appFolder || './src';
_config.getUserUrl = config.getUserUrl || 'authority/user';
_config.indexUrl = config.indexUrl || 'login.html';
_config.appEdition = config.appEdition || 'beta';
_config.appVersion = config.appVersion || '3.0';
_config.logoUrl = config.version || 'resources/images/sys/logo.jpg';
_config.requires = config.requires || [];
me.app = me.create('Rsd.common.Application', _config);
me.app.createdTime = Date.now();
//console.debug(me.app.createdTime,'app created.');
if (me.isMobile()) {
window.onerror = function (error) {
alert(error);
}
}
/*
* */
me.onReady(function appStartup() {
//console.debug(Date.now(),'app startup...');
me.app.startTime = new Date().getTime();
//等待框架加载
var _id = setInterval(function(){
if(!Rsd.isLoading())
{
clearInterval(_id);
}
//程序启动前执行
if (me.isFunction(me.app.beforeRun)) {
me.app.beforeRun.call(me.app);
}
//console.trace('me.app.run');
me.app.run();
},100)
});
return me.app;
};
/*
*
* */
this.clearHotKey = function clearHotKey(key) {
if (this.isEmpty(this.__hotKey)) {
return;
}
if (arguments.length == 0) {
this.__hotKey = {};
return;
}
delete this.__hotKey[key.toLowerCase()];
};
/**
*@desc 注册全局热键
* */
this.registerHotKey = function hotKey(key, fn, caller, args) {
this.__hotKey = this.__hotKey || {};
this.__hotKey[key.toLowerCase()] = {fn: fn, caller: caller, args: args};
};
/*
*
* */
this.exeHotKeyFun = function exeHotKeyFun(key) {
if (this.isEmpty(key)) {
return;
}
if (this.isEmpty(this.__hotKey)) {
return;
}
var _hotKey = this.__hotKey[key.toLowerCase()];
if (_hotKey) {
this.callFunction(_hotKey.caller || this, _hotKey.fn, _hotKey.args);
}
};
/**
* @public
* @description 注册事件,在 document onload 事件执行结束
* @function
* @memberof Redjs
* */
"use strict";
this.onReady = function onReady(callback) {
var me = Rsd || this;
var _fn = function (){
if (me.isFunction(callback)) {
callback.call();
}
window.Rsd.events.fire(null,'ready',arguments);
}
if(me.isReady())
{
_fn();
}
else
{
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", _fn, false);
}
}
};
/**
* DOMContentLoaded 事件 即:HTML 文档被加载和解析完成后
* */
this.isReady = function isReady( ) {
return this.__readyTime > 0;
}
/**
* @public
* @description 注册 document Resize事件
* @function
* @memberof Redjs
* */
"use strict";
this.onResize = function onResize(obj, callback) {
if(this.isWeChatApp())
{
return;
}
var me = Rsd || this;
var events = me.events;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
events.add(obj, resizeEvt, callback);
};
/**
* @description 注销 document Resize事件
*/
this.unResize = function unResize(callback) {
if(this.isWeChatApp())
{
return;
}
var me = Rsd || this;
var _fn = callback;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var events = me.events;
events.remove(resizeEvt, _fn);
};
/**
* @description 触发 document Resize事件
* @param {*} evt
* @returns
*/
this.fireResize = function fireResize(evt)
{
if(this.isWeChatApp())
{
return;
}
var me = Rsd || this;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var events = me.events;
events.fire(me, resizeEvt,evt);
};
/**
* @public
* @description Fires on the source object continuously during a drag operation.
* @function
* @param dom 可拖动区域的dom对象
* @param callback 控件拖动结束后回调方法
* @memberof Redjs
* */
"use strict";
this.onDrag = function onDrag(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondrag = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/*
*
* */
"use strict";
this.onDrop = function onDrop(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondrop = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/*
* 使用 onDrop 前必须注册onDragOver
* Fires on the target element continuously while the user drags the object over a valid drop target.
* */
"use strict";
this.onDragOver = function onDragOver(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondragover = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/*
*
* Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.
* */
"use strict";
this.onDragLeave = function onDragLeave(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondragleave = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/*
* Fires on the source object when the user releases the mouse at the close of a drag operation.
* */
"use strict";
this.onDragEnd = function onDragEnd(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondragend = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/*
*
* Fires on the target element when the user drags the object to a valid drop target.
* */
this.onDragEnter = function onDragEnter(dom, callback) {
if(this.isWeChatApp())
{
return;
}
var _dom = dom || document;
_dom.ondragenter = function (event) {
event.preventDefault();
if (Rsd.isFunction(callback)) {
callback(event);
}
}
};
/**
* @public
* @description 获取dom 计算后样式
* @param {stirng} id dom ID值
* @param {string} style 样式名称
* @function
* @memberof Redjs
* */
"use strict";
this.getComputedStyle = function getComputedStyle(id, style) {
if(this.isWeChatApp())
{
console.error('Wechat小程序环境下getComputedStyle方法不可用');
return null;
}
var el = document.getElementById(id);
var _value = null;
if (el) {
if (el.currentStyle) {
_value = el.currentStyle[style];
alert('ie:' + _value);
} else if (window.getComputedStyle) {
_value = window.getComputedStyle(el, null)[style];
alert('firefox:' + _value);
}
}
return _value;
};
/**
* @description 预加载图片对象
* */
this.loadImage = function loadImage(src) {
var img = new Image();
img.src = src;
return img;
};
/**
* @public
* @description 展示提示信息,可自定义按钮
* @param {string} title 标题
* @param {string} msg 消息内容
* @param {array} btns 按钮集合,如:[{text:'OK',fn:function(){}}]
* @function
* @memberof Redjs
* */
this.showMessage = function showMessage(title, msg, btns) {
var me = Rsd || this;
var _title = "提示信息"
var _msg = '';
var _btns = [{text: '确 定', fn: null}];
if (arguments.length > 2) {
_title = arguments[0];
_msg = arguments[1];
_btns = arguments[2];
}
if (arguments.length == 2) {
_msg = arguments[0];
_btns = arguments[1];
}
if (arguments.length == 1) {
_msg = arguments[0];
}
var box = me.create('Rsd.control.MessageBox', {
title: _title,
messageType: 'text',
messageStyle:{fontSize:'130%'},
message:_msg,
buttons:_btns,
parent: me
});
return box.showDialog(document.body);
};
/**
* @function
* @memberof Redjs
* */
this.showHtml = function showHtml(title, html) {
var me = Rsd || this;
var _title = title;
var _html = html||'';
if (arguments.length == 1) {
_title = "提示信息";
_html = arguments[0];
}
var _btns = [{text: '确 定', fn: null}];
var box = me.create('Rsd.control.MessageBox', {
width: 600,
height: 400,
title: _title,
messageType: 'html',
message:_html,
buttons:_btns,
parent: me
});
return box.showDialog(document.body);
};
/**
* @description 展示【确定】或【取消】操作的信息提示框
* @function
* @memberof Redjs
* */
this.yesOrNo = function yesOrNo(msg, callback_yes, callback_no) {
var me = Rsd || this;
var _title = "重要操作确认"
var _msg = msg;
var _btns = [{text: '确 定', fn: callback_yes}, {text: '取 消', fn: callback_no}];
var box = me.create('Rsd.control.MessageBox', {title: _title, message:_msg,buttons:_btns,parent: this});
return box.showDialog(document.body);
};
/**
* @public
* @description 提示popup信息
* @param {number} x x轴方向位置信息,以提示框居中时为位置 0
* @param {number} y y轴方向位置信息
* @function
* @memberof Redjs
* */
this.showPopup = function showPopup(msg, x, y) {
var me = Rsd || this;
var _height = 50;
var _width = 250;
me.__popup_count = this.__popup_count||0;
var _popup = me.create('Rsd.container.Component', {
border: false,
header:{visible:false},
width: '100%',
height: _height,
fixed:true,
layout: 'fit',
style: {zIndex: 99999,top:(y||0) + me.__popup_count*50},
bodyCls:'x-popup-bar',
items: [
{
xtype: 'label',
cls: 'x-popup-box',
label:{visible:false},
style:{left:x||0,lineHeight: _height},
ctrlCls: 'x-text',
height: _height,
width: _width,
text: msg
}
]
});
_popup.header.visible = false;
me.__popup_count++;
_popup.show(function () {
_popup.animate({top:-50},500,function () {});
});
setTimeout(function () {
me.__popup_count--;
_popup.close({opacity:0,top:-50},2000,0);
}, 3000);
};
/**
* @public
* @description 以动画的形式 将TipBox(有尖头指向)样式显示到目标(x,y)位置
* @param string msg
* @param int w
* @param int h
* @param int x
* @param int x
* @param int y
* @param int position
* */
this.showTip = function showTip(msg ,w,h,x,y,position) {
var _msg = null;
var _w = null;
var _h = null;
var _x = null;
var _y = null;
var _position = null;
for(var i =0;i < arguments.length;i++)
{
if(this.isString(arguments[i]) && _msg == null)
{
_msg = arguments[i];
continue;
}
if(this.isString(arguments[i]) && _position == null)
{
_position = arguments[i];
continue;
}
if(this.isNumber(arguments[i]) && _w ==null)
{
_w = arguments[i];
continue;
}
if(this.isNumber(arguments[i]) && _h ==null)
{
_h = arguments[i];
continue;
}
if(this.isNumber(arguments[i]) && _x==null)
{
_x = arguments[i];
continue;
}
if(this.isNumber(arguments[i]) && _y==null)
{
_y = arguments[i];
continue;
}
}
//
this.loadClass('Rsd.control.HtmlBox');
var _tip = this.create("Rsd.container.TipBox",{
header:{position:_position||'top',space:0},
width:_w||200,
height:_h||50,
border:false,
style:{opacity:0},
layout:{type:'border',align:'center'},
listeners:{
'click':{
element:'dom',
fn:function (sender,event) {
this.close(1000,{opacity:0,top:_y-200,left:_x-200},0);
Rsd.events.remove(Rsd,'click',this.id);
}
}
},
items:[
{
xtype:'html-box',
label:{visible:false},
//margin:'10 10 10 10',
region:'center',
style:{align:'center'},
height:'100%',width:'100%',html:_msg||''
}
]
});
_tip.show({left:_x==null?100:_x,top:_y==null?50:_y },1000,function () {
//延时加入 队列 防止click 事件 关闭显示
Rsd.events.add(Rsd,'click',this.id,function () {
_tip.close(1000,{opacity:0,top:_y-200,left:_x-200},0);
},true);
});
return _tip.id;
};
/**
* @description 提示JSON数据信息
* @function
* @memberof Redjs
* */
this.alertLog = function alertLog(obj) {
alert(Rsd.toString(obj));
};
/**
* @public
* @description 提示信息
* @function
* @memberof Redjs
* */
this.alert = function alert(title, msg, callback) {
//console.log(arguments);
var me = Rsd || this;
var _title = "提示信息";
var _msg = "";
var _callback = null;
if (arguments.length > 2) {
_title = arguments[0];
_msg = arguments[1];
_callback = arguments[2];
}
if (arguments.length == 2) {
if (Rsd.isFunction(arguments[1])) {
_msg = arguments[0];
_callback = arguments[1];
}
else {
_title = arguments[0];
_msg = arguments[1];
}
}
if (arguments.length == 1) {
_msg = arguments[0];
}
var _btns = null;
if (Rsd.isFunction(_callback)) {
_btns = [{text: '确 定', fn: _callback}];
}else {
_btns = [{text: '确 定', fn: null }];
}
var box = me.create('Rsd.control.MessageBox', {title: _title, message:_msg,messageType:((_msg.indexOf('<')>-1||_msg.indexOf('>')>-1 ) ? 'html':'text'),buttons:_btns,parent: this});
box.showDialog(document.body);
};
/**
* @public
* @description 关闭窗口
* @function
* @memberof Redjs
* */
this.closeWindow = function closeWindow() {
var win = window.open("about:blank", "_self");
win.close();
};
/*
* */
this.getTiming = function getTiming(ext) {
var _timing ={
redjsLoadStartTime: Rsd.__loadStartTime,
redjsLoadEndTime: Rsd.__loadEndTime,
redjsLoadTime: (Rsd.__loadEndTime || 0) - (Rsd.__loadStartTime || 0),
redjsBuildStartTime: Rsd.__buildStartTime,
redjsBuildEndTime: Rsd.__buildEndTime,
redjsBuildTime: (Rsd.__buildEndTime || 0) - (Rsd.__buildStartTime || 0)
};
var _per = window.performance;
if (_per && _per.timing) {
_timing.start = _per.timing.navigationStart;
//DNS查询耗时
_timing.DNS = _per.timing.domainLookupEnd - _per.timing.domainLookupStart;
//TCP链接耗时
_timing.TCP = _per.timing.connectEnd - _per.timing.connectStart;
//request请求耗时
_timing.request = _per.timing.responseEnd - _per.timing.responseStart;
//解析dom树耗时
_timing.domComplete = _per.timing.domComplete - _per.timing.domInteractive;
//白屏时间
_timing.white = _per.timing.responseStart - _per.timing.navigationStart;
//domready时间(用户可操作时间节点) :
_timing.domReady = _per.timing.domContentLoadedEventEnd - _per.timing.navigationStart;
//onload时间(总下载时间)
_timing.total = _per.timing.loadEventEnd - _per.timing.navigationStart;
_timing.end = _per.timing.loadEventEnd;
}
var _data = Rsd.apply( _timing,ext||{});
return _data;
};
/**
* @public
* @description 本地log日志,不向日志服务器发送
* @function
* @memberof Redjs
* */
this.log = function log(msg) {
var _args = [];
var stack = new Error().stack.split("@\n");
stack.splice(0,2);
stack = stack.join("<-");
_args.push.apply(_args,arguments);
_args.push.apply(_args,['call stack:' + stack + 'in class (' + this.$className||'' + ') by object(id:'+this.id||'' + ')']);
console.log.apply(this,_args);
};
/**
* @public
* @description 记录调试信息
* @param {string} msg
* @param {object} data
* @function
* @memberof Redjs
* */
this.debug = function debug(msg, data) {
var me = Rsd || this;
//debugger;
if (me.isDebug) {
var _args = [];
var stack = new Error().stack.split("@\n");
stack.splice(0,2);
stack = stack.join("<-");
_args.push.apply(_args,arguments);
_args.push.apply(_args,['call stack:' + stack + 'in class (' + this.$className||'' + ') by object(id:'+this.id||'' + ')']);
console.debug.apply(this,_args);
//发送到日志服务器
if (me.Logger) {
me.Logger.debug(msg, data);
}
}
};
/**
* @public
* @description info日志
* @param {string} msg
* @param {object} data
* @function
* @memberof Redjs
* */
this.info = function info(msg, data) {
var me = Rsd || this;
var _args = [];
var stack = new Error().stack.split("@\n");
stack.splice(0,2);
stack = stack.join("<-");
_args.push.apply(_args,arguments);
_args.push.apply(_args,['call stack:' + stack + 'in class (' + this.$className||'' + ') by object(id:'+this.id||'' + ')']);
console.log.apply(this,_args);
//发送到日志服务器
if (me.Logger) {
me.Logger.info(msg, data);
}
};
/**
* @public
* @description 警告日志
* @param {string} msg
* @param {object} data
* */
this.warn = function warn(msg, data) {
var me = Rsd || this;
var _args = [];
var stack = new Error().stack.split("@\n");
stack.splice(0,2);
stack = stack.join("<-");
_args.push.apply(_args,arguments);
_args.push.apply(_args,['call stack:' + stack + 'in class (' + this.$className||'' + ') by object(id:'+this.id||'' + ')']);
console.warn.apply(this,_args);
//发送到日志服务器
if (me.Logger) {
me.Logger.warn(msg, data);
}
};
/**
* @public
* @desc 调试模式下,提示错误信息,非调试模式打印到控制台;如日志接口(Rsd.Logger)存在发送日志到服务端
* @param {string} msg
* @param {string} url
* @param {object} ex
* */
this.error = function error(msg, url, ex) {
var _msg = msg;
var _url = url;
var _ex = ex;
if (arguments.length == 1 && this.isObject(arguments[0])) {
_msg = null;
_url = null;
_ex = arguments[0];
}
if (arguments.length == 2) {
_url = null;
_ex = null;
if(this.isString(arguments[1]))
{
_url = arguments[1];
}else
{
_ex = arguments[1];
}
}
var me = Rsd || this;
if (me.isDebug) {
console.error(arguments);
alert(msg + ((_ex && _ex.message) ? (':' + _ex.message) : ''));
}
else {
console.trace(arguments);
console.error((Rsd.isEmpty(msg) ? '运行异常' : _msg) + (_url ? '(' + _url + ')' : ''));
}
if (_ex) {
console.trace(_ex);
}
if (me.Logger) {
me.Logger.error(_msg + '(' + _url + ')', ex);
}
};
/**
* @public
* @description 写入会话缓存
* @param {string} key
* @param {string} value
* */
this.writeSession = function writeSession(key, value) {
var me = Rsd || this;
var storage = window.sessionStorage;
if (storage) {
storage.setItem(key, me.toString(value));
}
};
/**
* @public
* @description 读取指定会话缓存
* @param {string} key
* */
this.readSession = function readSession(key) {
var me = Rsd || this;
var storage = window.sessionStorage;
var data = null;
if (storage && storage.getItem(key) != null) {
data = me.toJson(storage.getItem(key));
}
return data;
};
/**
* @public
* @description 清除指定会话缓存
* @param {string} key
* */
this.removeSession = function removeSession(key) {
var me = Rsd || this;
var storage = window.sessionStorage;
if (key && storage && storage.getItem(key) != null) {
return storage.removeItem(key);
}
};
/**
* @public
* @description 清除所有会话缓存
* */
this.clearSession = function clearSession()
{
window.sessionStorage.clear();
};
/**
* @public
* @description 写到本地缓存
* @param {string} key
* */
this.writeLocal = function writeLocal(key, value) {
var me = Rsd || this;
var storage = window.localStorage;
if (storage) {
storage.setItem(key, me.toString(value));
}
};
/**
* @public
* @description 读取指定本地缓存
* @param {string} key
* */
this.readLocal = function readLocal(key) {
var me = Rsd || this;
var storage = window.localStorage;
var data = null;
if (storage && storage.getItem(key) != null) {
data = me.toJson(storage.getItem(key));
}
return data;
};
/**
* @public
* @description 清除指定本地缓存
* @param {string} key
* */
this.removeLocal = function removeLocal(key) {
var me = Rsd || this;
var storage = window.localStorage;
if (key && storage && storage.getItem(key) != null) {
return storage.removeItem(key);
}
};
/**
* @public
* @description 清除所有本地缓存
* */
this.clearLocal = function clearLocal() {
window.localStorage.clear();
};
/**
* @public
* @description 添加Cookie
* @param {*} name
* @param {*} value
* @param {*} expiresHours 单位:小时
*/
this.addCookie = function addCookie(name, value, expiresHours) {
var me = Rsd || this;
var cookieString = name + "=" + escape(value);
//判断是否设置过期时间
if (expiresHours > 0) {
var date = new Date();
date.setTime(date.getTime + expiresHours * 3600 * 1000);
cookieString = cookieString + "; expires=" + date.toGMTString();
}
document.cookie = cookieString;
};
/**
* @public
* */
this.getCookie = function getCookie(name) {
var me = Rsd || this;
var strCookie = document.cookie;
var arrCookie = strCookie.split("; ");
for (var i = 0; i < arrCookie.length; i++) {
var arr = arrCookie[i].split("=");
if (arr[0] == name) return arr[1];
}
return "";
};
/**
* @public
* */
this.deleteCookie = function deleteCookie(name) {
var me = Rsd || this;
var date = new Date();
date.setTime(date.getTime() - 10000);
document.cookie = name + "=null; expires=" + date.toGMTString();
};
/**
* @public
* */
"use strict";
this.getScript = function getScript(obj, f) {
if (obj == undefined) {
return "null";
}
var r = [];
if (typeof obj == "string") {
return "\'" + obj.replace(/([\"\\])/g, "\\$1").replace(/(\n)/g, "\\n").replace(/(\r)/g, "\\r").replace(/(\t)/g, "\\t").replace(/(\')/g, "\\'") + "\'";
}
if (typeof obj == "object") {
var _type = this.getType(obj);
if (_type == '[object Array]') {
for (var i = 0; i < obj.length; i++)
r.push(Rsd.getScript(obj[i], true))
r = "[" + r.join() + "]";
}
if (_type == '[object Object]') {
if (Rsd.isCreated(obj)) {
this.error('类型为[' + obj.xtype + ']属性定义为已创建对象,该类无法定义。');
} else {
for (var i in obj) {
if(obj.hasOwnProperty(i))
{
if (typeof obj[i] != 'function') {
r.push((f ? '' : 'this.') + i + (f ? ':' : '=') + this.getScript(obj[i], true));
}
else {
//无法实现自动为未命名的方法加上方法名
r.push((f ? '' : 'this.') + i + (f ? ':' : '=') + obj[i].toString());
}
}
}
r = (f ? '{' : '') + r.join(f ? ',' : ';') + (f ? '}' : '');
}
}
return r;
}
return obj.toString().replace(/\"\:/g, '":""');
};
/**
* @public
* @param className string
* @param config object
* @param callback function
*
* */
"use strict";
this.define = function define(className, config, callback) {
if(!Rsd.isString(className))
{
console.error(className);
return;
}
//此处需要进行 命名规范 约束
//
var me = Rsd || this;
me.debug('define class:' + className);
if (me.classes[className] != null) {
me.error('Failed to define class ['+ className + '],because it has defined.');
return;
}
config = config || {};
//模拟类静态方法,在类型定义之前被执行
if (config.static && config.static instanceof Function) {
var _static = config.static;
delete config.static;
if (_static.length > 0) {
_static(function () {
me.define(className, config, callback);
});
return;
} else {
_static();
}
}
var _extend = config.extend;
//delete config.extend;
var _requires = config.requires;
delete config.requires;
var _xtype = config.xtype ? config.xtype : className;
delete config.xtype;
var _properties = {};
var _functions = {};
if (_extend === className) {
this.error('Failed to define class', className, new Error('extend class don\'t allow same to className'));
return;
}
if (_extend) {
if (!me.classes[_extend]) {
me.debug('load class '+className+' extend class:' + _extend);
me.loadClass(_extend);
}
if (typeof me.classes[_extend] !== 'function') {
throw new Error('define ' + className + ' Fail ,Inheritance dependency error:' + _extend + ' can not found.');
}
}
var _namespace=null;
var _namespaces = className.split('.');
for (var i in config) {
if(!config.hasOwnProperty(i))
{
continue;
}
if (me.isFunction(config[i])) {
_functions[i] = config[i]
continue;
}
//定义对象属性
_properties[i] = config[i];
continue;
}
if (!_functions.hasOwnProperty('constructor') || !me.isFunction(_functions.constructor)) {
_functions['constructor'] = function () {
me.warn('Could not find function constructor in ' + this.$className + '.');
};
}
for (var n in _namespaces) {
if(!_namespaces.hasOwnProperty(n))
{
continue;
}
var _script="";
if (!_namespaces[n]) {
continue;
}
if (_namespace) {
_namespace += '.';
}
else {
_namespace = '';
}
_namespace += _namespaces[n];
if (n < _namespaces.length - 1) {
_script = 'if(!' + _namespace + '){' + _namespace + '={};}; ';
}
else {
_script = '' + _namespace + ' =';
_script += ' function ' + _namespaces[n] + '(_config){';
//动态原型技术
if (_extend) {
_script += 'this.__proto__.__proto__ = new ' + (_extend || 'Object') + '(false);';
}
//属性初始化
_script += me.getScript(_properties) + ';';
//_script += 'console.log(this.constructor);';
_script += 'this.constructor.call(this,_config);';
_script += 'if(_config && Rsd.isFunction(this.init)){ this.init.call(this);}';
_script += 'return this;};';
_script += 'Rsd.classes[\'' + className + '\']=' + _namespace + ';';
}
window.eval(_script);
}
var _depClass = _extend;
for (var p in _functions) {
me.classes[className].prototype[p] = _functions[p];
}
me.classes[className].prototype.$className = className;
me.classes[className].prototype.xtype = _xtype;
me.classes[className].prototype.dependencies = new Array();
me.classes[className].prototype.dependencies[_xtype] = className;
if (_depClass) {
me.classes[className].prototype.dependencies[me.types[_depClass]] = _depClass;
}
var __isLoading = me.isLoading();
for (var i in _requires) {
if(!_requires.hasOwnProperty(i))
{
continue;
}
_depClass = _requires[i];
if (_depClass.length == 0) {
continue;
}
//框架加载中, 不加载依赖项
if (__isLoading === false && !me.classes[_depClass]) {
me.debug('load class '+className+' dependent :' + _extend);
this.loadClass(_depClass);
}
this.classes[className].prototype.dependencies[me.types[_depClass]] = _depClass;
}
me.types[className] = _xtype
if (me.xtypes.hasOwnProperty(_xtype)) {
me.error('The xtype \'' + _xtype + '\' of class [' + className + '] is exist.');
}
else {
me.xtypes[_xtype] = className;
}
//_properties 属性定义
var _t = _extend ? new me.classes[_extend]() : {};
var _script = '';
for (var p in _properties) {
if (_t.hasProperty && _t.hasProperty(p)) {
/** @bug 父类对象属性不能重复定,否则会覆盖父类功能*/
//console.log('[' + className + '] prototype has property \'' + p + '\',program continue.');
continue;
}
//var enumerable = true;
//console.log('==>define [' + className + '] property :' + p);
_script += 'Rsd.defineProperty(Rsd.classes[\'' + className + '\'],\'' + p + '\',function __getter(){return this[\'__' + p + '\'];},function __setter(value){ this[\'__' + p + '\'] = value;},true);';
}
//console.log(_script);
window.eval(_script);
if (me.isFunction(callback)) {
callback.call(me, me.classes[className]);
}
me.debug('define class:' + className + ' end.');
};
/**
* @public
* @description 属性定义,如果属性存在,将跳过
* */
"use strict";
this.defineProperty = function defineProperty(type, propertyName, getter, setter, enumerable) {
var _type = this.isString(type) ? this.classes[type] : type;
if (!_type) {
return;
}
if (_type.prototype.hasOwnProperty(propertyName)) {
console.warn('Property [' + propertyName + '] is exsit in ' + _type.prototype.$className);
return;
}
if (Object.defineProperty) {
var _obj = {enumerable: enumerable, configurable: true};//{value:defaultValue,writable:true,enumerable: enumerable,configurable:true};
if (getter) {
_obj['get'] = getter;
}
if (setter) {
_obj['set'] = setter;
}
Object.defineProperty(_type.prototype, propertyName, _obj);
} else {
if (getter && Object.prototype.__defineGetter__) {
_type.prototype.__defineGetter__(propertyName, getter);
}
if (setter && Object.prototype.__defineSetter__) {
_type.prototype.__defineSetter__(propertyName, setter);
}
}
};
/**
*@public
* */
this.setDomToken = function setDomToken(flag, value) {
this.domFlag = flag;
this.domFlagValue = value;
};
/**
* @public
* @description 单列和需要缓存的对象会存入Rsd.objects对象中。
* */
"use strict";
this.create = function create(className, config) {
var me = Rsd || this;
//debugger;
if (!className || className == '') {
throw new Error('call Rsd.create function argument \'className\' is null. ');
}
if (me.singletons[className]) {
return me.objects[me.singletons[className]];
}
me.debug('create object:' + className);
me.loadClass(className);
if (me.classes[className] == null) {
throw new Error('class \'' + className + '\' not found.');
}
var _obj = new me.classes[className](config);
if (_obj.events) {
_obj.events.fire(_obj, 'aftercreate', {});
}
//debugger;
if (_obj.singleton || _obj.cache) {
me.objects[_obj.id] = _obj;
}
if (_obj.singleton) {
me.singletons[className] = _obj.id;
}
me.debug('return object:' + _obj.id);
return _obj;
};
/**
* @public
* @param xtype
* @param config
*
* */
"use strict";
this.widget = function widget(xtype, config) {
var _xtype = xtype;
var _className = null;
var _config = config || {};
if (this.isString(xtype)) {
_xtype = xtype;
}
if (this.isObject(xtype)) {
_config = xtype;
_xtype = _config['xtype'];
delete _config['xtype'];
}
if (this.isEmpty(_xtype)) {
console.error(arguments);
throw new Error('call Redjs.widget of argument \'xtype\' is null.');
}
_className = this.xtypes[_xtype];
if (!_className) {
throw new Error('call Redjs.widget of xtype \'' + _xtype + '\' mapping className not found.');
}
return this.create(_className, _config);
};
/**
*@public
* */
this.isCreated = function isCreated(obj) {
return obj && this.isFunction(obj.isCreated) && obj.isCreated();
};
/**
* @private
* */
this.getId = function getId(prefix) {
this.__id++;
var _id = prefix.replaceByRegExp('[-]', '_') + '_' + this.__id;
if(this.isWeChatApp())
{
//console.error('Wechat小程序环境下getId方法不可用');
return _id;
}else
{
while (document.getElementById(_id)) {
this.__id++;
}
}
return _id;
};
/**
* @public
* @description zIndex + offset
* @return number
* */
this.getZIndex = function getZIndex(offset) {
return this.__zIndex + offset;
};
/**
* @public
* @description 对象克隆
* */
this.clone = function clone(obj) {
var o;
switch (typeof obj) {
case 'undefined':
break;
case 'string' :
o = obj + '';
break;
case 'number' :
o = obj - 0;
break;
case 'boolean' :
o = obj;
break;
case 'object' :
if (obj === null) {
o = null;
break;
}
if (obj instanceof Array) {
o = [];
for (var i = 0, len = obj.length; i < len; i++) {
o.push(clone(obj[i]));
}
} else {
if (obj instanceof Node) {
o = obj.cloneNode(true);
break;
}
o = {};
for (var k in obj) {
o[k] = clone(obj[k]);
}
}
break;
default:
o = obj;
break;
}
return o;
};
/**
@description 将参数config合并到obj中
* */
this.apply = function apply(obj, config, deep) {
var _deep = deep || 1;
_deep = _deep < 1 ? 1 : _deep;
if (obj && config && this.isType(obj, Object) && this.isObject(config)) {
for (var i in config) {
try {
//delete obj[i];
if (_deep == 1) {
obj[i] = config[i];
continue;
}
//console.log(i + '--' + _deep);
if (obj[i] && config[i] && this.isType(obj[i], Object) && this.isObject(config[i])) {
//console.log('1111'); console.log(this.toString(obj[i])); console.log(this.toString(config[i]));
this.apply(obj[i], config[i], _deep - 1)
} else {
obj[i] = config[i];
}
} catch (ex) {
this.error('Run function Redjs.apply fail', 'Rsd', ex);
}
}
}
return obj;
};
/**
* @public
* */
this.loadClass = function loadClass(className, callback) {
if (!this.isString(className)) {
console.error(className);
return;
}
var me = Rsd || this;
if (!me.isNullOrUndefined(me.classes[className])) {
return;
}
if(me.classesCallback[className])
{
me.classesCallback[className].push(callback);
return;
}
me.classesCallback[className] = [callback];
me.debug('Load class: ' + className);
var _url = className;
var _flag = true;
//从插件中获取
if (_flag && me.app && me.app.plugins) {
var _c_name = className.substring(0,className.lastIndexOf('.'));
var _p = me.app.getPlugin(_c_name);
while(_p==undefined || _p==null)
{
var i = _c_name.lastIndexOf('.');
if(i<0)
{
break;
}
_c_name = _c_name.substring(0,i);
_p = me.app.getPlugin(_c_name);
}
if(_p)
{
_url = _url.replace(_p.name, '');
_url = _url.replace("Rsd", me.getRedjsHost());
_url = _p.path + '/' + _url.replaceByRegExp('[.]', '/') + '.js';
_url += '?t=' + (_p.isDebug ? new Date().getTime() : _p.pluginDate);
_flag = false;
}
}
if (_flag && me.app && className.startWith(me.app.appName)) {
_url = _url.replace(me.app.appName, '');
_url = _url.replace("Rsd", me.getRedjsHost());
_url = me.app.appFolder + '/' + _url.replaceByRegExp('[.]', '/') + '.js';
_url += '?t=' + (me.app.isDebug ? new Date().getTime() : this.app.appDate);
_url = (this.app && this.app.jsAgentHost) ? (this.app.jsAgentHost + '?' + this.utf8ToBase64(_url)) : _url;
_flag = false;
}
if (_flag) {
_url = _url.replaceByRegExp('[.]', '/') + '.js';
if (me.isAgentHost()) {
_url = _url.replace("Rsd", "");
if(_url.startWith('/'))
{
_url = _url.substr(1);
}
_url = me.getRedjsHost() + this.utf8ToBase64(_url + '?t=' + (me.isDebug ? new Date().getTime() : this.timestamp));
}
else {
_url = _url.replace("Rsd", me.getRedjsHost());
_url += '?t=' + (me.isDebug ? new Date().getTime() : this.timestamp);
}
}
me.loadScriptFile(_url, function (response, status) {
if (me.classes[className]) {
me.debug('Load class: ' + className + ' end.');
var _list = me.classesCallback[className];
for(var i in _list)
{
me.callFunction(me, _list[i]);
}
}
else {
me.error(className + ' can not found.Please check class name is case upper or lower.');
}
});
}
/**
*@public
*@desc 用<script> 加载标签 pugins 目录下资源或第三方资源,可以避免异步加载方式失败。
* */
this.loadPlugin = function loadPlugin(url, callback) {
if(this.isWeChatApp())
{
console.log(url);
console.error('Wechat小程序环境下loadPlugin方法不可用,请在document的head中提前加载css文件。');
return ;
}
var me = Rsd || this;
var name = url;
if (name == undefined || name == null || name == '') {
return;
}
var src = null;
if (name.toLowerCase().startWith('http://') || name.toLowerCase().startWith('https://')) {
src = name;
} else {
src = me.getRedjsUrl(name) ;
}
me.debug('Load plugin:' + src);
var el = document.createElement('script');
el.type = "text/javascript"
el.src = src;
el.onload = el.onreadystatechange = function onready() {
if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
if (me.isFunction(callback)) callback.call();
// Handle memory leak in IE
el.onload = el.onreadystatechange = null;
}
};
document.getElementsByTagName('head')[0].appendChild(el);
};
/**
* @public
* @description 用ajax【同步加载】脚本文件,加载到本地后并执行 不用用于加载jquery
* @param {string} url 脚本地址
* @param {string} callback 加载执行完成回调函数
* */
this.loadScriptFile = function loadScriptFile(url, callback) {
var me = Rsd || this;
var _url = url;
if (_url.startWith('http://') || _url.startWith('https://')) {
}
else {
if(_url.startWith('/'))
{
_url = _url.substr(1);
}
_url = (this.app && this.app.jsAgentHost) ? (this.app.jsAgentHost + '?' + this.utf8ToBase64(_url)) : _url;
}
me.debug('Load script file: ' + _url);
// 创建ajax对象
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('GET', _url, false);//同步加载
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");//标识为ajax请求
//xhr.setRequestHeader("Content-type", 'application/x-javascript; charset=utf-8');//开启后会出现 OPTIONS 请求
xhr.send(null);
//同步 不出发 onload onreadystatechange 事件
//xhr.onload = function(){};
//xhr.onreadystatechange = function(){};
if (xhr.readyState == 4 && xhr.status == 200) {
var str = xhr.responseText;
try
{
window["eval"].call(window, str);
}
catch (e)
{
try
{
window.eval(str);
}
catch (e1)
{
console.error('load javascript file [' + url + '] successed,script execute error in function loadScriptFile.');
console.error(e1);
}
}
if (me.isFunction(callback))
{
callback.apply(me,[str]);
}
}
else
{
me.error('Failed to load script file resource: ' + _url + "(" + xhr.responseText + ")");
}
me.debug('Load script file: ' + _url + ' end.');
};
/**
* @public
* @description 用ajax【异步加载】json文件,加载到本地后并序列化json 不用用于加载jquery
* @param {string} url 脚本地址
* @param {string} callback 加载执行完成回调函数
*/
this.loadJsonFile = function loadJsonFile(url,callback)
{
var me = Rsd || this;
var _url = url;
if (_url.startWith('http://') || _url.startWith('https://')) {
}
else
{
if(_url.startWith('/'))
{
_url = _url.substr(1);
}
_url = (this.app && this.app.jsAgentHost) ? (this.app.jsAgentHost + '?' + this.utf8ToBase64(_url)) : _url;
}
me.debug('Load json file: ' + _url);
// 创建ajax对象
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
try
{
xhr.open('GET', _url, true);//异步加载
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");//标识为ajax请求
//xhr.setRequestHeader("Content-type", 'application/x-javascript; charset=utf-8');//开启后会出现 OPTIONS 请求
xhr.send(null);
xhr.onload = function()
{
if (xhr.readyState == 4 && xhr.status == 200) {
var str = xhr.responseText;
try
{
var json = me.toJson(str);
if (me.isFunction(callback))
{
callback.apply(me,[json]);
}
}
catch (e)
{
console.error('load json file [' + url + '] successed.');
console.error(e);
}
}
else
{
me.error('Failed to load json file resource: ' + _url + "(" + xhr.responseText + ")");
}
me.debug('Load json file: ' + _url + ' end.');
};
xhr.onerror = function(evt)
{
console.error('load json file error',evt);
}
//xhr.onreadystatechange = function(){ };
}
catch(err)
{
console.error('load json file occured exception',err);
}
},
/**
*@public
* */
this.loadCssFile = function loadCssFile(url) {
if(this.isWeChatApp())
{
console.error(url);
console.error('Wechat小程序环境下loadCssFile方法不可用,请在document的head中提前加载css文件。');
return ;
}
var head = document.getElementsByTagName('HEAD').item(0);
var style = document.createElement('link');
style.href = url;
style.rel = 'stylesheet';
style.type = 'text/css';
head.appendChild(style);
};
/**
* @public
* */
this.gbkToUTF8 = function gbkToUTF8(wide) {
var c, s;
var enc = "";
var i = 0;
while (i < wide.length) {
c = wide.charCodeAt(i++);
// handle UTF-16 surrogates
if (c >= 0xDC00 && c < 0xE000) continue;
if (c >= 0xD800 && c < 0xDC00) {
if (i >= wide.length) continue;
s = wide.charCodeAt(i++);
if (s < 0xDC00 || c >= 0xDE00) continue;
c = ((c - 0xD800) << 10) + (s - 0xDC00) + 0x10000;
}
// output value
if (c < 0x80) enc += String.fromCharCode(c);
else if (c < 0x800) enc += String.fromCharCode(0xC0 + (c >> 6), 0x80 + (c & 0x3F));
else if (c < 0x10000) enc += String.fromCharCode(0xE0 + (c >> 12), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
else enc += String.fromCharCode(0xF0 + (c >> 18), 0x80 + (c >> 12 & 0x3F), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
}
return enc;
};
/**
*
* @public
* */
this.unicodeToUTF8 = function unicodeToUTF8(str) {
if (null == str)
return null;
var strUni = String(str);
var strUTF8 = String();
for (var i = 0; i < strUni.length; i++) {
var wchr = strUni.charCodeAt(i);
if (wchr < 0x80) {
strUTF8 += strUni.charAt(i);
}
else if (wchr < 0x800) {
var chr1 = wchr & 0xff;
var chr2 = (wchr >> 8) & 0xff;
strUTF8 += String.fromCharCode(0xC0 | (chr2 << 2) | ((chr1 >> 6) & 0x3));
strUTF8 += String.fromCharCode(0x80 | (chr1 & 0x3F));
}
else {
var chr1 = wchr & 0xff;
var chr2 = (wchr >> 8) & 0xff;
strUTF8 += String.fromCharCode(0xE0 | (chr2 >> 4));
strUTF8 += String.fromCharCode(0x80 | ((chr2 << 2) & 0x3C) | ((chr1 >> 6) & 0x3));
strUTF8 += String.fromCharCode(0x80 | (chr1 & 0x3F));
}
}
return strUTF8;
};
/*
*
* */
this.utf8ToBase64 = function utf8ToBase64( str ) {
return window.btoa(unescape(encodeURIComponent(str)));
}
/*
*
* */
this.base64ToUTF8 = function base64ToUTF8( str ) {
return decodeURIComponent(escape(window.atob(str)));
}
/**
* @public
* @description 获取屏幕设备像素值(1英寸正方形区域(长*宽)像素)
* */
this.getDPI = function getDPI() {
if(this.__dpi)
{
return this.__dpi;
}
var _width, _height;
if (window.screen.deviceXDPI) {
_width = window.screen.deviceXDPI;
_height = window.screen.deviceYDPI;
}
else {
var tmpNode = document.createElement("DIV");
tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden;";
document.body.appendChild(tmpNode);
_width = parseInt(tmpNode.offsetWidth);
_height = parseInt(tmpNode.offsetHeight);
tmpNode.parentNode.removeChild(tmpNode);
//console.log(_width,_height);
}
this.__dpi = {width: _width, height: _height};
return this.__dpi;
};
/**
* @description 将一个块区域的长宽的值(px)转换为以mm为计算单位的值
* @param {number} width
* @param {number} height
* @param {number} scale 缩放比例 参考: window.devicePixelRatio;
* @returns {object} {width:100,height:100}
**/
this.pxToMm = function pxToMm(width, height,scale) {
var dpi = this.getDPI();
var _scale = scale||1;
var inch_w = (width||0)/ (dpi.width * _scale);
var _width = inch_w * 25.4 ;
var inch_h = (height||0)/(dpi.height * _scale);
var _height = inch_h * 25.4 ;
return {width:_width,height:_height};
};
/**
* @description 将一个块区域的长宽的值(mm)转换为以px为计算单位的值
* @param {number} width
* @param {number} height
* @param {number} scale 缩放比例 参考: window.devicePixelRatio;
* @returns {object} {width:100,height:100}
*/
this.mmToPx = function mmToPx(width, height,scale) {
var dpi = this.getDPI();
var inch_w = (width||0)/25.4;
var inch_h = (height||0)/25.4;
var _scale = scale||1;
var _width = inch_w * dpi.width * _scale;
var _height = inch_h * dpi.height * _scale;
return {width:_width,height:_height};;
};
/**
*
* @param {*} url
* @param {*} callback
*/
this.loadTemplateFile = function loadTemplateFile(url, callback) {
var me = Rsd || this;
var _url = url;
if (_url.startWith('http://') || _url.startWith('https://')) {
}
else {
if(_url.startWith('/'))
{
_url = _url.substr(1);
}
}
me.debug('Load file: ' + _url);
// 创建ajax对象
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('GET', _url, false);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");//标识为ajax请求
//xhr.setRequestHeader("Content-type", 'application/x-javascript; charset=utf-8');//开启后会出现 OPTIONS 请求
xhr.send(null);
if (xhr.readyState == 4 && xhr.status == 200) {
var str = xhr.responseText;
if (me.isFunction(callback)) callback.call(me,str);
} else {
me.error('Failed to load resource: ' + _url + "(" + xhr.responseText + ")");
}
me.debug('Load file: ' + _url + ' end.');
};
/***
* 编译模板 或 编译+渲染模板
*/
this.template = function template(tplStr, data) {
var _fn = this.compile(tplStr);
//console.log(_fn)
return data ? _fn(data) : _fn;
};
/**
* 模板编译 并缓存 方法 ,返回编译后的方法
* @param {*} tplStr 模板字符串
* @param {*} caseno 引擎方案:1 or 2
* @returns
*/
this.compile = function compile(tplStr,caseno)
{
var _fn = null;
if(Rsd.isEmpty(caseno)|| caseno==1)
{
//模板编译引擎 方案一
//两种正则表达式匹配模式:
// interpolate:取值变量,需要在其位置替换出相应的值==>可扩展成支持多种模式:{{name}},<%=name%>
// evaluate:代码,执行代码语句
var interpolate =/<%=(.+?)%>/g;
var interpolate1 = /{{=(.+?)}}/g;
var evaluate = /<%(.+?)%>/g;
var evaluate1 = /{{(.+?)}}/g;
var regStr = interpolate.source + "|" + interpolate1.source + "|" + evaluate.source + "|" + evaluate1.source + "|$"
//正则表达式组
//var matcher = new RegExp(`${interpolate.source}|${interpolate1.source}|${evaluate.source}|${evaluate1.source}|$`, 'g' );
var matcher = new RegExp(regStr, 'g' );
var index = 0
var p = '';
//需要处理的特殊字符
var escapes = {
'\n': 'n',
'\r': 'r',
'\u2028': 'u2028',
'\u2029': 'u2029',
'\\': '\\',
"'": "'",
};
var escapeReg = /[\n\r\u2028\u2029\\']/g;
//特殊字符转义 处理
var escapeChar = function (match) { return '\\' + escapes[match];} ;
var str = tplStr||'';
str.replace(matcher, function (match, interpolate, interpolate1, evaluate,evaluate1, offset) {
// match 匹配到对象 console.log(match);
// console.log(interpolate);
// console.log(interpolate);
// 正则对象的lastIndex属性只有在开启g标志且在regexp.exec和regexp.test方法有效,指定下次匹配的开始位置,此属性可读可写,
// 如果方法没找到任何匹配则自动将它设置0,而在这里,用index来模拟lastIndex的作用
// 另外需要注意,matcher最后的`$`目的是匹配字符串结束位置,从而得到结束位置的offset,
// 当`$`发生匹配时,match是空字符串,因为`$`是零宽断言,确实发生匹配但是没有匹配内容,故返回空字符串
// 使用slice方法取子字符串的副本,确保str保持不变
// 将本次匹配到的<%=xxx%>或<%xxx%>之前的文本进行特殊字符文本化
var line = str.slice(index, offset).replace(escapeReg, escapeChar);
p += line;
// 记录下次replace匹配的开始位置
index = offset + match.length;
// 进行替换
// 这里巧妙利用了正则表达式的 捕获分组 和 或运算
// `/part1(group1)|part2(group2)|part3/g`这是上面matcher的结构,
// 由于或运算的存在,只要三者之一匹配成功,整个正则表达式匹配成功,就会执行replace的回调函数,
// 由于group1和group2必然要存在(因为它们写在正则表达式里面),
// 那么其中某一个就得是undefined,如果是part3发生的匹配,那么group1和group2都是undefined
//变量
if (interpolate) {
p += '\' + ( '+interpolate + '|| \'\') + \'';
}
if (interpolate1) {
p += '\' + ( ' + interpolate1 + '|| \'\') + \'';
}
//模板格式0 要替换的代码
if (evaluate)
{
p += '\'; ' + evaluate + ' p+=\'';
}
//模板格式1 要替换的代码
if (evaluate1)
{
p += '\'; ' + evaluate1 + ' p+=\'';
}
// 把匹配到的字符串原封不动地还回去,确保str保持不变
return match;
});
// 给p拼上头部和尾部的代码, with 语法影响性能
var code = "var p = ''; try{ with(data){ p+='" + p + "';}}catch(err){console.error(err);console.log(data);} return p;";
// 创建模板渲染函数
try
{
_fn = new Function('data', code);
}
catch(err)
{
console.error(err);
_fn = function()
{
console.debug("模板参考格式:{{=name}}或<%=name%>");
}
console.error("模板编译失败:"+code);
}
//console.log(code);
}
else
{
//模版编译引擎 方案二 ,方案二 不支持格式:{{}} {{=user.name}}
var str=tplStr||'';
_fn = new Function(
'data',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
"with(data){p.push('" +
str
.replace(/[\r\t\n]/g, ' ')
.split('<%')
.join('\t')
.replace(/((^|%>)[^\t]*)'/g, '$1\r')
.replace(/\t=(.*?)%>/g, "',$1,'")
.split('\t')
.join("');")
.split('%>')
.join("p.push('")
.split('\r')
.join("\\'") +
"');}return p.join('');"
);
}
return _fn;
};
/**
* @public
* @description 格式化模版字符串
* */
this.formatTemplateString = function formatTemplateString(str, data) {
if(this.isEmpty(str))
{
return "";
}
var _str = str;
if(str.indexOf("#=")>-1 && str.indexOf("=#")>-1)
{
_str = str.replace("#=","{{=").replace("=#","}}");
console.warn('不建议使用的模板语法格式:#=name=#,请使用{{=name}}格式替代');
console.warn(str);
}
var html = this.template(_str,data);
return html;
},
/**
* @public
* @description 获取App
* */
this.getApp = function getApp() {
return this.app;
};
/**
* 添加App属性
*/
this.setAppConfig = function setAppConfig(name,value)
{
if(!this.isEmpty(this.app))
{
this.app[name] = value;
}
},
/**
* 获取APP配置项,即app属性值
*/
this.getAppConfig = function getAppConfig(name)
{
if(this.isEmpty(this.app))
{
return '';
}
return this.app[name]
};
/**
* @public
* @description 获取App Id
* */
this.getAppId = function getAppId() {
if(this.isEmpty(this.app))
{
return '';
}
return this.app.appId || window.Rsd.projectId;
};
/**
* @public
* @description 获取App token
* */
this.getAppToken = function getAppToken() {
if(this.isEmpty(this.app) )
{
return '';
}
//console.log('getAppToken',this.app.appToken);
return this.app.appToken;
};
/**
* @public
* @description 设置token
* */
this.setAppToken = function setAppToken(token) {
if(this.isEmpty(this.app) && this.getApp)
{
this.app = this.getApp();
}
this.app.appToken = token
//console.log('setAppToken',this.app.appToken);
};
/**
*
*/
this.getAppAuthorization = function getAppAuthorization()
{
if(this.isEmpty(this.app))
{
return '';
}
return this.app.authorization;
};
/**
* @public
* */
this.checkToken = function checkToken() {
};
/**
* @public
* @param config 将被合并到Ajax对象上
* @param callback 回调函数
* */
this.httpRequest = function httpRequest(config, data, callback) {
var _c = null;
var _d = null;
var _fn = null;
for(var i in arguments)
{
if(_c == null && this.isString(arguments[i]))
{
_c = {url:arguments[i]};
continue;
}
if(_c == null && this.isObject(arguments[i]))
{
_c = arguments[i];
continue;
}
if(_d == null && this.isObject(arguments[i]))
{
_d = arguments[i];
continue;
}
if(_fn == null && this.isFunction(arguments[i]))
{
_fn = arguments[i];
continue;
}
}
if (_fn == null) {
_fn = void(0);
}
var _ajax = this.create('Rsd.data.Ajax', this.apply({token:Rsd.getAppToken(), appId:Rsd.getAppId()}, _c));
return _ajax.request(_d, _fn);
};
/**
*
*/
this.httpGet = function httpGet(config,callback)
{
throw new Error('Unimplemented');
};
/**
*
*/
this.httpPost = function httpPost(config,data,callback)
{
throw new Error('Unimplemented');
};
/**
* 上传文件
* @param config ajax配置项{url:'',method:'post'} 将被合并到Ajax对象上
* @param {*} files 文件数组,即 File对象数组
* @param {*} callback 回调方法
*/
this.postFiles = function postFiles(config,files,callback)
{
var _ajax = this.create('Rsd.data.File', this.apply({token:Rsd.getAppToken(),appId:Rsd.getAppId()}, config));
return _ajax.upload(files, callback);
};
/**
* 将字符串 通过文件的方式上传到服务器
* @param {*} config ajax配置项{url:'',method:'post'} 将被合并到Ajax对象上
* @param {*} content 文件内容 字符串
* @param {*} fileName 文件名
* @param {*} fileType 文件类型
* @param {*} callback 回调方法
* @returns
*/
this.postFileFromString = function postFileFromString(config,content,fileName,fileType,callback)
{
var files = [new File([new Blob([content])],fileName, {type: fileType})];
var _ajax = this.create('Rsd.data.File', this.apply({token:Rsd.getAppToken(),appId:Rsd.getAppId()}, config));
return _ajax.upload(files, callback);
};
/**
*
* @description 提交表单数据
* */
this.submitForm = function submitForm(form, callback) {
if(form && form.action)
{
var formData = new FormData(form);
var _ajax = this.create('Rsd.data.Ajax', {token:Rsd.getAppToken(),appId:Rsd.getAppId(),contentType:"application/x-www-form-urlencoded"});
return _ajax.request(formData, callback);
}
},
/**
*
* @public
* */
this.sleep = function sleep(msec) {
var start = new Date().getTime();
while (true) if (new Date().getTime() - start > msec) break;
};
/**
* 解码
* @param {*} str
* @returns
*/
this.decodeURI = this.unescape = function unescape(str)
{
if(this.isString(str))
{
return window.decodeURIComponent(str);
}
return str
};
/**
* @description escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。
* @description 该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。
* @description 提示: 使用 unescape() 方法对字符串进行解码。
* @param {*} str
*/
this.encodeURI = this.escape = function escape(str)
{
if(this.isString(str))
{
return window.encodeURIComponent(str);
}
return str
}
/**
* @public
* */
this.toJson = function toJson(str) {
//console.log(str);
if (str == null || this.getType(str) != '[object String]') {
return str;
}
if (!str || str.length == 0) {
return null;
}
var _data = null;
try
{
_data = JSON.parse(str);
} catch( ex) {
try
{
_data = window.eval('(' + str + ')');
} catch(ex1)
{
try
{
_data = window["eval"].call(window, str);
} catch (ex2) {
_data= {msg:'JSON格式化失败',data:str,success:false};
this.showHtml("JSON格式化失败", str);
}
}
}
return _data;
};
/**
* @public
* */
this.toString = function toString(obj) {
if (obj == undefined) {
return "null";
}
var r = [];
if (typeof obj == "string") {
return "\"" + obj.replace(/([\"\\])/g, "\\$1").replace(/(\n)/g, "\\n").replace(/(\r)/g, "\\r").replace(/(\t)/g, "\\t") + "\"";
}
if (typeof obj == "object") {
if (!obj.sort) {
for (var i in obj) {
if (typeof (obj[i]) == 'function') {
continue;
}
r.push("\"" + i + "\":" + this.toString(obj[i]));
}
r = "{" + r.join() + "}"
} else {
for (var i = 0; i < obj.length; i++)
r.push(this.toString(obj[i]))
r = "[" + r.join() + "]";
}
return r;
}
return obj.toString().replace(/\"\:/g, '":""');
};
/**
* @description 将字符串转化为dom节点
* @public
* */
this.toHtml = this.parseDom = function parseDom(str) {
var objE = document.createElement('div');
objE.innerHTML = str;
return objE.childNodes;
};
/**
* @public
* @description 获取对象的jsonSchema
* https://json-schema.org/understanding-json-schema/
* @param {*} json
*/
this.getJsonSchema = function getJsonSchema(data)
{
var schema = {};
var _data = data||{};
var _fn_full_common_pro = function(examples){
this.$ref = "";//通过设置id,引用其他类型的
this.dependencies = null;//属性依赖关系
this.minProperties = 0;//属性个数限制
this.maxProperties = 0,//属性个数限制
this.additionalProperties = false;//是否允许额外属性
this.enum = null;
this.default = null;
this.examples = examples;
this.allOf = [];//[schema1,schema2]满足allOf数组中的所有Json Schema。
this.anyOf = [];//[schema1,schema2]满足anyOf数组中的任意个Schema。
this.oneOf = [];//[schema1,schema2]满足且进满足oneOf数组中的一个Schema,这也是与anyOf的区别。
this.not = [];//[schema1,schema2]不严格规定Json数据应满足什么要求,它告诉Json不能满足not所对应的Schema。
};
for(var p in _data)
{
schema[p]={
$id:p,
title:'',
description:"",
};
if(schema[p] == null)
{
schema[p].type ='null';
_fn_full_common_pro.call(schema[p],[_data[p]]);
continue;
}
if(Rsd.isString(_data[p]))
{
schema[p].type ='string';
schema[p].minLength = 0;
schema[p].maxLength = 0;
schema[p].pattern = "";
schema[p].format = "";
_fn_full_common_pro.call(schema[p],[_data[p]]);
continue;
}
if(Rsd.isDate(_data[p]))
{
schema[p].type = 'date';
schema[p].format = "";
_fn_full_common_pro.call(schema[p],[_data[p]]);
continue;
}
if(Rsd.isBoolean(_data[p]))
{
schema[p].type ='boolean';
_fn_full_common_pro.call(schema[p],[_data[p]]);
continue;
}
if(Rsd.isNumber(_data[p]))
{
schema[p].type ='number';
schema[p].multipleOf = 0;//约束目标数值必须是该值的整数倍
schema[p].minimum = null;
schema[p].maximum = null;
schema[p].exclusiveMinimum = null;
schema[p].exclusiveMaximum = null;
_fn_full_common_pro.call(schema[p],[_data[p]]);
continue;
}
if(Rsd.isArray(_data[p]))
{
schema[p].type ='array';
schema[p].minItems = 0;
schema[p].maxItems = 0;
var cols = _data[p].length > 0?this.getJsonSchema(_data[p][0]):{};
schema[p].items = {type:'object',properties:cols};//统一的数组元素的Schema 复制对象,不同元素约束用数组
schema[p].additionalItems = [];//其他数组元素约束
_fn_full_common_pro.call(schema[p],_data[p]);
continue;
}
if(Rsd.isObject(_data[p]))
{
schema[p].type ='object';
schema[p].properties = this.getJsonSchema(_data[p]);
schema[p].required = [];//必填属性名称数组["name","age"]
_fn_full_common_pro.call(schema[p],[]);
continue;
}
}
return schema;
}
/**
* @public
* */
this.getType = function getType(obj) {
return Object.prototype.toString.apply(obj);
};
/**
*@public
* */
this.isEmpty = function isEmpty(obj) {
if (obj == undefined || obj == null || obj == '') {
return true;
}
if (obj instanceof Function) {
return false;
}
if (obj instanceof Array) {
return obj.length == 0
}
if (obj instanceof Date) {
return false
}
if (Rsd && Rsd.common && Rsd.common.Object && obj instanceof Rsd.common.Object) {
return false
}
if (obj instanceof HTMLElement) {
return false;
}
if ( obj instanceof Node) {
return false;
}
if (obj instanceof Object) {
return Object.keys ? Object.keys(obj).length == 0 : JSON.stringify(obj) == "{}";
}
return false;
};
/**
* @public
* */
this.isNull = function isNull(obj) {
return this.getType(obj) == '[object Null]';
};
/**
*@public
*
* */
this.isNaN = function isNaN(obj) {
if(window)
{
return window.isNaN(obj);
}
return Number.isNaN(obj);
};
/**
* */
this.isUndefined = function isUndefined(obj) {
return this.getType(obj) == '[object Undefined]';
};
/**
* @public
* */
this.isNullOrUndefined = function isNullOrUndefined(obj) {
return this.isNull(obj) || this.isUndefined(obj);
};
/**
* @public
* */
this.isBoolean = function isBoolean(obj) {
return this.getType(obj) === this.getType(true);
};
/**
* @public 是否为true
* */
this.isTrue = function isTrue(obj) {
if (this.isNullOrUndefined(obj)) {
return false;
}
if (this.isBoolean(obj)) {
return obj==true;
}
if (this.isString(obj)) {
return obj.toLowerCase() == 'true';
}
if(this.isNumber(obj))
{
new Boolean(obj) == true;
}
return new Boolean(obj) == true;
};
/**
* @public
* */
this.isString = function isString(obj) {
return this.getType(obj) === this.getType('');
};
/**
* @public
* @description 是否是数字
* */
this.isNumber = function isNumber(obj) {
return this.getType(obj) === this.getType(0) && !isNaN(Number(obj));
};
/**
* @public
* @description 是否是数字
* */
this.isDate = function isDate(obj) {
return this.getType(obj) === this.getType(new Date());
};
/**
* @public
* */
this.isFunction = function isFunction(obj) {
return this.getType(obj) == this.getType(function(){});
};
/*
*
* */
this.isArguments = function isArguments(obj) {
return this.getType(obj) == this.getType(arguments);
};
/**
* @public
* @description 是否是原生态对象,Rsd.getType(obj) == this.getType({})
* */
this.isObject = function isObject(obj) {
return this.getType(obj) == this.getType({});
};
/**
* @public
* @description 判断对象是否是数组
* @return boolean
* */
this.isArray = function isArray(obj) {
return this.getType(obj) == this.getType([]);
};
/**
* @public
* @description obj instanceof type
* @param {object} obj 对象
* @param {class} type 类型名称
* @return boolean
* */
this.isType = function isType(obj, type) {
if(this.isString(type))
{
return this.getType(obj) == type;
}
return obj instanceof type || this.getType(obj) == '[object ' + type.name + ']';
};
/**
* @public
* @description获取提示语言
* */
this.lang = function lang(name) {
var lang = Rsd.resources.lang||{};
var lang = lang[Rsd.app.lang];
var arr = name.split('.');
for (var i in arr) {
if(lang==null )
{
break;
}
lang = lang[arr[i]];
}
return lang;
};
/**
* @public
* @description getUserAgent*/
this.getUserAgent = function getUserAgent() {
return navigator.userAgent.toLowerCase();
};
/**
* @public
*@description 判断是否是移动端
* */
this.isMobile = function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
/**
*
* @public
* @description 判断是否是Chrome浏览器
* */
this.isChrome = function isChrome() {
return /\bchrome\b/.test(this.getUserAgent());
};
/**
* @public
* @description 判断是否是微信浏览器
* */
this.isWeChat = function isWeChat(){
if(this.isEmpty(this.app) || this.isEmpty(this.app.appType))
{
if(navigator && navigator.userAgent)
{
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
}
return false;
}
};
/**
* @description 判断是否是微信小程序 (this.app.appType == 'wxapp')
*/
this.isWeChatApp = function isWeChatApp(){
return this.app && this.app.appType == 'wxapp';
};
/**
* @public
* @description Gets the classname of an object or function if it can.
* @description Otherwise returns the provided default.
*
*/
this.getFunctionName = function getFunctionName(fn, defaultName) {
var nameFromToStringRegex = /^function \s?([^\s(]*)/;
var result = "";
if (typeof fn === 'function') {
try
{
result = fn.name || fn.toString().match(nameFromToStringRegex)[1];
}
catch(ex)
{
console.error("Get Function Name Fail",fn);
}
} else if (typeof fn.constructor === 'function') {
result = getFunctionName(fn.constructor, defaultName);
}
return result || defaultName;
};
/**
* @public
* @description 打印方法调用栈信息
* */
this.printCallStack = function printCallStack(text,count) {
var _count = 0;
console.log('==========='+(text||'')+'=============');
var caller = arguments.callee.caller; //当前方法的调用者
while(caller && (_count < count || !count))
{
console.log(caller);
caller = caller.caller;
_count++;
}
};
/**
* @public
* */
this.print = function print(id) {
if(this.isWeChatApp())
{
console.error('Wechat小程序环境下print方法不可用,无法打印。');
return;
}
if (arguments.length == 0) {
window.print();
return;
}
var _list = [];
var _node;
for (var i in document.body.childNodes) {
_node = document.body.childNodes[i];
if (_node instanceof Element) {
_list.push({node: _node, display: _node.style.display});
_node.style.display = 'none';
}
}
// A4 210mm* 297mm 1in=25.4mm
var _dpi = this.getDPI();
var _a4_width = _dpi.width * 210 / 25.4;
document.body.style.width = _a4_width + 'px';
alert(document.body.style.width);
var _div = document.getElementById(id);
var _temp = document.createElement('div');
_temp.innerHTML = _div.innerHTML;
document.body.appendChild(_temp);
window.print();
document.body.removeChild(_temp);
for (var i in _list) {
_list[i].node.style.display = _list[i].display;
}
return;
};
/**
* @public
* @description 复制数据到剪贴板
* */
this.copy = function copy(data) {
if(this.isWeChatApp())
{
console.error('Wechat小程序环境下copy方法不可用,无法复制数据。');
return ;
}
var currentFocus = document.activeElement;
if (window.clipboardData && window.clipboardData.setData('Text', data)) // 赋予 text 格式的数据
{
this.showPopup("复制成功!");
return;
}
var _text_for_copy = document.getElementById('rsd_text_for_copy');
if (_text_for_copy == null) {
_text_for_copy = document.createElement('textarea');
_text_for_copy.setAttribute('id', 'rsd_text_for_copy');
//_text_for_copy.style.width ='0px';
// _text_for_copy.style.height ='0px';
_text_for_copy.style.position = "absolute";
_text_for_copy.style.left = "-9999px";
_text_for_copy.style.top = "0";
document.body.appendChild(_text_for_copy);
}
_text_for_copy.textContent = data;
_text_for_copy.setSelectionRange(0, _text_for_copy.value.length);
_text_for_copy.focus();
_text_for_copy.select();
var _flag = document.execCommand != undefined;
try {
//第一始终失败
_flag = document.execCommand('copy');
//第二次成功
_flag = _flag || document.execCommand('copy');
} catch (err) {
this.error("复制数据失败", "", err);
}
if (_flag) {
this.showPopup("复制成功!");
} else {
var _d = this.create('Rsd.container.Dialog', {width: 600, height: 420, layout: 'fit', title: '复制数据'});
var _t = this.create('Rsd.form.TextArea', {height: 350, value: data, margin: '5 5 5 5'});
_d.add(_t);
_d.showDialog();
_t.focus();
_t.select();
}
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
document.body.removeChild(_text_for_copy);
return;
};
/**
* @public
* @description 显示等待窗口
* */
this.showWaiting = function showWaiting(key, parent,msg) {
var _key = key || (parent && parent.id) || Math.random();
if (this.isEmpty(_key)) {
throw new Erorr('key is null. Rsd.showWaiting = function showWaiting(key, parent,msg)');
}
var me = Rsd || this;
setTimeout(function (parent) {
me.__waitings = me.__waitings || {};
if (!me.__waitings[_key]) {
me.__waitings[_key] = me.create('Rsd.control.WaitingBox', {
key:_key,
message: msg|| me.lang('common.waitingText'),
border: false
});
}
me.__waitings[_key].showDialog(document.body);
}, 0);
return _key;
};
/**
* @public
@description 关闭等待窗口
* */
this.closeWaiting = function closeWaiting(key, delay) {
if (this.isEmpty(key)) {
throw new Erorr('key is null. Rsd.closeWaiting=function closeWaiting(key, delay)');
}
var me = Rsd || this;
setTimeout(function () {
if (me.__waitings && me.__waitings[key]) {
me.__waitings[key].close();
delete me.__waitings[key];
}
}, (delay == undefined || delay == null) ? 500 : delay);
};
/**
* @description 使用window.open 打开新的url
* @public
* */
this.showModalDialog = function showModalDialog(url, title, height, width, data) {
if (window.showModalDialog) {
window.showModalDialog(url);
}
else {
var _h = height || 400;
var _w = width || 500;
var _params = 'height=' + _h + ', width=' + _w + ', top=' + (((window.screen.height - _h) / 2) - 50) + ',left=' + ((window.screen.width - _w) / 2) + ',toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no';
window.open(url, title, _params);
}
};
/**
* @public
* */
this.get = function get(id) {
return this.objects[id];
};
/**
* @public
* */
this.getDom = function getDom(id) {
if(this.isWeChatApp())
{
console.error('小程序getDom方法不可用,无法获取dom对象。');
return {};
}
return document.getElementById(id);
};
/*
*
* */
this.getFileExt = function getFileExt(url) {
var file = url;
var FileExt = file.replace(/.+\./, ""); //正则表达式获取后缀
return FileExt;
};
/**
* */
this.getFileName = function getFileName(url) {
var file = url;
var pos = file.lastIndexOf('/');
file = file.substring(pos + 1);
pos = file.lastIndexOf('.');
return file.substring(0, pos);
};
/**
* @public
* @desc 映射成当前网站网站目录
* */
this.mappingUrl = function mappingUrl(url) {
if (this.isNullOrUndefined(this.__homePath )) {
this.__homePath = window.location.protocol + '//' + window.location.host + '/' + window.location.pathname + '/';
}
return this.__homePath + url;
};
/*
* RedjsHost是否是代理服务器
* */
this.isAgentHost = function isAgentHost( ) {
return this.__isAgentHost || false;
};
/**
*@public
*@description 获取redjs框架服务器地址,支持将框架部署在远程服务器上
* */
this.getRedjsHost = function getRedjsHost() {
//debugger;
if (this.isEmpty(this.__jsHomeHost )) {
if(this.isWeChatApp())
{
console.error('Wechat小程序环境下getRedjsHost方法不可用,默认返回:https://js.redmicro.cn。');
return 'https://js.redmicro.cn';
}
var result = ""
var e = Error('redjs');
if (e.fileName) {//firefox
result = e.fileName;
} else if (e.sourceURL) {//safari
result = e.sourceURL;
} else if (e.stacktrace) {//opera
var m = e.stacktrace.match(/\(\) in\s+(.*?\:\/\/\S+)/m);
if (m && m[1])
result = m[1];
}
if (!result) {//IE与chrome
var scripts = document.getElementsByTagName("script");
var reg = /rsd([.-]\d)*\.js(\W|$)/i
for (var i = 0, n = scripts.length; i < n; i++) {
var src = !!document.querySelector ? scripts[i].src : scripts[i].getAttribute("src", 4);
if (src && reg.test(src)) {
result = src
break;
}
}
}
var _path = result.substr(0, result.lastIndexOf('/') + 1);
var _d = _path.split('/');
this.__jsHomeHost = _path.replace(_d[_d.length - 1], '');
}
if(window.location.protocol=='https:' && this.__jsHomeHost.startsWith('http://'))
{
this.__jsHomeHost = 'https://' + this.__jsHomeHost.substring(7);
}
if(window.location.protocol=='http:' && this.__jsHomeHost.startsWith('https://'))
{
//this.__jsHomeHost = 'http://' + this.__jsHomeHost.substring(8);
}
return this.__jsHomeHost;
};
/**
* 获取完整的redjs框架地址
* isAgentHost:true 表示jsHomePath指向的服务期是否代理服务器,代理服务器的求情格式为jsHomePath/base64(path),需要在代理服务上 先解析path内容
* isAgentHost:false 表示正常结构
*/
this.getRedjsUrl = function getRedjs(url) {
var _url = url;
if(_url.startWith('/'))
{
_url = _url.substr(1);
}
if(this.isAgentHost())
{
return this.getRedjsHost() + this.utf8ToBase64(_url);
}
else
{
return this.getRedjsHost() + _url;
}
}
/**
*@public
*@description重定向
* */
this.redirect = function redirect(url) {
window.location.href = url;
};
/**
* @public
* @description 获取url参数
* */
this.getUrlParam = function getUrlParam(url, name) {
var _url = '';
var _name = name;
if (arguments.length == 1) {
_url = window.location.search.substr(1);
_name = arguments[0];
}
if (arguments.length > 1) {
var _list = (url || '?').split('?');
_url = _list[_list.length - 1];
_name = name;
}
var reg = new RegExp("(^|&)" + _name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = _url.match(reg); //匹配目标参数
if (r != null) return unescape(r[2]);
return null; //返回参数值
};
/**
*
*@public
*@description 设置url参数
* */
this.setUrlParam = function setUrlParam(url,name,value) {
var _url = url || (window.location.protocol + '//' + window.location.host + '/' + window.location.pathname + '/');
var _params = {};
if (arguments.length == 2 && this.isObject(arguments[1])) {
_params = arguments[1];
}
if (arguments.length == 3) {
if (this.getUrlParam(name) == value) {
return url;
}
else
{
_params[name] = value;
}
}
var currentUrl = _url.split('#')[0];
for (var i in _params) {
var _name = i;
var _value = _params[i];
if (/\?/g.test(currentUrl)) {
var exp = new RegExp(_name + '[%20]{0,100}=[%20]{0,100}[-\\w]{0,100}');
if (exp.test(currentUrl)) {
currentUrl = currentUrl.replace(exp, _name + "=" + _value);
} else {
currentUrl += "&" + _name + "=" + _value;
}
} else {
currentUrl += "?" + _name + "=" + _value;
}
}
if (_url.split('#')[1]) {
currentUrl = currentUrl + '#' + _url.split('#')[1];
}
return currentUrl;
};
/**
*@public
* */
this.getByteLength = function getByteLength(val) {
var len = 0;
for (var i = 0; i < val.length; i++) {
if (val[i].match(/[^x00-xff]/ig) != null) //全角
len += 2;
else
len += 1;
}
;
return len;
};
/**
* @public
* @description 调用方法执行
* @param {Rsd.common.Object} caller,
* @param {function|string} fn,
* @param {array} args []
* */
this.callFunction = function callFunction(caller, fn, args) {
var _caller = null;
var _fn = null;
var _args = null;
for(var i=0;i< arguments.length;i++)
{
if (this.isFunction(arguments[i]) || this.isString(arguments[i])) {
_fn = arguments[i];
continue;
}
if (Rsd.common && Rsd.common.Object && arguments[i] instanceof Rsd.common.Object) {
_caller = arguments[i];
continue;
}
if (this.isArray(arguments[i]) ) {
_args = arguments[i];
continue;
}
if(_args==null && this.isArguments(arguments[i]))
{
var _args = Array.prototype.slice.call(arguments[i]);
continue;
}
}
if (this.isFunction(_fn)) {
return _fn.apply(_caller || window.Rsd, _args||[]);
}
if (this.isString(_fn)) {
if (!(_caller instanceof Rsd.common.Object)) {
this.error('argument caller is not instanceof Rsd.common.Object,when call function callFunction(caller,fn,args).');
return true;
}
return _caller.funApplyByIOC(_fn, _args||[]);
}
return null;
};
/**
@public
@description 获取字符宽度,像素值
@param val:文本,
@param size:单个英文字符文本宽度(像素)
@return 文本宽度
@type Number
* */
this.getStringWidth = function getStringWidth(container, str) {
var span = document.createElement("span");
var _parent = container || document.body;
_parent.appendChild(span);
span.style.visibility = "hidden";
span.style.whiteSpace = "nowrap";
span.innerText = str;
var _width = span.offsetWidth;
_parent.removeChild(span);
return _width;
};
/**
* @public
* @description 货币格式化,不做四舍五入处理
* @param {number} num 金额
* @param {string} currency 货币符号 £(英镑) ¥(人民币,日元) €(欧元) $(美元)
* @return string
* */
this.formatCurrency = function formatCurrency(num, currency) {
if (num == undefined || num == null) {
return "";
}
num = num.toFixed(2);
//num = this.toString(num);
var str = (currency || '') + num.split('').reverse().join('').replace(/(\d{3}(?=\d)(?!\d+\.|$))/g, '$1,').split('').reverse().join('');
return str;
};
/**
* @public
* @description 金额小写转大写
* */
this.formatCurrencyCN = function formatCurrencyCN(num) {
var fraction = ['角', '分'];
var digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
var unit = [ ['元', '万', '亿'], ['', '拾', '佰', '仟'] ];
var head = num < 0? '欠': '';
num = Math.abs(num);
var s = '';
for (var i = 0; i < fraction.length; i++)
{
s += (digit[Math.floor(num * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
}
s = s || '整';
num = Math.floor(num);
for (var i = 0; i < unit[0].length && num > 0; i++)
{
var p = '';
for (var j = 0; j < unit[1].length && num > 0; j++)
{
p = digit[num % 10] + unit[1][j] + p;
num = Math.floor(num / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
}
return head + s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整');
};
/**
* @public
* @description 时间转化
* @param {Number|String} timestamp
* @param {string} [format] 格式:yyyy-MM-dd|yyyy-MM-dd hh:mm:ss|yyyy-MM-dd hh:mm:ss S
* */
this.formatTimestamp = function formatTimestamp(timestamp, format) {
var _s = timestamp;
if (this.isString(_s)) {
_s = Number(_s);
}
if(_s>0)
{
while(_s.toString().length < 13)
{
_s = _s*10;
}
}
if (this.isNumber(_s)) {
return new Date(_s).format(format || 'yyyy-MM-dd hh:mm:ss');
}
return timestamp;
};
/**
* @public
* @description 数字格式化
* @param {Number|String} value
* @param {Number} precision
* */
this.formatNumber = function formatNumber(value, precision) {
var _n = Number(value);
if (isNaN(_n)) {
return 0;
}
return _n.toFixed(precision || 0);
};
/**
* @public
* @description 格式化json
* @param {string|object} json
* @param {Function|String|Number} [replacer]
* @param {Number|String} [space]
* */
this.formatJson = function formatJson(json, replacer, space) {
return JSON.stringify(json, replacer || null, space || 4);
};
/**
* @public
* @description 检测浏览器及其版本
* */
this.detectNavigator = function detectNavigator() {
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/msie ([\d.]+)/)) ? this.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? this.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? this.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? this.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? this.safari = s[1] : 0;
//以下进行测试
if (this.ie) return ('IE: ' + this.ie);
if (this.firefox) return ('Firefox: ' + this.firefox);
if (this.chrome) return ('Chrome: ' + this.chrome);
if (this.opera) return ('Opera: ' + this.opera);
if (this.safari) return ('Safari: ' + this.safari);
};
/**
* @public
@description 检查操作系统
* */
this.detectOS = function detectOS() {
var sUserAgent = navigator.userAgent;
var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel");
if (isMac) return "Mac";
var isUnix = (navigator.platform == "X11") && !isWin && !isMac;
if (isUnix) return "Unix";
var isLinux = (String(navigator.platform).indexOf("Linux") > -1);
if (isLinux) return "Linux";
if (isWin) {
var isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1;
if (isWin2K) return "Win2000";
var isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1;
if (isWinXP) return "WinXP";
var isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1;
if (isWin2003) return "Win2003";
var isWinVista = sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1;
if (isWinVista) return "WinVista";
var isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1;
if (isWin7) return "Win7";
}
return "other";
};
/**
*@public
* @description 数组拼接
* arr1,arr2.... arr n
* */
this.arrayConcat = function arrayConcat(arr1, arr2) {
var _arr = [];
for (var i in arguments) {
if (this.isArray(arguments[i])) {
Array.prototype.push.apply(_arr, arguments[i]);
}
}
return _arr;
};
/**
* @description 定义枚举类型
* url:'http://hermes.redmicro.cn/dev/getenum?enumtype=' + enumName
*
*/
this.defineEnum = function defineEnum(url,enumName,valueMember)
{
if (!Rsd.classes[enumName]) {
Rsd.httpRequest({url:url ,async:false},function(data){
if(!Rsd.isEmpty(data.data))
{
Rsd.define(data.data.name,{
extend:'Rsd.data.Enum',
"valueMember": valueMember||"Value",
"codeMember": "Code",
"textMember": "Text",
"colorMember":"Color",
items:data.data.items,
constructor:function constructor()
{
}
});
_enum = Rsd.widget(enumName,{});
}else
{
Rsd.warn('类型:' + enumName + '不存在。');
}
});
}
},
/**
*
* @param {*} url 枚举数据获取地址
* url:'http://hermes.redmicro.cn/dev/getenumlist'
*/
this.defineEnums = function defineEnums(url,method){
this.httpRequest({url:url,method:method||'GET' },function(data){
if(data.success)
{
var list = data.data;
for(var i in list)
{
var _enum = list[i];
if(_enum == null )
{
continue;
}
var _typeName = _enum.typeName||_enum.TypeName
if(Rsd.isEmpty(_typeName))
{
console.error('枚举信息错误:',_enum);
continue;
}
if(Rsd.classes && Rsd.classes[_typeName])
{
continue;
}
try
{
Rsd.define(_typeName,{
extend:'Rsd.data.Enum',
"valueMember": "Value",
"codeMember": "Code",
"textMember": "Text",
items:_enum.Items,
constructor:function constructor()
{
}
});
}
catch(err)
{
console.error(err);
}
}
}
});
};
/**
* @description 为dom 附加一个按钮
* @param {*} targetDom
* @param {*} text
* @param {*} handler function(tpl,dataSource);
* @param {*} tip 文字提示
*/
this.patchButton = function patchButton(targetDom,text,handler,tip)
{
var _fn = function(dom)
{
dom.style.border = "1px red dotted";
dom.style.boxSizing = "border-box";
var id = dom.getAttribute('rsdbtn');
var _btn = null;
if(id)
{
_btn = document.getElementById(id);
}
else
{
id = Date.now();
_btn = document.createElementNS("http://www.w3.org/2000/svg",'svg');
_btn.setAttribute("id",id);
_btn.style.color = "red";
_btn.style.backgroundColor="#c34b4b54";
_btn.style.position = "absolute";
_btn.style.width = "56px";
_btn.style.height = "26px";
_btn.style.zIndex = 9999;
_btn.style.fontSize = "80%";
_btn.style.cursor = "pointer";
//_btn.style.transform = "translate(-7px,-4px)";
_btn.setAttribute("viewBox","-5 -5 46 2");
dom.appendChild(_btn);
dom.setAttribute('rsdbtn',id);
}
var _txt = document.createElementNS("http://www.w3.org/2000/svg", "text");
_txt.textContent = text||'未设置';
//_txt.setAttributeNS(null, "width","55px");
//_txt.setAttributeNS(null, "height","25px");
while (_btn.lastChild) {
_btn.removeChild(_btn.lastChild);
}
_btn.appendChild(_txt);
if(tip)
{
var _title = document.createElementNS("http://www.w3.org/2000/svg",'title');
_title.textContent = tip;
_btn.appendChild(_title);
}
_btn.onclick = function(){
if(handler)
{
var list = [];
for(var i=0;i < this.parentNode.children.length;i++)
{
var item = this.parentNode.children[i];
if(item.id == id)
{
continue;
}
list.push(item);
}
var parent = this.parentNode;
var tpl = parent.getAttribute('rsd-tpl');
//数据源名称
var ds = parent.getAttribute('rsd-ds');
//从app.data中提取数据,app.data在页面数据加载时赋值
handler.call(parent,tpl,Rsd.app.data[ds]||ds);
}
else
{
alert(' not set handler value ');
}
};
};
if(Rsd.isString(targetDom))
{
var list = Rsd.select(targetDom);
list.forEach(_fn);
return list.length;
}
if(targetDom instanceof Node)
{
var dom = targetDom;
dom.style.border = "1px red dotted";
dom.style.boxSizing = "border-box";
_fn(dom);
return 1;
}
console.error( "不支持的dom对象", targetDom);
return 0;
}
/**
*
* @param {*} checked
* @param {*} readonly
* @returns
*/
this.checkbox = function checkbox(checked,readonly)
{
var chk = document.createElement('input');
chk.setAttribute('type','checkbox');
chk.setAttribute('readonly',readonly);
chk.setAttribute('disabled',readonly);
chk.cheched = checked;
return chk;
};
/**
* @description 生成标签
* @param {object} style 文本颜色或样式对象{color:'red'}
* @param {string} tip tip
* */
this.label = function label(text, style,tip) {
var _lbl = document.createElement('label');
_lbl.classList.add('x-text-label');
_lbl.innerHTML = text;
_lbl.onmouseenter = function()
{
var id = "del_"+Date.now();
var _del = document.createElementNS("http://www.w3.org/2000/svg",'svg');
_del.setAttribute("id",id);
_del.style.color = "red";
//_del.style.backgroundColor="#ffffff";
_del.style.position = "absolute";
_del.style.width = "14px";
_del.style.height = "14px";
_del.style.transform = "translate(-7px,-4px)";
_del.setAttribute("viewBox","0 0 1024 1024");
var _path = document.createElementNS("http://www.w3.org/2000/svg", "path");
var _d = "M511.232 438.8352L112.9984 40.6016A51.2 51.2 0 0 0 40.6016 112.9984L438.784 511.232 40.6016 909.4656a51.2 51.2 0 1 0 72.3968 72.448l398.2336-398.2848 398.2336 398.2848a51.2 51.2 0 1 0 72.448-72.448l-398.2848-398.2336 398.2848-398.2336A51.2 51.2 0 0 0 909.4656 40.6016L511.232 438.784z";
_path.setAttributeNS(null, "d", _d);
_path.setAttributeNS(null, "fill", 'red');
_del.appendChild(_path);
var _title = document.createElementNS("http://www.w3.org/2000/svg",'title');
_title.textContent = "点击删除该标签";
_del.appendChild(_title);
_del.onclick = function(){
alert('delete ');
};
this.appendChild(_del);
this.setAttribute("for",id);
}
_lbl.onmouseleave = function()
{
var id = this.getAttribute("for");
var _del = document.getElementById(id);
if(_del)
{
_del.parentNode.removeChild(_del);
}
}
if(Rsd.isString(tip))
{
_lbl.title = tip;
}
if(this.isObject(style))
{
this.setElStyle(_lbl,style);
}
if(this.isString(style))
{
_lbl.style.backgroundColor = style;
_lbl.style.borderColor = style;
}
return _lbl;
};
/**
* @public
* @description 生成text HtmlElement
* @param {string} text 文本信息
* @param {string} style 样式对象{color:'red'}
* @param {string} tip tip
* */
this.text = function text(text, style,tip) {
if(Rsd.isNumber(arguments[1]))
{
console.error('最大宽度应使用样式属性{maxWidth:'+arguments[1]+'px}控制')
style = null;
}
if(Rsd.isString(arguments[1]))
{
console.error('颜色应使用样式属性{color:'+arguments[1]+'}控制');
style = null;
}
var _t = text || '';
var _style = style || {overflow:'hidden',color:'grey'};
var _tip = tip || _t;
var txt = document.createElement('span');
this.setElStyle(txt,_style);
txt.appendChild(document.createTextNode(_t))
if(Rsd.isString(_tip))
{
txt.title = _tip;
}
return txt;
};
/**
* @description 将枚举值,转化为对应的文字输出
* @param {*} enumName
* @param {*} value
* @param {*} style 样式对象{color:'red'}
* @returns
*/
this.enumText = function enumText(enumName,value,style)
{
var _value = value;
var _txt = Rsd.isEmpty(_value)?"":_value;
var _style = style;
if (!Rsd.xtypes[enumName])
{
Rsd.warn('类型:' + enumName + '不存在,请先定义该类型。');
return Rsd.isEmpty(_value)?"":_value;
}
else
{
_enum = Rsd.widget(enumName,{});
var _enumItem = _enum.getItem(_value);
if(_enumItem)
{
_txt = _enumItem.text;
_style = _style || {color:_enumItem.color};
}
}
return Rsd.text(_txt,_style)
};
/**
* @description 将枚举值,转化为对应的文字标签输出
* @param {*} enumName
* @param {*} value
* @param {*} style 样式对象{color:'red'}
* @returns
*/
this.enumLabel = function enumLabel(enumName,value,style)
{
var _value = value;
var _txt = Rsd.isEmpty(_value)?"":_value;
var _style = style;
if (!Rsd.xtypes[enumName])
{
Rsd.warn('类型:' + enumName + '不存在,请先定义该类型。');
}
else
{
_enum = Rsd.widget(enumName,{});
var _enumItem = _enum.getItem(_value);
if(_enumItem)
{
_txt = _enumItem.text;
_style = _style || {color:_enumItem.color};
}
}
return Rsd.label(_txt,_style);
};
/**
*
* @param {*} text
* @param {*} width
* @param {*} color 样式对象{color:'red'}
* @param {*} tip
*/
this.nobr = function nobr(text,style,tip) {
if(Rsd.isNumber(arguments[1]))
{
console.error('最大宽度应使用样式属性{maxWidth:'+arguments[1]+'px}控制')
style = null;
}
if(Rsd.isString(arguments[1]))
{
console.error('颜色应使用样式属性{color:'+arguments[1]+'}控制');
style = null;
}
var _t = text || '';
var _style = style || {overflow:'hidden',color:'grey'};
var _tip = tip || _t;
var nobr = document.createElement('span');
nobr.appendChild(document.createTextNode(_t));
this.setElStyle(nobr,_style);
if(Rsd.isString(_tip))
{
nobr.title = _tip;
}
return nobr;
};
/**
* @public
* @description 创建圆dom对象 function circle(size, color)
* */
this.circle = function circle(size, color,text) {
var _s = size || 10;
var _c = color || 'green';
return this.parseDom('<div class="x-icon_circle" style="text-align:center;width: ' + _s + 'px;height: ' + _s + 'px;line-height:'+ _s +'px;color:#ffffff;background-color: ' + _c + ';">'+(text||'')+'</div>')[0];
};
/**
* @public
* @description 创建空格dom对象
* */
this.blankspan = function blankspan(count,style) {
var _c = count || 1;
var _s = '';
for (var i = 0; i < _c; i++) {
_s = _s + ' ';
}
var span = this.parseDom('<span>' + _s + '</span>')[0];
this.setElStyle(span,style||{});
return span;
};
/**
* @public
* @description 创建换行dom对象
* */
this.newLine = function newLine() {
return this.parseDom('<br>')[0]
};
/**
* @public
* @description 创建button <input type='button'> 对象,function (text,fn,caller,args)
* @param {string|object} text 文字信息
* @param {string|function} fn 点击事件函数
* @param {object} caller 调用对象
* @param {array} args fn参数
* @param {object} style 样式对象{text:'',backroud}
* */
this.button = function button(text, fn, caller, args,style,tip) {
var me = Rsd||this;
var btn = document.createElement('input');
btn.type = 'button';
btn.classList.add('x-text-button');
btn.value = text;
if(Rsd.isString(tip))
{
btn.title = tip;
}
if(style && style.backgroundColor)
{
style.borderColor = style.borderColor||style.backgroundColor;
}
this.setElStyle(btn,style||{});
if (me.isEmpty(fn)) {
btn.title = "暂不可操作。";
btn.classList.add("x-control-disabled");
}
else {
btn.onclick = function (e) {
me.callFunction(caller, fn, Rsd.arrayConcat([e],args||[]));
};
}
return btn;
};
/**
* @description 样式简单 无背景的 <a>标签
* @param {*} text
* @param {*} fn
* @param {*} caller
* @param {*} args
* @param {*} style
* @param {*} tip
*/
this.link = function link(text, fn, caller, args,style,tip) {
var me = Rsd||this;
var btn = document.createElement('a');
btn.classList.add('x-text-link');
btn.href = 'javascript:void(0);';
btn.innerHTML = text;
if(Rsd.isString(tip))
{
btn.title = tip;
}
this.setElStyle(btn,style||{});
if (me.isEmpty(fn)) {
btn.title = "暂不可操作。";
btn.classList.add("x-control-disabled");
}
else {
btn.onclick = function (e) {
me.callFunction(caller, fn, Rsd.arrayConcat([e],args||[]));
};
}
return btn;
};
/**
* @description 空白透明PNG 图片base64编码
* */
this.emptyImage = function emptyImage() {
return 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
};
/**
* @public
* @description 创建mailTo dom对象
* */
this.mailTo = function mailTo() {
console.error('暂未实现。')
return [];
};
/**
* @public
* @description md5加密
* */
this.md5 = function md5(str) {
if ($.md5) {
return $.md5(str);
}
else {
this.error('$.md5(jquery md5插件) 加密插件不存在。')
}
return null;
};
/**
* @public
* @description 是否包含属性 name ,含其原型的属性。
* */
this.hasProperty = function hasProperty(obj, name) {
if(obj==null || obj== undefined)
{
return false;
}
if (obj instanceof Object) {
return name in obj;
}
if(obj.hasOwnProperty)
{
return obj.hasOwnProperty(name);
}
return false;
};
/**
*
* @desc 清空dom对象
* */
this.empty = function empty(ctrl) {
if (this.isType(ctrl, Element)) {
if (ctrl.childNodes && ctrl.childNodes.forEach) {
ctrl.childNodes.forEach(function (node) {
ctrl.removeChild(node);
});
return;
}
ctrl.innerHTML = null;
}
};
/**
*@description 查询dom
* @param {dom} dom 默认为document
* @param {string} selector
* */
this.select = function select(dom,selector)
{
var _doc = dom;
if(Rsd && Rsd.common && Rsd.common.ComponentX)
{
if(_doc instanceof Rsd.common.ComponentX)
{
_doc = _doc.dom;
}
}
var _selector = selector;
if(arguments.length == 1)
{
_selector = arguments[0];
_doc = document;
}
//console.debug(_selector);
return Array.from(_doc.querySelectorAll(_selector));
};
/**
* @description 为Dom绑定事件
* @param {*} selector
* @param {*} eventName
* @param {*} fn
*/
this.bindEvent = function(selector,eventName,fn)
{
var list = this.select(selector);
for(var i in list)
{
list[i][eventName] = fn;
}
};
/**
* @decription 获取各主机Controller
* @description 设置dom 元素style属性值
* */
this.setElStyle=function setElStyle(el,style,sizeUnit)
{
var _dom = el;
var _style = style||{};
//
if (_dom instanceof Element||_dom instanceof Node) {
var _sizeUnit = this.isEmpty(sizeUnit) ? 'px':sizeUnit;
var _list = [
'width',
'height',
'maxWidth',
'maxHeight',
'minWidth',
'minHeight',
'lineHeight',
'top',
'right',
'bottom',
'left',
'marginTop',
'marginRight',
'marginBottom',
'marginLeft'
];
var _p = null;
for (var i in _list) {
_p = _list[i];
if (this.isNullOrUndefined(_style[_p])) {
continue;
}
if (this.isString(_style[_p])) {
if(_style[_p]=='auto')
{
continue;
}
if (_style[_p].endWith('%') || _style[_p].endWith('px') || _style[_p].endWith('rem') || _style[_p].endWith('em')) {
continue;
}
_style[_p] = parseFloat(_style[_p]) + _sizeUnit;
continue;
}
if (this.isNumber(_style[_p])) {
_style[_p] = _style[_p] + _sizeUnit;
continue;
}
}
if (_dom.style.setProperty) {
for (var p in _style) {
if (/^[0-9a-z]*$/.test(p)) {
_dom.style.setProperty(p, _style[p], 'important');
}
else
{
//大写字母替换为小写,并在前插入 -
var _l = p.match(/[A-Z]/g);
var _new_p = p;
for (var i in _l) {
_new_p = _new_p.replaceByRegExp(_l[i], '-' + _l[i].toLowerCase());
}
_dom.style.setProperty(_new_p, _style[p], 'important');
}
}
} else {
this.apply(_dom.style, _style);
}
}
};
/**
* @description 加载本地配置文件,将配置项合并到service对象中
* @param localConfig 本地服务配置文件 [{group:},{}]
*/
this.loadRouteTable = function loadRouteTable(localConfig,callback)
{
var me = this;
//加载所有host 并 配置合并本地配置
var _fnLoadAll = function (configList) {
var _configMap = {};
//console.log(configList);
for(var i in configList)
{
_configMap[configList[i].group.toLowerCase()] = configList[i];
}
//console.log(_configMap);
var _hosts = Rsd.app.apiHosts;
for(var i in _hosts)
{
me.loadServices(_hosts[i],_configMap,callback);
}
}
//config 是配置文件
if(this.isString(localConfig))
{
//获取controller的本地配置
var configStore = Rsd.create('Rsd.data.Store',{
proxy: {
url:localConfig,
method:'get'
}
});
configStore.load({},function (groupList) {
_fnLoadAll(groupList);
});
return;
}
//config 是配置数组
if(this.isArray(localConfig)||this.isEmpty(localConfig))
{
_fnLoadAll(localConfig||[]);
return;
}
},
/**
{
text:'电商服务',
name:'',
url:'http://hermes.redmicro.cn/',
index:'dev/index',
isLoaded:false//已加载
controllers:[{name:'',path:'',GetDescription:''},{},{}],
routeList:'/dev/getroutetable',//服务端路由表接口
useSSL:false
},
* @decription 将一个apihost加载到本地
* @param host 一个独立API项目 {name:'',text:'',url:'',useSSL:true,controllers:[]}
* @param config 配置文件
* @param callback
*/
this.loadServices = function loadServices(host,config,callback)
{
//console.log(host);
//console.log(config);
var _config = config ||{};
//获取主机的controlls 的api
var _fnLoad = function(host,data)
{
//console.log(data);
//controller list
var _controllers = [];
for(var i in data.data)
{
//合并本地配置 => controller 级别 配置项
var group = (data.data[i].Name||data.data[i].name).toLowerCase();
var _url = host.url + (data.data[i].Path||data.data[i].path).toLowerCase().trim('/') + "/" + ((data.data[i].GetDescription||data.data[i].GetDescription||'GetDes').trim('/'));
if(!Rsd.isEmpty(host.name))
{
group = host.name + "." + group;
}
var gConfig = _config[group]||{};
//console.log(gConfig);
//初始化contoller
var _ctrl = {
"group":group,
"url":_url,
"useSSL":host.useSSL,
"errorHandler": gConfig.errorHandler || "errorHandler",
"failureHandler": gConfig.failureHandler || "failureHandler",
"successHandler": gConfig.emptyHandler || "emptyHandler",
"api": {}
};
_controllers.push(_ctrl);
Rsd.services[_ctrl.group]=_ctrl;
}
var _data = {success:true,msg:'',data:{total:0,pagecount:1,pageindex:0,pagesize:1000,modeltype:'',rows:[]}};
var _fnConfig = function (__data) {
for(var i in __data.data)
{
var key = this.group + '.' + __data.data[i].MethodName.toLowerCase();
var apiService = Rsd.app.getService(key);
apiService.parent = Rsd.app;
apiService.data = __data.data[i];
_data.data.total++;
_data.data.rows.push(apiService);
}
var gConfig = _config[this.group]||{};
//合并本地配置 => api级别配置项
if(!Rsd.isEmpty(gConfig))
{
//console.log(gConfig);
//api 指定配置
for(var i in gConfig.api)
{
var _c = gConfig.api[i];//特定 api的配置项
var key = this.group + '.' + gConfig.api[i].name.toLowerCase();//console.log(key);
var apiService = Rsd.app.getService(key);
if(apiService)
{
apiService.errorHandler =_c.errorHandler || apiService.errorHandler;
apiService.failureHandler = _c.failureHandler || apiService.failureHandler;
apiService.successHandler = _c.successHandler || apiService.successHandler;
apiService.progressHandler= _c.progressHandler||apiService.progressHandler;
apiService.ajaxType =_c.ajaxType ||apiService.ajaxType;
apiService.local={method:'get',url:_c.localUrl};
}
}
}
}
for(var i in _controllers)
{
Rsd.loadServiceApi(_controllers[i],_fnConfig);
}
Rsd.callFunction(Rsd.app, callback, [_data]);
};
if(host.isLoaded)
{
return;
}
if(Rsd.isEmpty(host.url))
{
console.error("apihost未设置url属性。")
return;
}
Rsd.services = Rsd.services || {};
//加载策略1:根据路由表返回加载
if(!Rsd.isEmpty(host.routeList))
{
var _services = Rsd.create('Rsd.data.Store',{
host:host,
proxy: {
url: host.url + host.routeList,
method:'get'
}
});
_services.load({},function(data){
Rsd.callFunction(Rsd.app, _fnLoad, [this.host,data]);
});
return ;
}
//加载策略2:指定要加的controller
if(!Rsd.isEmpty(host.controllers))
{
//适配返回数据
Rsd.callFunction(Rsd.app, _fnLoad, [host,{data:host.controllers}]);
return ;
}
//提示错误:未设置要加载的数据
if(Rsd.isEmpty(host.routeList) && Rsd.isEmpty(host.controllers))
{
console.error("apihost未设置routeList属性 ,且未设置controllers属性。")
return;
}
};
/**
* @description 加载单个controller,获取controller拥有的API(方法)
* @param {*} controller {group:'',url:'',useSSL:false,errorHandler:'',failureHandler:'',successHandler:'',api:{}} 获取api描述地址URL
* @param {*} callback
*/
this.loadServiceApi = function loadServiceApi(controller,callback) {
controller.isLoading = true;
//console.log(controller);
var _group = controller.group.toLowerCase();
var _ssl = controller.useSSL;
//console.log('load =>' + _group);
Rsd.httpRequest({ url: controller.url,method:'GET'}, {}, function(data) {
if(data.success===false)
{
console.error('获取API描述(' + controller.url + ' )失败:',data);
return;
}
var list = data.data || data||[];
for(var j in list)
{
var item = list[j];
if(!Rsd.isString(item.Url))
{
console.error('属性Url的值('+item.Url+')无效',item);
item.Url = '';
}
if( _ssl && item.Url.startWith('http://'))
{
item.Url = 'https://' + item.Url.substr(7);
}
var config = {
key:_group + '.' + item.MethodName.toLowerCase(),
name:item.MethodName.toLowerCase(),
group:_group,
text:item.Description,
parent : Rsd.app,
errorHandler :controller.errorHandler||'',
failureHandler : controller.failureHandler||'',
successHandler : controller.successHandler||'',
progressHandler: controller.progressHandler||'',
ajaxType:item.ajaxType ||'ajax',
local:{method:'get',url:''},
server:{
url:item.Url||'',
method:item.Method||'POST',
contentType:item.ContentType||'application/x-www-form-urlencoded',
//dataType: 'json',
async:true
}
}
if(Rsd.services[_group])
{
Rsd.services[_group].api[item.MethodName.toLowerCase()] = new Rsd.data.Service(config);
}
else
{
console.error(_group + '不存在');
}
}
controller.isLoading = false;
//console.log('loaded =>' + _group);
if(Rsd.isFunction(callback))
{
callback.call(controller,data);
}
},'加载服务');
};
/**
*
* @description 请求API服务,接口数据加载中时,自动等待。
* @param name
* @param data
* @param callback 请求成功(status==200)回调方法,且优先执行,执行返回true时,后续方法(success,failure)继续执行,返回false时,后续方法终止
* @param msg
* @param timeout 毫秒
* */
this.requestService = function requestService(name, data, callback,msg,timeout) {
if(Rsd.isEmpty(name))
{
throw new Error('param [name] is null when call Rsd.requestService method.');
}
var _name = name.toLowerCase();
var _group = _name.substr(0,_name.lastIndexOf('.'));
var _method = _name.substr(_name.lastIndexOf('.')+1);
//组
var serviceGroup = Rsd.services[_group];
if(Rsd.isEmpty(serviceGroup))
{
var _error = '服务['+ name +']不存在,请先注册';
Rsd.warn(_group);
console.error(_error);
return;
}
var _fn = function () {
var apiService = serviceGroup.api[_method];
if(Rsd.isEmpty(apiService))
{
var _error = '服务['+ name +']不存在,请确认';
Rsd.warn(_method);
console.error(_error);
return;
}
apiService.request(data,callback,msg,timeout);
}
var _timer = 0;
var _request = function () {
if(serviceGroup.isLoading)
{
//如果正在加载服务 延时200毫秒 最多延时5次
_timer++;
if(_timer>10)
{
Rsd.warn('系统繁忙,请稍后再试');
return;
}
console.log(_timer + '- call '+_name + ' => controller ' + serviceGroup.group + ' is loading.' );
setTimeout(_request,200*_timer);
}
else
{
_fn();
}
}
if(Rsd.isEmpty(serviceGroup.api))
{
if(serviceGroup.isLoading)
{
_request();
}
else
{
Rsd.loadServiceApi(serviceGroup,_fn);
}
}else
{
_fn();
}
};
//console.debug(Date.now(),'redjs end');
}