o2.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /** ***** BEGIN LICENSE BLOCK *****
  2. * |------------------------------------------------------------------------------|
  3. * | O2OA 活力办公 创意无限 o2.js |
  4. * |------------------------------------------------------------------------------|
  5. * | Distributed under the AGPL license: |
  6. * |------------------------------------------------------------------------------|
  7. * | Copyright © 2018, o2oa.net, o2server.io O2 Team |
  8. * | All rights reserved. |
  9. * |------------------------------------------------------------------------------|
  10. *
  11. * This file is part of O2OA.
  12. *
  13. * O2OA is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as published by
  15. * the Free Software Foundation, either version 3 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * O2OA is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
  25. *
  26. * ***** END LICENSE BLOCK ******/
  27. /* load o2 Core
  28. * |------------------------------------------------------------------------------|
  29. * |addReady: o2.addReady(fn), |
  30. * |------------------------------------------------------------------------------|
  31. * |load: o2.load(urls, callback, reload) |
  32. * |loadCss: o2.loadCss(urls, dom, callback, reload, doc) |
  33. * |------------------------------------------------------------------------------|
  34. * |typeOf: o2.typeOf(o) |
  35. * |------------------------------------------------------------------------------|
  36. * |uuid: o2.uuid() |
  37. * |------------------------------------------------------------------------------|
  38. */
  39. (function(){
  40. var _href = window.location.href;
  41. var _debug = (_href.indexOf("debugger")!==-1);
  42. this.o2 = {
  43. "version": {
  44. "v": '1.1.7',
  45. "build": "2018.11.22",
  46. "info": "O2OA 活力办公 创意无限. Copyright © 2018, o2oa.net O2 Team All rights reserved."
  47. },
  48. "session": {
  49. "isDebugger": _debug,
  50. "path": "/o2_core/o2"
  51. }
  52. };
  53. var _attempt = function(){
  54. for (var i = 0, l = arguments.length; i < l; i++){
  55. try {
  56. arguments[i]();
  57. return arguments[i];
  58. } catch (e){}
  59. }
  60. return null;
  61. };
  62. var _typeOf = function(item){
  63. if (!item) return 'null';
  64. if (item.$family) return item.$family();
  65. if (item.constructor === window.Array) return "array";
  66. if (item.nodeName){
  67. if (item.nodeType === 1) return 'element';
  68. if (item.nodeType === 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
  69. } else if (typeof item.length === 'number'){
  70. if (item.callee) return 'arguments';
  71. }
  72. return typeof item;
  73. };
  74. this.o2.typeOf = _typeOf;
  75. var _addListener = function(dom, type, fn){
  76. if (type === 'unload'){
  77. var old = fn; //self = this;
  78. fn = function(){
  79. _removeListener(dom, 'unload', fn);
  80. old();
  81. };
  82. }
  83. if (dom.addEventListener) dom.addEventListener(type, fn, !!arguments[2]);
  84. else dom.attachEvent('on' + type, fn);
  85. };
  86. var _removeListener = function(dom, type, fn){
  87. if (dom.removeEventListener) dom.removeEventListener(type, fn, !!arguments[2]);
  88. else dom.detachEvent('on' + type, fn);
  89. };
  90. //http request class
  91. var _request = (function(){
  92. var XMLHTTP = function(){ return new XMLHttpRequest(); };
  93. var MSXML2 = function(){ return new ActiveXObject('MSXML2.XMLHTTP'); };
  94. var MSXML = function(){ return new ActiveXObject('Microsoft.XMLHTTP'); };
  95. return _attempt(XMLHTTP, MSXML2, MSXML);
  96. })();
  97. var _returnBase = function(number, base) {
  98. return (number).toString(base).toUpperCase();
  99. };
  100. var _getIntegerBits = function(val, start, end){
  101. var base16 = _returnBase(val, 16);
  102. var quadArray = [];
  103. var quadString = '';
  104. //var i = 0;
  105. for (var i = 0; i < base16.length; i++) {
  106. quadArray.push(base16.substring(i, i + 1));
  107. }
  108. for (i = Math.floor(start / 4); i <= Math.floor(end / 4); i++) {
  109. if (!quadArray[i] || quadArray[i] === '')
  110. quadString += '0';
  111. else
  112. quadString += quadArray[i];
  113. }
  114. return quadString;
  115. };
  116. var _rand = function(max) {
  117. return Math.floor(Math.random() * (max + 1));
  118. };
  119. var _uuid = function(){
  120. var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
  121. var dc = new Date();
  122. var t = dc.getTime() - dg.getTime();
  123. var tl = _getIntegerBits(t, 0, 31);
  124. var tm = _getIntegerBits(t, 32, 47);
  125. var thv = _getIntegerBits(t, 48, 59) + '1';
  126. var csar = _getIntegerBits(_rand(4095), 0, 7);
  127. var csl = _getIntegerBits(_rand(4095), 0, 7);
  128. var n = _getIntegerBits(_rand(8191), 0, 7)
  129. + _getIntegerBits(_rand(8191), 8, 15)
  130. + _getIntegerBits(_rand(8191), 0, 7)
  131. + _getIntegerBits(_rand(8191), 8, 15)
  132. + _getIntegerBits(_rand(8191), 0, 15);
  133. return tl + tm + thv + csar + csl + n;
  134. };
  135. this.o2.uuid = _uuid;
  136. //use framework url
  137. var _frameworks = {
  138. "o2.core": ["/o2_core/o2/o2.core.js"],
  139. "o2.more": ["/o2_core/o2/o2.more.js"],
  140. "jquery": ["/x_desktop/res/framework/jquery/jquery.min.js"],
  141. "mootools": ["/x_desktop/res/framework/mootools/mootools-1.6.0_all.js"],
  142. "ckeditor": ["/x_desktop/res/framework/htmleditor/ckeditor/ckeditor.js"],
  143. "raphael": ["/x_desktop/res/framework/raphael/raphael.js"],
  144. "d3": ["/x_desktop/res/framework/d3/d3.js"],
  145. "ace": ["/x_desktop/res/framework/ace/src-min-noconflict/ace.js","/x_desktop/res/framework/ace/src-min-noconflict/ext-language_tools.js"],
  146. "mwf": "/x_desktop/res/mwf4/MWF.js",
  147. "JSBeautifier": ["/x_desktop/res/framework/JSBeautifier/beautify.js"],
  148. "JSBeautifier_css": ["/x_desktop/res/framework/JSBeautifier/beautify-css.js"],
  149. "JSBeautifier_html": ["/x_desktop/res/framework/JSBeautifier/beautify-html.js"]
  150. };
  151. var _loaded = {};
  152. var _loadedCss = {};
  153. var _loadSingle = function(url, callback, reload, doc){
  154. var addr_uri = _frameworks[url] || url;
  155. if (!_debug) if (addr_uri.indexOf("framework")===-1) addr_uri = addr_uri.replace(/\.js/, ".min.js");
  156. addr_uri = (addr_uri.indexOf("?")!==-1) ? addr_uri+"&v="+o2.version.v : addr_uri+"?v="+o2.version.v;
  157. var key = encodeURIComponent(url);
  158. if (!reload) if (_loaded[key]){ if (callback)callback(); return; }
  159. var curdoc = doc || document;
  160. var head = (curdoc.head || curdoc.getElementsByTagName("head")[0] || curdoc.documentElement);
  161. var s = curdoc.createElement('script');
  162. s.src = addr_uri;
  163. head.appendChild(s);
  164. var _checkScriptLoaded = function(_, isAbort){
  165. if (isAbort || !s.readyState || s.readyState === "loaded" || s.readyState === "complete") {
  166. _loaded[key] = true;
  167. _removeListener(s, 'DOMContentLoaded', _checkScriptLoaded);
  168. _removeListener(s, 'readystatechange', _checkScriptLoaded);
  169. if (!isAbort) if (callback)callback();
  170. }
  171. };
  172. if ('onreadystatechange' in s) _addListener(s, 'readystatechange', _checkScriptLoaded);
  173. _addListener(s, 'load', _checkScriptLoaded);
  174. };
  175. var _load = function(urls, callback, reload, doc){
  176. var urltype = _typeOf(urls);
  177. var modules;
  178. if (urltype==="array"){
  179. modules = [];
  180. urls.each(function(url){
  181. var module = _frameworks[url] || url;
  182. if (_typeOf(module)==="array"){
  183. modules.concat(module)
  184. }else{
  185. modules.push(url)
  186. }
  187. }.bind(this));
  188. }else{
  189. modules = _frameworks[urls] || urls;
  190. }
  191. var type = _typeOf(modules);
  192. if (type==="array"){
  193. var thisLoaded = [];
  194. for (var i=0; i<modules.length; i++){
  195. _loadSingle(modules[i], function(){
  196. thisLoaded.push(modules[i]);
  197. if (thisLoaded.length===modules.length){
  198. if (callback) callback();
  199. }
  200. }, reload, doc);
  201. }
  202. }
  203. if (type==="string"){
  204. _loadSingle(modules, callback, reload);
  205. }
  206. };
  207. this.o2.load = _load;
  208. var _loadSingleCss = function(url, dom, callback, reload, sourceDoc){
  209. var key = encodeURIComponent(url);
  210. if (!reload){
  211. if (_loadedCss[key]){
  212. if (dom) _parseDom(dom, function(node){ node.className += ((node.className) ? " css"+_loadedCss[key] : "css"+_loadedCss[key])}, sourceDoc);
  213. if (callback)callback(_loadedCss[key]);
  214. return;
  215. }
  216. }
  217. var cssurl = _frameworks[url] || url;
  218. var xhr = new _request();
  219. xhr.open("GET", cssurl, true);
  220. var success = function(xhr){
  221. var cssText = xhr.responseText;
  222. try{
  223. if (cssText){
  224. var uuid = "";
  225. if (dom){
  226. uuid = _uuid();
  227. _parseDom(dom, function(node){ node.className += ((node.className) ? " css"+uuid : "css"+uuid)}, sourceDoc);
  228. }
  229. if (uuid){
  230. var rex = new RegExp("(.+)(?=\\{)", "g");
  231. var match;
  232. while ((match = rex.exec(cssText)) !== null) {
  233. var prefix = ".css" + uuid + " ";
  234. var rule = prefix + match[0];
  235. cssText = cssText.substring(0, match.index) + rule + cssText.substring(rex.lastIndex, cssText.length);
  236. rex.lastIndex = rex.lastIndex + prefix.length;
  237. }
  238. }
  239. var doc = sourceDoc || document;
  240. var style = doc.createElement("style");
  241. style.setAttribute("type", "text/css");
  242. var head = (doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement);
  243. head.appendChild(style);
  244. if(style.styleSheet){
  245. var setFunc = function(){
  246. style.styleSheet.cssText = cssText;
  247. };
  248. if(style.styleSheet.disabled){
  249. setTimeout(setFunc, 10);
  250. }else{
  251. setFunc();
  252. }
  253. }else{
  254. var cssTextNode = doc.createTextNode(cssText);
  255. style.appendChild(cssTextNode);
  256. }
  257. // style.sheet.cssRules[0].cssText = "#layout_xxx {\n" +
  258. // " width: 500px;\n" +
  259. // " height: 300px;\n" +
  260. // " background: #FFCCBA;\n" +
  261. // "}"
  262. }
  263. _loadedCss[key] = uuid;
  264. if (callback) callback(style);
  265. }catch (e){
  266. if (callback) callback();
  267. return "";
  268. }
  269. };
  270. var failure = function(xhr){
  271. if (callback) callback(xhr);
  272. };
  273. var onreadystatechange= function(){
  274. if (xhr.readyState !== 4) return;
  275. var status = xhr.status;
  276. status = (status === 1223) ? 204 : status;
  277. //var response = {text: xhr.responseText || '', xml: xhr.responseXML};
  278. if ((status >= 200 && status < 300))
  279. success(xhr);
  280. else if ((status >= 300 && status < 400))
  281. failure(xhr);
  282. else
  283. failure(xhr);
  284. };
  285. _addListener(xhr, "readystatechange", onreadystatechange);
  286. //xhr.onreadystatechange = onreadystatechange;
  287. xhr.send();
  288. };
  289. var _parseDomString = function(dom, fn, sourceDoc){
  290. var doc = sourceDoc || document;
  291. var list = doc.querySelectorAll(dom);
  292. if (list.length) for (var i=0; i<list.length; i++) _parseDomElement(list[i], fn);
  293. };
  294. var _parseDomElement = function(dom, fn){
  295. if (fn) fn(dom);
  296. };
  297. var _parseDom = function(dom, fn, sourceDoc){
  298. var domType = _typeOf(dom);
  299. if (domType==="string") _parseDomString(dom, fn, sourceDoc);
  300. if (domType==="element") _parseDomElement(dom, fn);
  301. if (domType==="array") for (var i=0; i<dom.length; i++) _parseDom(dom[i], fn, sourceDoc);
  302. };
  303. var _loadCss = function(urls, dom, callback, reload, sourceDoc){
  304. modules = _frameworks[urls] || urls;
  305. var type = _typeOf(modules);
  306. if (type==="array"){
  307. var thisLoaded = [];
  308. var styleList = [];
  309. for (var i=0; i<modules.length; i++){
  310. _loadSingleCss(modules[i], dom, function(style){
  311. thisLoaded.push(modules[i]);
  312. if (style) styleList.push(styleList);
  313. if (thisLoaded.length===modules.length){
  314. if (callback) callback(styleList);
  315. }
  316. }, reload, sourceDoc);
  317. }
  318. }
  319. if (type==="string"){
  320. _loadSingleCss(modules, dom, callback, reload, sourceDoc);
  321. }
  322. };
  323. this.o2.loadCss = _loadCss;
  324. var _dom = {
  325. ready: false,
  326. loaded: false,
  327. checks: [],
  328. shouldPoll: false,
  329. timer: null,
  330. testElement: document.createElement('div'),
  331. readys: [],
  332. domready: function(){
  333. clearTimeout(_dom.timer);
  334. if (_dom.ready) return;
  335. _dom.loaded = _dom.ready = true;
  336. _removeListener(document, 'DOMContentLoaded', _dom.checkReady);
  337. _removeListener(document, 'readystatechange', _dom.check);
  338. _dom.onReady();
  339. },
  340. check: function(){
  341. for (var i = _dom.checks.length; i--;) if (_dom.checks[i]() && window.MooTools && o2.core && o2.more){
  342. _dom.domready();
  343. return true;
  344. }
  345. return false;
  346. },
  347. poll: function(){
  348. clearTimeout(_dom.timer);
  349. if (!_dom.check()) _dom.timer = setTimeout(_dom.poll, 10);
  350. },
  351. /*<ltIE8>*/
  352. // doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
  353. // testElement.doScroll() throws when the DOM is not ready, only in the top window
  354. doScrollWorks: function(){
  355. try {
  356. _dom.testElement.doScroll();
  357. return true;
  358. } catch (e){}
  359. return false;
  360. },
  361. /*</ltIE8>*/
  362. onReady: function(){
  363. for (var i=0; i<_dom.readys.length; i++){
  364. this.readys[i].apply(window);
  365. }
  366. },
  367. addReady: function(fn){
  368. if (_dom.loaded){
  369. if (fn) fn.apply(window);
  370. }else{
  371. if (fn) _dom.readys.push(fn);
  372. }
  373. return _dom;
  374. },
  375. checkReady: function(){
  376. _dom.checks.push(function(){return true});
  377. _dom.check();
  378. }
  379. };
  380. var _loadO2 = function(){
  381. o2.core = true;
  382. o2.more = true;
  383. // o2.load("o2.core", _dom.check);
  384. // o2.load("o2.more", _dom.check);
  385. };
  386. _addListener(document, 'DOMContentLoaded', _dom.checkReady);
  387. /*<ltIE8>*/
  388. // If doScroll works already, it can't be used to determine domready
  389. // e.g. in an iframe
  390. if (_dom.testElement.doScroll && !_dom.doScrollWorks()){
  391. _dom.checks.push(_dom.doScrollWorks);
  392. _dom.shouldPoll = true;
  393. }
  394. /*</ltIE8>*/
  395. if (document.readyState) _dom.checks.push(function(){
  396. var state = document.readyState;
  397. return (state === 'loaded' || state === 'complete');
  398. });
  399. if ('onreadystatechange' in document) _addListener(document, 'readystatechange', _dom.check);
  400. else _dom.shouldPoll = true;
  401. if (_dom.shouldPoll) _dom.poll();
  402. if (!window.MooTools) this.o2.load("mootools", function(){ _loadO2(); _dom.check(); });
  403. this.o2.addReady = function(fn){ _dom.addReady.call(_dom, fn); };
  404. })();