You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1484 lines
55 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(function (global, factory) {
"use strict";
if (typeof module === "object" && typeof module.exports === "object") {
module.exports = factory(global, true);
} else {
factory(global);
}
})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
"use strict";
var bFinished = true;
/**
* 兼容IE低版本的创建httpobj对象的方法
* @returns httpobj可用于进行数据传输的http的对象
*/
function getHttpObj() {
var httpobj = null;
if (IEVersion() < 10) {
try {
httpobj = new XDomainRequest();
} catch (e1) {
httpobj = new createXHR();
}
} else {
httpobj = new createXHR();
}
return httpobj;
}
//兼容IE低版本的创建xmlhttprequest对象的方法
/**
* 兼容IE低版本的创建xmlhttprequest对象的方法
* @returns xmlhttprequest对象兼容低版本IE
*/
function createXHR() {
if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器
return new XMLHttpRequest();
} else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject 兼容IE6
var versions = [ //由于MSXML库有3个版本因此都要考虑
'MSXML2.XMLHttp.6.0',
'MSXML2.XMLHttp.3.0',
'MSXML2.XMLHttp'
];
for (var i = 0; i < versions.length; i++) {
try {
return new ActiveXObject(versions[i]);
} catch (e) {
//跳过
}
}
} else {
throw new Error('您的浏览器不支持XHR对象');
}
}
/**
* 加载项本地服务返回的错误信息统一为data message的json格式
* 如果有新增错误信息,添加到下面
* 也可以通过请求状态码返回错误信息
*/
var errorMsg = [
"{\"data\": \"Failed to send message to WPS.\"}",
"{\"data\": \"Json parse failed.\"}",
"{\"error\": \"Json parse failed.\"}"
]
/**
* 通过该接口给服务器发请求
* @param {*} options 参数对象,具体包含的参数如下:
* @param {*} url 网页路径,传输地址
* @param {*} type 传输类型POST / GET / PUT
* @param {*} sendData 传输的数据
* @param {*} callback 回调函数
* @param {*} tryCount 请求失败后的尝试次数
* @param {*} bPop 是否弹出浏览器提示对话框
* @param {*} timeout 请求等待响应的时间,超过时间请求实效
* @param {*} concurrent 请求是否同步发送
* @param {*} wpsclient wpsclient对象
* @returns NULL
*/
function startWps(options) {
if (!bFinished && !options.concurrent) {
if (options.callback)
options.callback({
status: 1,
message: "上一次请求没有完成"
});
return;
}
if (!options.concurrent)
bFinished = false;
else
options.bFinished = false;
function startWpsInnder(tryCount) {
if (tryCount <= 0) {
if (!options.concurrent) {
if (bFinished)
return;
bFinished = true;
} else {
if (options.bFinished) {
return;
}
options.bFinished = true;
}
if (options.callback)
options.callback({
status: 2,
message: "请允许浏览器打开WPS Office"
});
return;
}
var xmlReq = getHttpObj();
//WPS客户端提供的接收参数的本地服务HTTP服务端口为58890HTTPS服务端口为58891
//这俩配置,取一即可,不可同时启用
xmlReq.open('POST', options.url);
xmlReq.onload = function (res) {
var responseStr = IEVersion() < 10 ? xmlReq.responseText : res.target.response;
var respStatus = IEVersion() < 10 ? xmlReq.status : res.target.status;
if (!options.concurrent)
bFinished = true;
else
options.bFinished = true;
if (options.callback) {
if (respStatus != 200 || errorMsg.indexOf(responseStr) != -1) {
var errorMessage = JSON.parse(responseStr)
options.callback({
status: 1,
message: errorMessage.data
});
if (errorMessage.data == "Subserver not available." && tryCount == options.tryCount && options.bPop) {
InitWpsCloudSvr();
setTimeout(function () {
startWpsInnder(tryCount - 1)
}, 3000);
}
}
else {
options.callback({
status: 0,
response: responseStr
});
}
}
}
xmlReq.ontimeout = xmlReq.onerror = function (res) {
xmlReq.bTimeout = true;
if (tryCount == options.tryCount && options.bPop) { //打开wps并传参
InitWpsCloudSvr();
}
setTimeout(function () {
startWpsInnder(tryCount - 1)
}, 1000);
}
if (IEVersion() < 10) {
xmlReq.onreadystatechange = function () {
if (xmlReq.readyState != 4)
return;
if (xmlReq.bTimeout) {
return;
}
if (xmlReq.status === 200)
xmlReq.onload();
else
xmlReq.onerror();
}
}
xmlReq.timeout = options.timeout;
xmlReq.send(options.sendData)
}
startWpsInnder(options.tryCount);
return;
}
var fromCharCode = String.fromCharCode;
// encoder stuff
var cb_utob = function (c) {
if (c.length < 2) {
var cc = c.charCodeAt(0);
return cc < 0x80 ? c :
cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) +
fromCharCode(0x80 | (cc & 0x3f))) :
(fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) +
fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) +
fromCharCode(0x80 | (cc & 0x3f)));
} else {
var cc = 0x10000 +
(c.charCodeAt(0) - 0xD800) * 0x400 +
(c.charCodeAt(1) - 0xDC00);
return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) +
fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) +
fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) +
fromCharCode(0x80 | (cc & 0x3f)));
}
};
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
var utob = function (u) {
return u.replace(re_utob, cb_utob);
};
var _encode = function (u) {
var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]';
if (isUint8Array)
return u.toString('base64')
else
return btoa(utob(String(u)));
}
if (typeof window.btoa !== 'function') window.btoa = func_btoa;
function func_btoa(input) {
var str = String(input);
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
for (
// initialize result and counter
var block, charCode, idx = 0, map = chars, output = '';
// if the next str index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
str.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = str.charCodeAt(idx += 3 / 4);
if (charCode > 0xFF) {
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
}
if (typeof window.atob !== 'function') window.atob = func_atob;
function func_atob(input) {
output = input.replace(/[\s\S]{1,4}/g, cb_decode);
return output
}
function cb_decode(cccc) {
var len = cccc.length
, padlen = len % 4
, n = (len > 0 ?
b64tab[cccc.charAt(0)] << 18 : 0) |
(len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
| (len > 3 ? b64tab[cccc.charAt(3)] : 0)
, chars = [
fromCharCode(n >>> 16),
fromCharCode((n >>> 8) & 0xff),
fromCharCode(n & 0xff)
]
;
chars.length -= [0, 0, 2, 1][padlen];
return chars.join('');
};
function btou (b) {
return b.replace(re_btou, cb_btou);
};
// decoder stuff
var re_btou = new RegExp([
'[\xC0-\xDF][\x80-\xBF]',
'[\xE0-\xEF][\x80-\xBF]{2}',
'[\xF0-\xF7][\x80-\xBF]{3}'
].join('|'), 'g');
function cb_btou (cccc) {
switch (cccc.length) {
case 4:
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
| ((0x3f & cccc.charCodeAt(1)) << 12)
| ((0x3f & cccc.charCodeAt(2)) << 6)
| (0x3f & cccc.charCodeAt(3)),
offset = cp - 0x10000;
return (fromCharCode((offset >>> 10) + 0xD800)
+ fromCharCode((offset & 0x3FF) + 0xDC00));
case 3:
return fromCharCode(
((0x0f & cccc.charCodeAt(0)) << 12)
| ((0x3f & cccc.charCodeAt(1)) << 6)
| (0x3f & cccc.charCodeAt(2))
);
default:
return fromCharCode(
((0x1f & cccc.charCodeAt(0)) << 6)
| (0x3f & cccc.charCodeAt(1))
);
}
};
/**
* 将字符串进行Base64编码
* @param {*} u 需要编码的数据
* @param {*} urisafe 返回值,编码后的数据
* @returns urisafe
*/
var encode = function (u, urisafe) {
return !urisafe ?
_encode(u) :
_encode(String(u)).replace(/[+\/]/g, function (m0) {
return m0 == '+' ? '-' : '_';
}).replace(/=/g, '');
};
var decode = function(u) {
return btou(atob(String(u)));
}
/**
* 获取IE浏览器版本
* @returns IE浏览器版本
*/
function IEVersion() {
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
if (isIE) {
var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
reIE.test(userAgent);
var fIEVersion = parseFloat(RegExp["$1"]);
if (fIEVersion == 7) {
return 7;
} else if (fIEVersion == 8) {
return 8;
} else if (fIEVersion == 9) {
return 9;
} else if (fIEVersion == 10) {
return 10;
} else {
return 6; //IE版本<=7
}
} else if (isEdge) {
return 20; //edge
} else if (isIE11) {
return 11; //IE11
} else {
return 30; //不是ie浏览器
}
}
/**
* 启动wps客户端加载项执行操作无返回值
* @param {*} options 参数对象,详情见下:
* @param {*} clientType 加载项类型, wps / wpp / et
* @param {*} name 加载项名称
* @param {*} func 客户端加载项要执行的方法
* @param {*} param 客户端家乡执行方法的参数
* @param {*} urlBase 网页路径前缀
* @param {*} callback 回调函数
* @param {*} tryCount 请求失败后的尝试次数
* @param {*} bPop 是否弹出浏览器提示对话框
* @param {*} wpsclient wpsclient对象
*/
function WpsStart(options) {
var startInfo = {
"name": options.name,
"function": options.func,
"info": options.param.param,
"jsPluginsXml": options.param.jsPluginsXml
};
var strData = JSON.stringify(startInfo);
if (IEVersion() < 10) {
try {
cceval("strData = '" + JSON.stringify(startInfo) + "';");
} catch (err) {
}
}
var baseData = encode(strData);
var url = options.urlBase + "/" + options.clientType + "/runParams";
var data = "ksowebstartup" + options.clientType + "://" + baseData;
startWps({
url: url,
sendData: data,
callback: options.callback,
tryCount: options.tryCount,
bPop: options.bPop,
timeout: 5000,
concurrent: false,
wpsclient: options.wpsclient
});
}
/**
* 服务端版本为空时通过该接口启动wps
* @param {*} options 参数对象,详情见下:
* @param {*} clientType 加载项类型, wps / wpp / et
* @param {*} name 加载项名称
* @param {*} func 客户端加载项要执行的方法
* @param {*} param 客户端家乡执行方法的参数
* @param {*} urlBase 网页路径前缀
* @param {*} callback 回调函数
* @param {*} wpsclient wpsclient对象
* @param {*} concurrent 请求是否同步发送
*/
function WpsStartWrap(options) {
WpsStart({
clientType: options.clientType,
name: options.name,
func: options.func,
param: options.param,
urlBase: options.urlBase,
callback: options.callback,
tryCount: 4,
bPop: true,
wpsclient: options.wpsclient,
})
}
/**
* 支持浏览器触发WPS有返回值的启动
*
* @param {*} clientType 组件类型
* @param {*} name WPS加载项名称
* @param {*} func WPS加载项入口方法
* @param {*} param 参数包括WPS加载项内部定义的方法参数等
* @param {*} callback 回调函数
* @param {*} tryCount 重试次数
* @param {*} bPop 是否弹出浏览器提示对话框
*/
function WpsStartWrapExInner(options) {
var infocontent = options.param.param;
var cmdId = guid();
if (!options.wpsclient || options.wpsclient.single) {
infocontent = JSON.stringify(options.param.param);
var rspUrl = options.urlBase + "/transferEcho/runParams";
var funcEx = "var res = " + options.func;
var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值
var infoEx = infocontent + ");" + cbCode + "void(0";
options.func = funcEx;
infocontent = infoEx;
}
var startInfo = {
"name": options.name,
"function": options.func,
"info": infocontent,
"showToFront": options.param.showToFront,
"jsPluginsXml": options.param.jsPluginsXml,
};
var strData = JSON.stringify(startInfo);
if (IEVersion() < 10) {
try {
cceval("strData = '" + JSON.stringify(startInfo) + "';");
} catch (err) {
}
}
var baseData = encode(strData);
var wrapper;
if (!options.wpsclient || options.wpsclient.single) {
var url = options.urlBase + "/transfer/runParams";
var data = "ksowebstartup" + options.clientType + "://" + baseData;
wrapper = {
id: cmdId,
app: options.clientType,
data: data,
serverId: serverId,
mode: options.silentMode ? true : false
};
}
else {
var url = options.urlBase + "/transferEx/runParams";
wrapper = {
id: options.wpsclient.clientId,
app: options.clientType,
data: baseData,
mode: options.wpsclient.silentMode ? "true" : "false",
serverId: serverId
};
}
wrapper = JSON.stringify(wrapper);
startWps({
url: url,
sendData: wrapper,
callback: options.callback,
tryCount: options.tryCount,
bPop: options.bPop,
timeout: 0,
concurrent: options.concurrent,
wpsclient: options.wpsclient
});
}
var serverVersion = "wait"
/**
* 获取服务端版本号的接口
* @param {*} options 参数对象,详情见下:
* @param {*} clientType 加载项类型, wps / wpp / et
* @param {*} name 加载项名称
* @param {*} func 客户端加载项要执行的方法
* @param {*} param 客户端家乡执行方法的参数
* @param {*} urlBase 网页路径前缀
* @param {*} callback 回调函数
* @param {*} wpsclient wpsclient对象
* @param {*} concurrent 请求是否同步发送
*/
function WpsStartWrapVersionInner(options) {
if (serverVersion == "wait") {
if (g_isSdkInited == true) {
InitWpsCloudSvr();
}
startWps({
url: options.urlBase + '/version',
sendData: JSON.stringify({ serverId: serverId }),
callback: function (res) {
if (res.status !== 0) {
options.callback(res)
return;
}
serverVersion = res.response;
options.tryCount = 1
options.bPop = false
if (serverVersion === "") {
WpsStart(options)
} else if (serverVersion < "1.0.1" && options.wpsclient) {
options.wpsclient.single = true;
WpsStartWrapExInner(options);
} else {
WpsStartWrapExInner(options);
}
},
tryCount: 4,
bPop: !g_isSdkInited,
timeout: 5000,
concurrent: options.concurrent
});
} else {
options.tryCount = 4
options.bPop = true
if (serverVersion === "") {
WpsStartWrap(options)
} else if (serverVersion < "1.0.1" && options.wpsclient) {
options.wpsclient.single = true;
WpsStartWrapExInner(options);
} else {
WpsStartWrapExInner(options);
}
}
}
var HeartBeatCode =
"function getHttpObj() {\n"
+ " var httpobj = null;\n"
+ " if (IEVersion() < 10) {\n"
+ " try {\n"
+ " httpobj = new XDomainRequest();\n"
+ " } catch (e1) {\n"
+ " httpobj = new createXHR();\n"
+ " }\n"
+ " } else {\n"
+ " httpobj = new createXHR();\n"
+ " }\n"
+ " return httpobj;\n"
+ " }\n"
+ " \n"
+ " function createXHR() {\n"
+ " if (typeof XMLHttpRequest != 'undefined') {\n"
+ " return new XMLHttpRequest();\n"
+ " } else if (typeof ActiveXObject != 'undefined') {\n"
+ " var versions = [\n"
+ " 'MSXML2.XMLHttp.6.0',\n"
+ " 'MSXML2.XMLHttp.3.0',\n"
+ " 'MSXML2.XMLHttp'\n"
+ " ];\n"
+ " \n"
+ " for (var i = 0; i < versions.length; i++) {\n"
+ " try {\n"
+ " return new ActiveXObject(versions[i]);\n"
+ " } catch (e) {\n"
+ " \n"
+ " }\n"
+ " }\n"
+ " } else {\n"
+ " throw new Error('您的浏览器不支持XHR对象');\n"
+ " }\n"
+ " }\n"
+ " \n"
+ " function IEVersion() {\n"
+ " var userAgent = navigator.userAgent; \n"
+ " var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;\n"
+ " var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; \n"
+ " var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;\n"
+ " if (isIE) {\n"
+ " var reIE = new RegExp('MSIE (\\d+\\.\\d+);');\n"
+ " reIE.test(userAgent);\n"
+ " var fIEVersion = parseFloat(RegExp['$1']);\n"
+ " if (fIEVersion == 7) {\n"
+ " return 7;\n"
+ " } else if (fIEVersion == 8) {\n"
+ " return 8;\n"
+ " } else if (fIEVersion == 9) {\n"
+ " return 9;\n"
+ " } else if (fIEVersion == 10) {\n"
+ " return 10;\n"
+ " } else {\n"
+ " return 6; \n"
+ " }\n"
+ " } else if (isEdge) {\n"
+ " return 20; \n"
+ " } else if (isIE11) {\n"
+ " return 11; \n"
+ " } else {\n"
+ " return 30; \n"
+ " }\n"
+ " }\n"
+ " var heartBeatStart = false;\n"
+ " function checkLastRegTime() {\n"
+ " var now = new Date().valueOf();\n"
+ " var TimeGap = now - LastRegTime;\n"
+ " if (TimeGap > 5000 && !heartBeatStart) {\n"
+ " HeartBeat();\n"
+ " heartBeatStart = true;\n"
+ " }\n"
+ " }\n"
+ " \n"
+ " function HeartBeat() {\n"
+ " var heartBeatItem = function () {\n"
+ " var xhr = getHttpObj();\n"
+ " xhr.onload = function (e) {\n"
+ " self.setTimeout(heartBeatItem, 5000);\n"
+ " }\n"
+ " xhr.onerror = function (e) {\n"
+ " self.setTimeout(heartBeatItem, 5000);\n"
+ " }\n"
+ " xhr.ontimeout = function (e) {\n"
+ " self.setTimeout(heartBeatItem, 5000);\n"
+ " }\n"
+ " xhr.open('POST', 'http://127.0.0.1:58890/askwebnotify', true);\n"
+ " xhr.timeout = 2000;\n"
+ " xhr.send(JSON.stringify(paramStr));\n"
+ " }\n"
+ " heartBeatItem();\n"
+ " }\n"
+ " \n"
+ " var paramStr;\n"
+ " var startCheck = false;\n"
+ " self.addEventListener('message', function (event) {\n"
+ " var data = event.data;\n"
+ " paramStr = data.param\n"
+ " paramStr.heartBeat = true\n"
+ " LastRegTime = data.LastRegTime;\n"
+ " if (!startCheck) {\n"
+ " startCheck = true;\n"
+ " self.setInterval(checkLastRegTime, 5000)\n"
+ " }\n"
+ " }, false);\n"
/**
* 生成guid的接口
* @returns guid
*/
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/**
* 开启多用户的接口
*/
var serverId = undefined
function EnableMultiUser() {
serverId = getServerId();
InitSdk(true)
}
/**
* 自定义协议启动服务端
* 默认不带参数serverIdlinux未升级之前不要使用多用户
*/
function InitWpsCloudSvr() {
if (serverId == undefined)
SetHref( "ksoWPSCloudSvr://start=RelayHttpServer")//是否启动wps弹框
else
SetHref( "ksoWPSCloudSvr://start=RelayHttpServer" + "&serverId=" + serverId )//是否启动wps弹框
}
/**
* 获取serverId的接口
* @returns serverId
*/
function getServerId() {
if (window.localStorage) {
if (localStorage.getItem("serverId")) {
//
}
else {
localStorage.setItem("serverId", guid());
}
return localStorage.getItem("serverId");
}
else {
return guid();
}
}
/**
* 将字符串转成二进制这里用来将字符串化后的js代码转成二进制文件
* @param {*} code
* @returns js文件对象的url
*/
function codeToBlob(code) {
var blob = new Blob([code], { type: 'text/javascript' }); // 生成js文件对象
var objectURL = window.URL.createObjectURL(blob); // 生成js文件的url
return objectURL;
}
var RegWebNotifyMap = { wps: {}, wpp: {}, et: {} }
var bWebNotifyUseTimeout = true
function WebNotifyUseTimeout(value) {
bWebNotifyUseTimeout = value ? true : false
}
var g_businessId = Number(Math.random().toString().substr(3, 5) + Date.parse(new Date())).toString(36);
var HeartBeatWorker
if (window.Worker) {
try {
HeartBeatWorker = new Worker(codeToBlob(HeartBeatCode));
} catch (error) {
//
}
}
var g_LastRegTime;
/**
* 注册一个前端页面接收WPS传来消息的方法
* @param {*} clientType wps | et | wpp
* @param {*} name WPS加载项的名称
* @param {*} callback 回调函数
* @param {*} wpsclient wpsclient对象
*/
function RegWebNotify(clientType, name, callback, wpsclient) {
if (clientType != "wps" && clientType != "wpp" && clientType != "et")
return;
var paramStr = {}
if (wpsclient) {
if (wpsclient.notifyRegsitered == true) {
return
}
wpsclient.notifyRegsitered = true;
paramStr = {
clientId: wpsclient.clientId,
name: name,
type: clientType,
serverId: serverId
}
if (HeartBeatWorker)
paramStr.businessId = g_businessId
}
else {
if (typeof callback != 'function')
return
if (RegWebNotifyMap[clientType][name]) {
RegWebNotifyMap[clientType][name] = callback;
return
}
var RegWebNotifyID = new Date().valueOf() + ''
paramStr = {
id: RegWebNotifyID,
name: name,
type: clientType,
serverId: serverId
}
if (HeartBeatWorker)
paramStr.businessId = g_businessId
RegWebNotifyMap[clientType][name] = callback
}
var askItem = function () {
var xhr = getHttpObj()
xhr.onload = function (e) {
if (xhr.responseText == "WPSInnerMessage_quit" || xhr.status != 200) {
if (!wpsclient || wpsclient.single) {
window.setTimeout(askItem, 2000);
}
return;
}
window.setTimeout(askItem, 300)
try {
if (!HeartBeatWorker)
throw new Error();
var resText = JSON.parse(xhr.responseText);
paramStr.messageId = resText.msgId;
if (wpsclient) {
if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象这里的resText.data就是一个json对象可以输出自己想要的json数据
if (typeof resText.data == 'object')
wpsclient.OnRegWebNotify(JSON.stringify(resText.data))
else
wpsclient.OnRegWebNotify(resText.data)
else
wpsclient.OnRegWebNotify(xhr.responseText)
} else {
var func = RegWebNotifyMap[clientType][name]
if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象这里的resText.data就是一个json对象可以输出自己想要的json数据
if (typeof resText.data == 'object')
func(JSON.stringify(resText.data))
else
func(resText.data)
else
func(xhr.responseText)
}
}
catch (e) {
// 这里做一个容错即使json解析失败也要把msgId提取出来发回给服务端避免消息清不掉一直重复发送
// 同时把data也取出来但是格式无法保证
var data
var str = xhr.responseText
var idx1 = str.indexOf("\"msgId\"")
var idx2
var idx3
var idx4
var data
if (idx1 != -1) {
idx1 = idx1 + 8
idx2 = str.indexOf("\"data\"") - 2
paramStr.messageId = parseInt(str.substring(idx1, idx2))
idx3 = str.indexOf("\"data\"") + 8
idx4 = str.length - 2
data = str.substring(idx3, idx4)
}
if (wpsclient) {
if (paramStr.messageId !== undefined && data != undefined)
wpsclient.OnRegWebNotify(data)
else
wpsclient.OnRegWebNotify(xhr.responseText)
} else {
var func = RegWebNotifyMap[clientType][name]
if (paramStr.messageId !== undefined && data != undefined)
func(data)
else
func(xhr.responseText)
}
}
}
xhr.onerror = function (e) {
if (bWebNotifyUseTimeout)
window.setTimeout(askItem, 1000)
else
window.setTimeout(askItem, 10000)
}
xhr.ontimeout = function (e) {
if (bWebNotifyUseTimeout)
window.setTimeout(askItem, 300)
else
window.setTimeout(askItem, 10000)
}
if (IEVersion() < 10) {
xhr.onreadystatechange = function () {
if (xhr.readyState != 4)
return;
if (xhr.bTimeout) {
return;
}
if (xhr.status === 200)
xhr.onload();
else
xhr.onerror();
}
}
xhr.open('POST', GetUrlBase() + '/askwebnotify', true)
if (bWebNotifyUseTimeout)
xhr.timeout = 2000;
if (HeartBeatWorker) {
g_LastRegTime = new Date().valueOf();
var param = {
param: {
name: name,
type: clientType,
businessId: g_businessId,
serverId: serverId
},
LastRegTime: g_LastRegTime
}
HeartBeatWorker.postMessage(param)
}
xhr.send(JSON.stringify(paramStr));
}
askItem()
}
/**
* 获取网页路径前缀
* @returns url前缀
*/
function GetUrlBase() {
if (location.protocol == "https:")
return "https://127.0.0.1:58891"
return "http://127.0.0.1:58890"
}
/**
* 获取服务端版本号的接口,这里主要是初始化一些参数
* @param {*} clientType 加载项类型, wps / wpp / et
* @param {*} name 加载项名称
* @param {*} func 客户端加载项要执行的方法
* @param {*} param 客户端加载项执行方法的参数
* @param {*} callback 回调函数
* @param {*} showToFront 设置客户端是否显示到前面
* @param {*} jsPluginsXml 设置加载项路径
* @param {*} silentMode 是否是静默启动
*/
function WpsStartWrapVersion(clientType, name, func, param, callback, showToFront, jsPluginsXml, silentMode) {
var paramEx = {
jsPluginsXml: jsPluginsXml ? jsPluginsXml : "",
showToFront: typeof (showToFront) == 'boolean' ? showToFront : true,
param: (typeof (param) == 'object' ? param : JSON.parse(param))
}
var options = {
clientType: clientType,
name: name,
func: func,
param: paramEx,
urlBase: GetUrlBase(),
callback: callback,
wpsclient: undefined,
concurrent: true,
silentMode: silentMode
}
WpsStartWrapVersionInner(options);
}
//从外部浏览器远程调用 WPS 加载项中的方法
var WpsInvoke = {
InvokeAsHttp: WpsStartWrapVersion,
InvokeAsHttps: WpsStartWrapVersion,
RegWebNotify: RegWebNotify,
ClientType: {
wps: "wps",
et: "et",
wpp: "wpp"
},
CreateXHR: getHttpObj,
IsClientRunning: IsClientRunning
}
/**
* @constructor WpsClient wps客户端
* @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格
*/
function WpsClient(clientType) {
/**
* 设置RegWebNotify的回调函数加载项给业务端发消息通过该函数
* @memberof WpsClient
* @member onMessage
*/
this.onMessage;
/**
* 设置加载项路径
* @memberof WpsClient
* @member jsPluginsXml
*/
this.jsPluginsXml;
/**
* 内部成员,外部无需调用
*/
this.notifyRegsitered = false;
this.clientId = "";
this.concurrent = true;
this.clientType = clientType;
/**
* 内部函数,外部无需调用
* @param {*} options
*/
this.initWpsClient = function (options) {
options.clientType = this.clientType
options.wpsclient = this
options.concurrent = this.concurrent
WpsStartWrapVersionInner(options)
}
/**
* 以http启动
* @param {string} name 加载项名称
* @param {string} func 要调用的加载项中的函数行
* @param {string} param 在加载项中执行函数func要传递的数据
* @param {function({int, string})} callback 回调函数status = 0 表示成功失败请查看message信息
* @param {bool} showToFront 设置wps是否显示到前面来
* @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭;
* "WPS Addon is not response." 加载项阻塞,函数执行失败
*/
this.InvokeAsHttp = function (name, func, param, callback, showToFront) {
function clientCallback(res) {
//this不是WpsClient是options对象
if (res.status !== 0 || serverVersion < "1.0.1" || this.wpsclient.single == true) {
if (callback)
callback(res);
if (serverVersion < "1.0.1" || this.wpsclient.single == true)
RegWebNotify(clientType, name, this.wpsclient.onMessage)
return;
}
if(serverVersion < "1.0.3") {
try {
var resObject = JSON.parse(res.response);
if (this.wpsclient.clientId == "") {
this.wpsclient.clientId = resObject.clientId;
}
if (typeof resObject.data == "object")
res.response = JSON.stringify(resObject.data);
else
res.response = resObject.data;
}
catch(e) {
var str = res.response
var idx1 = str.indexOf("\"clientId\":\"{")
var idx2
var idx3
var idx4
if (idx1 != -1) {
idx1 = idx1 + ("\"clientId\":\"{").length - 1
idx2 = str.indexOf("\"data\":") - 3
if (this.wpsclient.clientId == "") {
this.wpsclient.clientId = str.substring(idx1, idx2);
}
idx3 = str.indexOf("\"data\":") + ("\"data\":").length
idx4 = str.length - 1
if(idx3 < idx4)
res.response = str.substring(idx3, idx4)
else
res.response = "";
}
}
}
else {
var resObject = JSON.parse(res.response);
if (this.wpsclient.clientId == "") {
this.wpsclient.clientId = resObject.clientId;
}
res.response = decode(resObject.data);
}
if (IEVersion() < 10)
cceval(" res.response = '" + res.response + "';");
if (callback)
callback(res);
this.wpsclient.RegWebNotify(name);
}
var paramEx = {
jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "",
showToFront: typeof (showToFront) == 'boolean' ? showToFront : true,
param: (typeof (param) == 'object' ? param : JSON.parse(param))
}
this.initWpsClient({
name: name,
func: func,
param: paramEx,
urlBase: GetUrlBase(),
callback: clientCallback
})
}
/**
* 以https启动
* @param {string} name 加载项名称
* @param {string} func 要调用的加载项中的函数行
* @param {string} param 在加载项中执行函数func要传递的数据
* @param {function({int, string})} callback 回调函数status = 0 表示成功失败请查看message信息
* @param {bool} showToFront 设置wps是否显示到前面来
*/
this.InvokeAsHttps = function (name, func, param, callback, showToFront) {
var paramEx = {
jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "",
showToFront: typeof (showToFront) == 'boolean' ? showToFront : true,
param: (typeof (param) == 'object' ? param : JSON.parse(param))
}
this.initWpsClient({
name: name,
func: func,
param: paramEx,
urlBase: GetUrlBase(),
callback: callback
})
}
/**
* 内部函数,外部无需调用
* @param {*} name
*/
this.RegWebNotify = function (name) {
RegWebNotify(this.clientType, name, null, this);
}
/**
* 消息注册函数的回调函数
* @param {*} message 客户端发来的消息
*/
this.OnRegWebNotify = function (message) {
if (this.onMessage)
this.onMessage(message)
}
/**
* 以静默模式启动客户端
* @param {string} name 必传参数,加载项名称
* @param {function({int, string})} [callback] 回调函数status = 0 表示成功失败请查看message信息
*/
this.StartWpsInSilentMode = function (name, callback) {
function initCallback(res) {
//this不是WpsClient是options对象
if (res.status !== 0 || serverVersion < "1.0.1" || this.wpsclient.single == true) {
if (callback)
callback(res);
if (serverVersion < "1.0.1" || this.wpsclient.single == true)
RegWebNotify(clientType, name, this.wpsclient.onMessage)
return;
}
var jsonObj = JSON.parse(res.response);
if (this.wpsclient.clientId == "") {
this.wpsclient.clientId = jsonObj.clientId;
}
if(serverVersion < "1.0.3") {
res.response = JSON.stringify(jsonObj.data);
}
else{
res.response = decode(jsonObj.data);
}
if (callback) {
callback(res);
}
this.wpsclient.RegWebNotify(name);
}
var paramEx = {
jsPluginsXml: this.jsPluginsXml,
showToFront: false,
param: { status: "InitInSilentMode" }
}
this.silentMode = true;
this.initWpsClient({
name: name,
func: "",
param: paramEx,
urlBase: GetUrlBase(),
callback: initCallback
})
}
/**
* 显示客户端到最前面
* @param {string} name 必传参数,加载项名称
* @param {function({int, string})} [callback] 回调函数
*/
this.ShowToFront = function (name, callback) {
if (serverVersion < "1.0.1") {
if (callback) {
callback({
status: 4,
message: "当前客户端不支持,请升级客户端"
});
return;
}
return;
}
if (this.clientId == "") {
if (callback) callback({
status: 3,
message: "没有静默启动客户端"
});
return;
}
var paramEx = {
jsPluginsXml: "",
showToFront: true,
param: { status: "ShowToFront" }
}
this.initWpsClient({
name: name,
func: "",
param: paramEx,
urlBase: GetUrlBase(),
callback: callback
})
}
/**
* 关闭未显示出来的静默启动客户端
* @param {string} name 必传参数,加载项名称
* @param {function({int, string})} [callback] 回调函数
*/
this.CloseSilentClient = function (name, callback) {
if (serverVersion < "1.0.1") {
if (callback) {
callback({
status: 4,
message: "当前客户端不支持,请升级客户端"
});
return;
}
return;
}
if (this.clientId == "") {
if (callback) callback({
status: 3,
message: "没有静默启动客户端"
});
return;
}
var paramEx = {
jsPluginsXml: "",
showToFront: false,
param: undefined
}
var func;
if (this.clientType == "wps")
func = "wps.WpsApplication().Quit"
else if (this.clientType == "et")
func = "wps.EtApplication().Quit"
else if (this.clientType == "wpp")
func = "wps.WppApplication().Quit"
function closeSilentClient(res) {
if (res.status == 0)
this.wpsclient.clientId = ""
if (callback) callback(res);
return;
}
this.initWpsClient({
name: name,
func: func,
param: paramEx,
urlBase: GetUrlBase(),
callback: closeSilentClient
})
}
/**
* 当前客户端是否在运行使用WpsClient.IsClientRunning()进行调用
* @param {function({int, string})} [callback] 回调函数,"Client is running." 客户端正在运行
* "Client is not running." 客户端没有运行
*/
this.IsClientRunning = function (callback) {
if (serverVersion < "1.0.1") {
if (callback) {
callback({
status: 4,
message: "当前客户端不支持,请升级客户端"
});
return;
}
return;
}
IsClientRunning(this.clientType, callback, this)
}
}
/**
* 初始化sdk用来减少在服务进程启动时自定义协议弹框出现的次数
*/
var g_isSdkInited = false;
function InitSdk(bMultiUser) {
g_isSdkInited = false;
var url = GetUrlBase() + "/version";
startWps({
url: url,
sendData: JSON.stringify({ serverId: serverId }),
callback: function (res) {
if ((!serverId && !bMultiUser) || bMultiUser)
g_isSdkInited = true;
if (res.status !== 0 && res.message !== "Subserver not available.") {
serverVersion = "wait"
return;
}
if (res.response && serverVersion == "wait")
serverVersion = res.response;
},
tryCount: 1,
bPop: false,
concurrent: true,
timeout: 1000
});
}
InitSdk(false);
if (typeof noGlobal === "undefined") {
window.WpsInvoke = WpsInvoke;
window.WpsClient = WpsClient;
window.WebNotifyUseTimeout = WebNotifyUseTimeout;
window.EnableMultiUser = EnableMultiUser;
}
/**
* 当前客户端是否在运行使用WpsInvoke.IsClientRunning()进行调用
* @param {string} clientType 加载项类型
* @param {function} [callback] 回调函数,"Client is running." 客户端正在运行
* "Client is not running." 客户端没有运行
*/
function IsClientRunning(clientType, callback, wpsclient) {
var url = GetUrlBase() + "/isRunning";
var wrapper = {
id: wpsclient == undefined ? undefined : wpsclient.clientId,
app: clientType,
serverId: serverId
}
wrapper = JSON.stringify(wrapper);
startWps({
url: url,
sendData: wrapper,
callback: callback,
tryCount: 1,
bPop: false,
timeout: 2000,
concurrent: true,
wpsclient: wpsclient
});
}
/**
* 获取publish.xml的内容
* @param {*} callBack 回调函数
*/
function WpsAddonGetAllConfig(callBack) {
var baseData = JSON.stringify({ serverId: serverId });
startWps({
url: GetUrlBase() + "/publishlist",
type: "POST",
sendData: baseData,
callback: callBack,
tryCount: 3,
bPop: true,
timeout: 5000,
concurrent: true
});
}
/**
* 检查ribbon.xml文件是否有效
* @param {*} element 参数对象
* @param {*} callBack 回调函数
*/
function WpsAddonVerifyStatus(element, callBack) {
var xmlReq = getHttpObj();
var offline = element.online === "false";
var url = offline ? element.url : element.url + "ribbon.xml";
xmlReq.open("POST", GetUrlBase() + "/redirect/runParams");
xmlReq.onload = function (res) {
if (offline && !res.target.response.startsWith("7z")) {
callBack({ status: 1, msg: "不是有效的7z格式" + url });
} else if (!offline && !res.target.response.startsWith("<customUI")) {
callBack({ status: 1, msg: "不是有效的ribbon.xml, " + url })
} else {
callBack({ status: 0, msg: "OK" })
}
}
xmlReq.onerror = function (res) {
xmlReq.bTimeout = true;
callBack({ status: 2, msg: "网页路径不可访问,如果是跨域问题,不影响使用" + url })
}
xmlReq.ontimeout = function (res) {
xmlReq.bTimeout = true;
callBack({ status: 3, msg: "访问超时" + url })
}
if (IEVersion() < 10) {
xmlReq.onreadystatechange = function () {
if (xmlReq.readyState != 4)
return;
if (xmlReq.bTimeout) {
return;
}
if (xmlReq.status === 200)
xmlReq.onload();
else
xmlReq.onerror();
}
}
xmlReq.timeout = 5000;
var data = {
method: "get",
url: url,
data: ""
}
var sendData = FormatSendData(data)
xmlReq.send(sendData);
}
/**
* 部署加载项包括启动enable / disable禁用 / disableall禁用所有
* @param {*} element 参数对象
* @param {*} cmd 具体操作enable / disable / disableall
* @param {*} callBack 回调函数
*/
function WpsAddonHandleEx(element, cmd, callBack) {
var data = FormatData(element, cmd);
startWps({
url: GetUrlBase() + "/deployaddons/runParams",
type: "POST",
sendData: data,
callback: callBack,
tryCount: 3,
bPop: true,
timeout: 0,
concurrent: true
});
}
/**
* 启用加载项
* @param {*} element 参数对象
* @param {*} callBack 回调函数
*/
function WpsAddonEnable(element, callBack) {
WpsAddonHandleEx(element, "enable", callBack)
}
/**
* 禁用加载项
* @param {*} element 参数对象
* @param {*} callBack 回调函数
*/
function WpsAddonDisable(element, callBack) {
WpsAddonHandleEx(element, "disable", callBack)
}
/**
* 禁用所有加载项
* @param {*} element
* @param {*} callBack
*/
function WpsAddonDisableAll(element, callBack) {
WpsAddonHandleEx(element, "disableall", callBack)
}
/**
* 生成json格式的数据
* @param {*} element 参数对象
* @param {*} cmd 具体操作enable / disable / disableall
* @returns base64编码后的数据
*/
function FormatData(element, cmd) {
var data = {
"cmd": cmd, //"enable", 启用, "disable", 禁用, "disableall", 禁用所有
"name": element.name,
"url": element.url,
"addonType": element.addonType,
"online": element.online,
"version": element.version,
"time": new Date().getTime()
}
return FormatSendData(data);
}
/**
* 将json格式的数据字符串化并进行base64编码
* @param {*} data 数据
* @returns base64编码后的数据
*/
function FormatSendData(data) {
var strData = JSON.stringify(data);
if (IEVersion() < 10)
cceval("strData = '" + JSON.stringify(strData) + "';");
if (serverVersion >= "1.0.2" && serverId != undefined) {
var base64Data = encode(strData);
return JSON.stringify({
serverId: serverId,
data: base64Data
})
}
else {
return encode(strData);
}
}
//管理 WPS 加载项
var WpsAddonMgr = {
getAllConfig: WpsAddonGetAllConfig,
verifyStatus: WpsAddonVerifyStatus,
enable: WpsAddonEnable,
disable: WpsAddonDisable,
disableall: WpsAddonDisableAll
}
if (typeof noGlobal === "undefined") {
window.WpsAddonMgr = WpsAddonMgr;
}
return { WpsInvoke: WpsInvoke, WpsAddonMgr: WpsAddonMgr, version: "1.0.31" };
});