Everything-Hook

it can hook everything

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/372672/1019316/Everything-Hook.js

  1. // ==UserScript==
  2. // @name Everything-Hook
  3. // @namespace https://gitee.com/HGJing/everthing-hook/
  4. // @updateURL https://gitee.com/HGJing/everthing-hook/raw/master/src/everything-hook.js
  5. // @version 0.5.9056
  6. // @include *
  7. // @description it can hook everything
  8. // @author Cangshi
  9. // @match http://*/*
  10. // @grant none
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. (function webpackUniversalModuleDefinition(root, factory) {
  15. if(typeof exports === 'object' && typeof module === 'object')
  16. module.exports = factory();
  17. else if(typeof define === 'function' && define.amd)
  18. define([], factory);
  19. else {
  20. var a = factory();
  21. for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
  22. }
  23. })(typeof self !== 'undefined' ? self : this, function() {
  24. return /******/ (() => { // webpackBootstrap
  25. /******/ var __webpack_modules__ = ([
  26. /* 0 */
  27. /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
  28.  
  29. "use strict";
  30.  
  31. /**
  32. * ---------------------------
  33. * Time: 2017/9/20 18:33.
  34. * Author: Cangshi
  35. * View: http://palerock.cn
  36. * ---------------------------
  37. */
  38.  
  39.  
  40. const eUtils = __webpack_require__(1);
  41.  
  42. ~(function (global, factory) {
  43.  
  44. "use strict";
  45.  
  46. if ( true && typeof module.exports === "object") {
  47. var results = factory.bind(global)(global, eUtils, true) || [];
  48. var HookJS = {};
  49. results.forEach(function (part) {
  50. HookJS[part.name] = part.module;
  51. });
  52. module.exports = HookJS;
  53. } else {
  54. factory.bind(global)(global, eUtils);
  55. }
  56.  
  57. }(typeof window !== "undefined" ? window : this, function (_global, utils, noGlobal) {
  58. /**
  59. * @namespace EHook
  60. * @author Cangshi
  61. * @constructor
  62. * @see {@link https://palerock.cn/projects/006HDUuOhBj}
  63. * @license Apache License 2.0
  64. */
  65. var EHook = function () {
  66. var _autoId = 1;
  67. var _hookedMap = {};
  68. var _hookedContextMap = {};
  69. this._getHookedMap = function () {
  70. return _hookedMap;
  71. };
  72. this._getHookedContextMap = function () {
  73. return _hookedContextMap;
  74. };
  75. this._getAutoStrId = function () {
  76. return '__auto__' + _autoId++;
  77. };
  78. this._getAutoId = function () {
  79. return _autoId++;
  80. };
  81. };
  82. EHook.prototype = {
  83. /**
  84. * 获取一个对象的劫持id,若没有则创建一个
  85. * @param context
  86. * @return {*}
  87. * @private
  88. */
  89. _getHookedId: function (context) {
  90. var contextMap = this._getHookedContextMap();
  91. var hookedId = null;
  92. Object.keys(contextMap).forEach(key => {
  93. if (context === contextMap[key]) {
  94. hookedId = key;
  95. }
  96. });
  97. if (hookedId == null) {
  98. hookedId = this._getAutoStrId();
  99. contextMap[hookedId] = context;
  100. }
  101. return hookedId;
  102. },
  103. /**
  104. * 获取一个对象的劫持方法映射,若没有则创建一个
  105. * @param context
  106. * @return {*}
  107. * @private
  108. */
  109. _getHookedMethodMap: function (context) {
  110. var hookedId = this._getHookedId(context);
  111. var hookedMap = this._getHookedMap();
  112. var thisTask = hookedMap[hookedId];
  113. if (!utils.isExistObject(thisTask)) {
  114. thisTask = hookedMap[hookedId] = {};
  115. }
  116. return thisTask;
  117. },
  118. /**
  119. * 获取对应方法的hook原型任务对象,若没有则初始化一个。
  120. * @param context
  121. * @param methodName
  122. * @private
  123. */
  124. _getHookedMethodTask: function (context, methodName) {
  125. var thisMethodMap = this._getHookedMethodMap(context);
  126. var thisMethod = thisMethodMap[methodName];
  127. if (!utils.isExistObject(thisMethod)) {
  128. thisMethod = thisMethodMap[methodName] = {
  129. original: undefined,
  130. replace: undefined,
  131. task: {
  132. before: [],
  133. current: undefined,
  134. after: []
  135. }
  136. };
  137. }
  138. return thisMethod;
  139. },
  140. /**
  141. * 执行多个方法并注入一个方法和参数集合
  142. * @param context
  143. * @param methods
  144. * @param args
  145. * @return result 最后一次执行方法的有效返回值
  146. * @private
  147. */
  148. _invokeMethods: function (context, methods, args) {
  149. if (!utils.isArray(methods)) {
  150. return;
  151. }
  152. var result = null;
  153. utils.ergodicArrayObject(context, methods, function (_method) {
  154. if (!utils.isFunction(_method.method)) {
  155. return;
  156. }
  157. var r = _method.method.apply(this, args);
  158. if (r != null) {
  159. result = r;
  160. }
  161. });
  162. return result;
  163. },
  164. /**
  165. * 生成和替换劫持方法
  166. * @param parent
  167. * @param context
  168. * @param methodName {string}
  169. * @private
  170. */
  171. _hook: function (parent, methodName, context) {
  172. if (context === undefined) {
  173. context = parent;
  174. }
  175. var method = parent[methodName];
  176. var methodTask = this._getHookedMethodTask(parent, methodName);
  177. if (!methodTask.original) {
  178. methodTask.original = method;
  179. }
  180. if (utils.isExistObject(methodTask.replace) && utils.isFunction(methodTask.replace.method)) {
  181. parent[methodName] = methodTask.replace.method(methodTask.original);
  182. return;
  183. }
  184. var invokeMethods = this._invokeMethods;
  185. // 组装劫持函数
  186. var builder = new utils.FunctionBuilder(function (v) {
  187. return {
  188. result: undefined
  189. };
  190. });
  191. if (methodTask.task.before.length > 0) {
  192. builder.push(function (v) {
  193. invokeMethods(context || v.this, methodTask.task.before, [methodTask.original, v.arguments]);
  194. });
  195. }
  196. if (utils.isExistObject(methodTask.task.current) && utils.isFunction(methodTask.task.current.method)) {
  197. builder.push(function (v) {
  198. return {
  199. result: methodTask.task.current.method.call(context || v.this, parent, methodTask.original, v.arguments)
  200. }
  201. });
  202. } else {
  203. builder.push(function (v) {
  204. return {
  205. result: methodTask.original.apply(context || v.this, v.arguments)
  206. }
  207. });
  208. }
  209. if (methodTask.task.after.length > 0) {
  210. builder.push(function (v) {
  211. var args = [];
  212. args.push(methodTask.original);
  213. args.push(v.arguments);
  214. args.push(v.result);
  215. var r = invokeMethods(context || v.this, methodTask.task.after, args);
  216. return {
  217. result: (r != null ? r : v.result)
  218. };
  219. });
  220. }
  221. builder.push(function (v) {
  222. return {
  223. returnValue: v.result
  224. };
  225. });
  226. // var methodStr = '(function(){\n';
  227. // methodStr = methodStr + 'var result = undefined;\n';
  228. // if (methodTask.task.before.length > 0) {
  229. // methodStr = methodStr + 'invokeMethods(context, methodTask.task.before,[methodTask.original, arguments]);\n';
  230. // }
  231. // if (utils.isExistObject(methodTask.task.current) && utils.isFunction(methodTask.task.current.method)) {
  232. // methodStr = methodStr + 'result = methodTask.task.current.method.call(context, parent, methodTask.original, arguments);\n';
  233. // } else {
  234. // methodStr = methodStr + 'result = methodTask.original.apply(context, arguments);\n';
  235. // }
  236. // if (methodTask.task.after.length > 0) {
  237. // methodStr = methodStr + 'var args = [];args.push(methodTask.original);args.push(arguments);args.push(result);\n';
  238. // methodStr = methodStr + 'var r = invokeMethods(context, methodTask.task.after, args);result = (r!=null?r:result);\n';
  239. // }
  240. // methodStr = methodStr + 'return result;\n})';
  241. // 绑定劫持函数
  242. var resultFunc = builder.result();
  243. for (var proxyName in methodTask.original) {
  244. Object.defineProperty(resultFunc, proxyName, {
  245. get: function () {
  246. return methodTask.original[proxyName];
  247. },
  248. set: function (v) {
  249. methodTask.original[proxyName] = v;
  250. }
  251. })
  252. }
  253. resultFunc.prototype = methodTask.original.prototype;
  254. parent[methodName] = resultFunc;
  255. },
  256. /**
  257. * 劫持一个方法
  258. * @inner
  259. * @memberOf EHook
  260. * @param parent{Object} 指定方法所在的对象
  261. * @param methodName{String} 指定方法的名称
  262. * @param config{Object} 劫持的配置对象
  263. */
  264. hook: function (parent, methodName, config) {
  265. var hookedFailure = -1;
  266. // 调用方法的上下文
  267. var context = config.context !== undefined ? config.context : parent;
  268. if (parent[methodName] == null) {
  269. parent[methodName] = function () {
  270. }
  271. }
  272. if (!utils.isFunction(parent[methodName])) {
  273. return hookedFailure;
  274. }
  275. var methodTask = this._getHookedMethodTask(parent, methodName);
  276. var id = this._getAutoId();
  277. if (utils.isFunction(config.replace)) {
  278. methodTask.replace = {
  279. id: id,
  280. method: config.replace
  281. };
  282. hookedFailure = 0;
  283. }
  284. if (utils.isFunction(config.before)) {
  285. methodTask.task.before.push({
  286. id: id,
  287. method: config.before
  288. });
  289. hookedFailure = 0;
  290. }
  291. if (utils.isFunction(config.current)) {
  292. methodTask.task.current = {
  293. id: id,
  294. method: config.current
  295. };
  296. hookedFailure = 0;
  297. }
  298. if (utils.isFunction(config.after)) {
  299. methodTask.task.after.push({
  300. id: id,
  301. method: config.after
  302. });
  303. hookedFailure = 0;
  304. }
  305. if (hookedFailure === 0) {
  306. this._hook(parent, methodName, context);
  307. return id;
  308. } else {
  309. return hookedFailure;
  310. }
  311.  
  312. },
  313. /**
  314. * 劫持替换一个方法
  315. * @see 注意:该方法会覆盖指定劫持方法在之前所进行的一切劫持,也不能重复使用,并且不和hookAfter,hookCurrent,hookBefore共存,在同时使用的情况下,优先使用hookReplace而不是其他的方法
  316. * @inner
  317. * @memberOf EHook
  318. * @param parent{Object} 指定方法所在的对象
  319. * @param context{Object=} 回调方法的上下文
  320. * @param methodName{String} 指定方法的名称
  321. * @param replace {function} 回调方法,该方法的返回值便是替换的方法 回调参数及返回值:[ method:指定的原方法,类型:function return:规定被替换的方法内容,类型:function ]
  322. * @return {number} 该次劫持的id
  323. */
  324. hookReplace: function (parent, methodName, replace, context) {
  325. return this.hook(parent, methodName, {
  326. replace: replace,
  327. context: context
  328. });
  329. },
  330. /**
  331. * 在指定方法前执行
  332. * @inner
  333. * @memberOf EHook
  334. * @param parent{Object} 指定方法所在的对象
  335. * @param methodName{String} 指定方法的名称
  336. * @param before{function} 回调方法,该方法在指定方法运行前执行 回调参数:[ method:指定的原方法 args:原方法运行的参数(在此改变参数值会影响后续指定方法的参数值) ]
  337. * @param context{Object=} 回调方法的上下文
  338. * @returns {number} 劫持id(用于解除劫持)
  339. */
  340. hookBefore: function (parent, methodName, before, context) {
  341. return this.hook(parent, methodName, {
  342. before: before,
  343. context: context
  344. });
  345. },
  346. /**
  347. * 劫持方法的运行,在对制定方法进行该劫持的时候,指定方法不会主动执行,替换为执行参数中的current方法
  348. * @see 注意:该方法只能对指定方法进行一次劫持,若再次使用该方法劫持就会覆盖之前的劫持[可以和hookBefore,hookAfter共存,且hookBefore和hookAfter可以对同个指定方法多次劫持]
  349. * @inner
  350. * @memberOf EHook
  351. * @param parent{Object} 指定方法所在的对象
  352. * @param methodName{String} 指定方法的名称
  353. * @param current{function} 回调方法,该方法在指定方法被调用时执行 回调参数及返回值:[ parent:指定方法所在的对象,类型:object method:指定的原方法,类型:function args:原方法的参数,类型:array return:规定被劫持方法的返回值,类型:* ]
  354. * @param context{Object=} 回调方法的上下文
  355. * @returns {number} 劫持id(用于解除劫持)
  356. */
  357. hookCurrent: function (parent, methodName, current, context) {
  358. return this.hook(parent, methodName, {
  359. current: current,
  360. context: context
  361. });
  362. },
  363. /**
  364. * 在指定方法后执行
  365. * @inner
  366. * @memberOf EHook
  367. * @param parent{Object} 指定方法所在的对象
  368. * @param methodName{String} 指定方法的名称
  369. * @param after{function} 回调方法,该方法在指定方法运行后执行 回调参数及返回值:[ method:指定的原方法,类型:function args:原方法的参数,类型:array result:原方法的返回值,类型:* return:规定被劫持方法的返回值,类型:* ]
  370. * @param context{Object=} 回调方法的上下文
  371. * @returns {number} 劫持id(用于解除劫持)
  372. */
  373. hookAfter: function (parent, methodName, after, context) {
  374. return this.hook(parent, methodName, {
  375. after: after,
  376. context: context
  377. });
  378. },
  379. hookClass: function (parent, className, replace, innerName, excludeProperties) {
  380. var _this = this;
  381. var originFunc = parent[className];
  382. if (!excludeProperties) {
  383. excludeProperties = [];
  384. }
  385. excludeProperties.push('prototype');
  386. excludeProperties.push('caller');
  387. excludeProperties.push('arguments');
  388. innerName = innerName || '_innerHook';
  389. var resFunc = function () {
  390. this[innerName] = new originFunc();
  391. replace.apply(this, arguments);
  392. };
  393. this.hookedToString(originFunc, resFunc);
  394. this.hookedToProperties(originFunc, resFunc, true, excludeProperties);
  395. var prototypeProperties = Object.getOwnPropertyNames(originFunc.prototype);
  396. var prototype = resFunc.prototype = {
  397. constructor: resFunc
  398. };
  399. prototypeProperties.forEach(function (name) {
  400. if (name === 'constructor') {
  401. return;
  402. }
  403. var method = function () {
  404. if (originFunc.prototype[name] && utils.isFunction(originFunc.prototype[name])) {
  405. return originFunc.prototype[name].apply(this[innerName], arguments);
  406. }
  407. return undefined;
  408. };
  409. _this.hookedToString(originFunc.prototype[name], method);
  410. prototype[name] = method;
  411. });
  412. this.hookReplace(parent, className, function () {
  413. return resFunc;
  414. }, parent)
  415. },
  416. hookedToProperties: function (originObject, resultObject, isDefined, excludeProperties) {
  417. var objectProperties = Object.getOwnPropertyNames(originObject);
  418. objectProperties.forEach(function (property) {
  419. if (utils.contains(excludeProperties, property)) {
  420. return;
  421. }
  422. if (!isDefined) {
  423. resultObject[property] = originObject[property];
  424. } else {
  425. Object.defineProperty(resultObject, property, {
  426. configurable: false,
  427. enumerable: false,
  428. value: originObject[property],
  429. writable: false
  430. });
  431. }
  432. });
  433. },
  434. hookedToString: function (originObject, resultObject) {
  435. Object.defineProperties(resultObject, {
  436. toString: {
  437. configurable: false,
  438. enumerable: false,
  439. value: originObject.toString.bind(originObject),
  440. writable: false
  441. },
  442. toLocaleString: {
  443. configurable: false,
  444. enumerable: false,
  445. value: originObject.toLocaleString.bind(originObject),
  446. writable: false
  447. }
  448. })
  449. },
  450. /**
  451. * 劫持全局ajax
  452. * @inner
  453. * @memberOf EHook
  454. * @param methods {object} 劫持的方法
  455. * @return {*|number} 劫持的id
  456. */
  457. hookAjax: function (methods) {
  458. if (this.isHooked(_global, 'XMLHttpRequest')) {
  459. return;
  460. }
  461. var _this = this;
  462. var hookMethod = function (methodName) {
  463. if (utils.isFunction(methods[methodName])) {
  464. // 在执行方法之前hook原方法
  465. _this.hookBefore(this.xhr, methodName, methods[methodName]);
  466. }
  467. // 返回方法调用内部的xhr
  468. return this.xhr[methodName].bind(this.xhr);
  469. };
  470. var getProperty = function (attr) {
  471. return function () {
  472. return this.hasOwnProperty(attr + "_") ? this[attr + "_"] : this.xhr[attr];
  473. };
  474. };
  475. var setProperty = function (attr) {
  476. return function (f) {
  477. var xhr = this.xhr;
  478. var that = this;
  479. if (attr.indexOf("on") !== 0) {
  480. this[attr + "_"] = f;
  481. return;
  482. }
  483. if (methods[attr]) {
  484. xhr[attr] = function () {
  485. f.apply(xhr, arguments);
  486. };
  487. // on方法在set时劫持
  488. _this.hookBefore(xhr, attr, methods[attr]);
  489. // console.log(1,attr);
  490. // xhr[attr] = function () {
  491. // methods[attr](that) || f.apply(xhr, arguments);
  492. // }
  493. } else {
  494. xhr[attr] = f;
  495. }
  496. };
  497. };
  498. return this.hookReplace(_global, 'XMLHttpRequest', function (XMLHttpRequest) {
  499. var resFunc = function () {
  500. this.xhr = new XMLHttpRequest();
  501. for (var propertyName in this.xhr) {
  502. var property = this.xhr[propertyName];
  503. if (utils.isFunction(property)) {
  504. // hook 原方法
  505. this[propertyName] = hookMethod.bind(this)(propertyName);
  506. } else {
  507. Object.defineProperty(this, propertyName, {
  508. get: getProperty(propertyName),
  509. set: setProperty(propertyName)
  510. });
  511. }
  512. }
  513. // 定义外部xhr可以在内部访问
  514. this.xhr.xhr = this;
  515. };
  516. _this.hookedToProperties(XMLHttpRequest, resFunc, true);
  517. _this.hookedToString(XMLHttpRequest, resFunc);
  518. return resFunc
  519. });
  520. },
  521. /**
  522. * 劫持全局ajax
  523. * @param methods {object} 劫持的方法
  524. * @return {*|number} 劫持的id
  525. */
  526. hookAjaxV2: function (methods) {
  527. this.hookClass(window, 'XMLHttpRequest', function () {
  528.  
  529. });
  530. utils.ergodicObject(this, methods, function (method) {
  531.  
  532. });
  533. },
  534. /**
  535. * 解除劫持
  536. * @inner
  537. * @memberOf EHook
  538. * @param context 上下文
  539. * @param methodName 方法名
  540. * @param isDeeply {boolean=} 是否深度解除[默认为false]
  541. * @param eqId {number=} 解除指定id的劫持[可选]
  542. */
  543. unHook: function (context, methodName, isDeeply, eqId) {
  544. if (!context[methodName] || !utils.isFunction(context[methodName])) {
  545. return;
  546. }
  547. var methodTask = this._getHookedMethodTask(context, methodName);
  548. if (eqId) {
  549. if (this.unHookById(eqId)) {
  550. return;
  551. }
  552. }
  553. if (!methodTask.original) {
  554. delete this._getHookedMethodMap(context)[methodName];
  555. return;
  556. }
  557. context[methodName] = methodTask.original;
  558. if (isDeeply) {
  559. delete this._getHookedMethodMap(context)[methodName];
  560. }
  561. },
  562. /**
  563. * 通过Id解除劫持
  564. * @inner
  565. * @memberOf EHook
  566. * @param eqId
  567. * @returns {boolean}
  568. */
  569. unHookById: function (eqId) {
  570. var hasEq = false;
  571. if (eqId) {
  572. var hookedMap = this._getHookedMap();
  573. utils.ergodicObject(this, hookedMap, function (contextMap) {
  574. utils.ergodicObject(this, contextMap, function (methodTask) {
  575. methodTask.task.before = methodTask.task.before.filter(function (before) {
  576. hasEq = hasEq || before.id === eqId;
  577. return before.id !== eqId;
  578. });
  579. methodTask.task.after = methodTask.task.after.filter(function (after) {
  580. hasEq = hasEq || after.id === eqId;
  581. return after.id !== eqId;
  582. });
  583. if (methodTask.task.current && methodTask.task.current.id === eqId) {
  584. methodTask.task.current = undefined;
  585. hasEq = true;
  586. }
  587. if (methodTask.replace && methodTask.replace.id === eqId) {
  588. methodTask.replace = undefined;
  589. hasEq = true;
  590. }
  591. })
  592. });
  593. }
  594. return hasEq;
  595. },
  596. /**
  597. * 移除所有劫持相关的方法
  598. * @inner
  599. * @memberOf EHook
  600. * @param context 上下文
  601. * @param methodName 方法名
  602. */
  603. removeHookMethod: function (context, methodName) {
  604. if (!context[methodName] || !utils.isFunction(context[methodName])) {
  605. return;
  606. }
  607. this._getHookedMethodMap(context)[methodName] = {
  608. original: undefined,
  609. replace: undefined,
  610. task: {
  611. before: [],
  612. current: undefined,
  613. after: []
  614. }
  615. };
  616. },
  617. /**
  618. * 判断一个方法是否被劫持过
  619. * @inner
  620. * @memberOf EHook
  621. * @param context
  622. * @param methodName
  623. */
  624. isHooked: function (context, methodName) {
  625. var hookMap = this._getHookedMethodMap(context);
  626. return hookMap[methodName] !== undefined ? (hookMap[methodName].original !== undefined) : false;
  627. },
  628. /**
  629. * 保护一个对象使之不会被篡改
  630. * @inner
  631. * @memberOf EHook
  632. * @param parent
  633. * @param methodName
  634. */
  635. protect: function (parent, methodName) {
  636. Object.defineProperty(parent, methodName, {
  637. configurable: false,
  638. writable: false
  639. });
  640. },
  641. preventError: function (parent, methodName, returnValue, context) {
  642. this.hookCurrent(parent, methodName, function (m, args) {
  643. var value = returnValue;
  644. try {
  645. value = m.apply(this, args);
  646. } catch (e) {
  647. console.log('Error Prevented from method ' + methodName, e);
  648. }
  649. return value;
  650. }, context)
  651. },
  652. /**
  653. * 装载插件
  654. * @inner
  655. * @memberOf EHook
  656. * @param option
  657. */
  658. plugins: function (option) {
  659. if (utils.isFunction(option.mount)) {
  660. var result = option.mount.call(this, utils);
  661. if (typeof option.name === 'string') {
  662. _global[option.name] = result;
  663. }
  664. }
  665. }
  666. };
  667. if (_global.eHook && (_global.eHook instanceof EHook)) {
  668. return;
  669. }
  670. var eHook = new EHook();
  671. /**
  672. * @namespace AHook
  673. * @author Cangshi
  674. * @constructor
  675. * @see {@link https://palerock.cn/projects/006HDUuOhBj}
  676. * @license Apache License 2.0
  677. */
  678. var AHook = function () {
  679. this.isHooked = false;
  680. var autoId = 1;
  681. this._urlDispatcherList = [];
  682. this._getAutoId = function () {
  683. return autoId++;
  684. };
  685. };
  686. AHook.prototype = {
  687. /**
  688. * 执行配置列表中的指定方法组
  689. * @param xhr
  690. * @param methodName
  691. * @param args
  692. * @private
  693. */
  694. _invokeAimMethods: function (xhr, methodName, args) {
  695. var configs = utils.parseArrayByProperty(xhr.patcherList, 'config');
  696. var methods = [];
  697. utils.ergodicArrayObject(xhr, configs, function (config) {
  698. if (utils.isFunction(config[methodName])) {
  699. methods.push(config[methodName]);
  700. }
  701. });
  702. return utils.invokeMethods(xhr, methods, args);
  703. },
  704. /**
  705. * 根据url获取配置列表
  706. * @param url
  707. * @return {Array}
  708. * @private
  709. */
  710. _urlPatcher: function (url) {
  711. var patcherList = [];
  712. utils.ergodicArrayObject(this, this._urlDispatcherList, function (patcherMap, i) {
  713. if (utils.UrlUtils.urlMatching(url, patcherMap.patcher)) {
  714. patcherList.push(patcherMap);
  715. }
  716. });
  717. return patcherList;
  718. },
  719. /**
  720. * 根据xhr对象分发回调请求
  721. * @param xhr
  722. * @param fullUrl
  723. * @private
  724. */
  725. _xhrDispatcher: function (xhr, fullUrl) {
  726. var url = utils.UrlUtils.getUrlWithoutParam(fullUrl);
  727. xhr.patcherList = this._urlPatcher(url);
  728. },
  729. /**
  730. * 转换响应事件
  731. * @param e
  732. * @param xhr
  733. * @private
  734. */
  735. _parseEvent: function (e, xhr) {
  736. try {
  737. Object.defineProperties(e, {
  738. target: {
  739. get: function () {
  740. return xhr;
  741. }
  742. },
  743. srcElement: {
  744. get: function () {
  745. return xhr;
  746. }
  747. }
  748. });
  749. } catch (error) {
  750. console.warn('重定义返回事件失败,劫持响应可能失败');
  751. }
  752. return e;
  753. },
  754. /**
  755. * 解析open方法的参数
  756. * @param args
  757. * @private
  758. */
  759. _parseOpenArgs: function (args) {
  760. return {
  761. method: args[0],
  762. fullUrl: args[1],
  763. url: utils.UrlUtils.getUrlWithoutParam(args[1]),
  764. params: utils.UrlUtils.getParamFromUrl(args[1]),
  765. async: args[2]
  766. };
  767. },
  768. /**
  769. * 劫持ajax 请求参数
  770. * @param argsObject
  771. * @param argsArray
  772. * @private
  773. */
  774. _rebuildOpenArgs: function (argsObject, argsArray) {
  775. argsArray[0] = argsObject.method;
  776. argsArray[1] = utils.UrlUtils.margeUrlAndParams(argsObject.url, argsObject.params);
  777. argsArray[2] = argsObject.async;
  778. },
  779. /**
  780. * 获取劫持方法的参数 [原方法,原方法参数,原方法返回值],剔除原方法参数
  781. * @param args
  782. * @return {*|Array.<T>}
  783. * @private
  784. */
  785. _getHookedArgs: function (args) {
  786. // 将参数中'原方法'剔除
  787. return Array.prototype.slice.call(args, 0).splice(1);
  788. },
  789. /**
  790. * 响应被触发时调用的方法
  791. * @param outerXhr
  792. * @param funcArgs
  793. * @private
  794. */
  795. _onResponse: function (outerXhr, funcArgs) {
  796. // 因为参数是被劫持的参数为[method(原方法),args(参数)],该方法直接获取参数并转换为数组
  797. var args = this._getHookedArgs(funcArgs);
  798. args[0][0] = this._parseEvent(args[0][0], outerXhr.xhr); // 强制事件指向外部xhr
  799. // 执行所有的名为hookResponse的方法组
  800. var results = this._invokeAimMethods(outerXhr, 'hookResponse', args);
  801. // 遍历结果数组并获取最后返回的有效的值作为响应值
  802. var resultIndex = -1;
  803. utils.ergodicArrayObject(outerXhr, results, function (res, i) {
  804. if (res != null) {
  805. resultIndex = i;
  806. }
  807. });
  808. if (resultIndex !== -1) {
  809. outerXhr.xhr.responseText_ = outerXhr.xhr.response_ = results[resultIndex];
  810. }
  811. },
  812. /**
  813. * 手动开始劫持
  814. * @inner
  815. * @memberOf AHook
  816. */
  817. startHook: function () {
  818. var _this = this;
  819. var normalMethods = {
  820. // 方法中的this指向内部xhr
  821. // 拦截响应
  822. onreadystatechange: function () {
  823. if (this.readyState == 4 && this.status == 200 || this.status == 304) {
  824. _this._onResponse(this, arguments);
  825. }
  826. },
  827. onload: function () {
  828. _this._onResponse(this, arguments);
  829. },
  830. // 拦截请求
  831. open: function () {
  832. var args = _this._getHookedArgs(arguments);
  833. var fullUrl = args[0][1];
  834. _this._xhrDispatcher(this, fullUrl);
  835. var argsObject = _this._parseOpenArgs(args[0]);
  836. this.openArgs = argsObject;
  837. _this._invokeAimMethods(this, 'hookRequest', [argsObject]);
  838. _this._rebuildOpenArgs(argsObject, args[0]);
  839. },
  840. send: function () {
  841. var args = _this._getHookedArgs(arguments);
  842. this.sendArgs = args;
  843. _this._invokeAimMethods(this, 'hookSend', args);
  844. }
  845. };
  846. // 设置总的hookId
  847. this.___hookedId = _global.eHook.hookAjax(normalMethods);
  848. this.isHooked = true;
  849. },
  850. /**
  851. * 注册ajaxUrl拦截
  852. * @inner
  853. * @memberOf AHook
  854. * @param urlPatcher
  855. * @param configOrRequest
  856. * @param response
  857. * @return {number}
  858. */
  859. register: function (urlPatcher, configOrRequest, response) {
  860. if (!urlPatcher) {
  861. return -1;
  862. }
  863. if (!utils.isExistObject(configOrRequest) && !utils.isFunction(response)) {
  864. return -1;
  865. }
  866. var config = {};
  867. if (utils.isFunction(configOrRequest)) {
  868. config.hookRequest = configOrRequest;
  869. }
  870. if (utils.isFunction(response)) {
  871. config.hookResponse = response;
  872. }
  873. if (utils.isExistObject(configOrRequest)) {
  874. config = configOrRequest;
  875. }
  876. var id = this._getAutoId();
  877. this._urlDispatcherList.push({
  878. // 指定id便于后续取消
  879. id: id,
  880. patcher: urlPatcher,
  881. config: config
  882. });
  883. // 当注册一个register时,自动开始运行劫持
  884. if (!this.isHooked) {
  885. this.startHook();
  886. }
  887. return id;
  888. }
  889. // todo 注销 cancellation: function (registerId){};
  890. };
  891.  
  892. _global['eHook'] = eHook;
  893. _global['aHook'] = new AHook();
  894.  
  895. return [{
  896. name: 'eHook',
  897. module: eHook
  898. }, {
  899. name: 'aHook',
  900. module: _global['aHook']
  901. }]
  902.  
  903. }));
  904.  
  905. /***/ }),
  906. /* 1 */
  907. /***/ (function(module) {
  908.  
  909. (function (global, factory) {
  910.  
  911. "use strict";
  912.  
  913. if ( true && typeof module.exports === "object") {
  914. module.exports = factory(global, true);
  915. } else {
  916. factory(global);
  917. }
  918.  
  919. }(typeof window !== "undefined" ? window : this, function (_global, noGlobal) {
  920.  
  921. var map = Array.prototype.map;
  922. var forEach = Array.prototype.forEach;
  923. var reduce = Array.prototype.reduce;
  924.  
  925. var BaseUtils = {
  926. /**
  927. * 对象是否为数组
  928. * @param arr
  929. */
  930. isArray: function (arr) {
  931. return Array.isArray(arr) || Object.prototype.toString.call(arr) === "[object Array]";
  932. },
  933. /**
  934. * 判断是否为方法
  935. * @param func
  936. * @return {boolean}
  937. */
  938. isFunction: function (func) {
  939. if (!func) {
  940. return false;
  941. }
  942. return typeof func === 'function';
  943. },
  944. /**
  945. * 判断是否是一个有效的对象
  946. * @param obj
  947. * @return {*|boolean}
  948. */
  949. isExistObject: function (obj) {
  950. return obj && (typeof obj === 'object');
  951. },
  952. isString: function (str) {
  953. if (str === null) {
  954. return false;
  955. }
  956. return typeof str === 'string';
  957. },
  958. uniqueNum: 1000,
  959. /**
  960. * 根据当前时间戳生产一个随机id
  961. * @returns {string}
  962. */
  963. buildUniqueId: function () {
  964. var prefix = new Date().getTime().toString();
  965. var suffix = this.uniqueNum.toString();
  966. this.uniqueNum++;
  967. return prefix + suffix;
  968. }
  969. };
  970.  
  971. //
  972. var serviceProvider = {
  973. _parseDepends: function (depends) {
  974. var dependsArr = [];
  975. if (!BaseUtils.isArray(depends)) {
  976. return;
  977. }
  978. forEach.call(depends, function (depend) {
  979. if (BaseUtils.isString(depend)) {
  980. dependsArr.push(serviceProvider[depend.toLowerCase()]);
  981. }
  982. });
  983. return dependsArr;
  984. }
  985. };
  986.  
  987. var factory = function (name, depends, construction) {
  988. if (!BaseUtils.isFunction(construction)) {
  989. return;
  990. }
  991. serviceProvider[name.toLowerCase()] = construction.apply(this, serviceProvider._parseDepends(depends));
  992. };
  993.  
  994. var depend = function (depends, construction) {
  995. if (!BaseUtils.isFunction(construction)) {
  996. return;
  997. }
  998. construction.apply(this, serviceProvider._parseDepends(depends));
  999. };
  1000.  
  1001. factory('BaseUtils', [], function () {
  1002. return BaseUtils;
  1003. });
  1004.  
  1005. // logger
  1006. factory('logger', [], function () {
  1007. return console;
  1008. });
  1009.  
  1010. // DateTimeUtils
  1011. factory('DateTimeUtils', ['logger'], function (logger) {
  1012. return {
  1013. /**
  1014. * 打印当前时间
  1015. */
  1016. printNowTime: function () {
  1017. var date = new Date();
  1018. console.log(this.pattern(date, 'hh:mm:ss:S'));
  1019. },
  1020. /**
  1021. * 格式化日期
  1022. * @param date
  1023. * @param fmt
  1024. * @returns {*}
  1025. */
  1026. pattern: function (date, fmt) {
  1027. var o = {
  1028. "M+": date.getMonth() + 1, //月份
  1029. "d+": date.getDate(), //日
  1030. "h+": date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, //小时
  1031. "H+": date.getHours(), //小时
  1032. "m+": date.getMinutes(), //分
  1033. "s+": date.getSeconds(), //秒
  1034. "q+": Math.floor((date.getMonth() + 3) / 3), //季度
  1035. "S": date.getMilliseconds() //毫秒
  1036. };
  1037. var week = {
  1038. "0": "/u65e5",
  1039. "1": "/u4e00",
  1040. "2": "/u4e8c",
  1041. "3": "/u4e09",
  1042. "4": "/u56db",
  1043. "5": "/u4e94",
  1044. "6": "/u516d"
  1045. };
  1046. if (/(y+)/.test(fmt)) {
  1047. fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  1048. }
  1049. if (/(E+)/.test(fmt)) {
  1050. fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[date.getDay() + ""]);
  1051. }
  1052. for (var k in o) {
  1053. if (new RegExp("(" + k + ")").test(fmt)) {
  1054. fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  1055. }
  1056. }
  1057. return fmt;
  1058. },
  1059. /**
  1060. * 以当前时间获取id
  1061. * @returns {number}
  1062. */
  1063. getCurrentId: function () {
  1064. var date = new Date();
  1065. return date.getTime();
  1066. },
  1067. /**
  1068. * 获取指定时间距离现在相差多久
  1069. * @param date {number|Date}
  1070. * @param isCeil{boolean=} 是否对结果向上取整,默认[false]
  1071. * @param type {string=} 单位可取值['day','month','year']默认'day'
  1072. * @returns {number}
  1073. */
  1074. getNowBetweenADay: function (date, isCeil, type) {
  1075. if (!type) {
  1076. type = 'day'
  1077. }
  1078. if (typeof date === 'number') {
  1079. date = new Date(date);
  1080. }
  1081. if (!(date instanceof Date)) {
  1082. throw new TypeError('该参数类型必须是Date')
  1083. }
  1084. var time = date.getTime();
  1085. var now = new Date();
  1086. var nowTime = now.getTime();
  1087. if (nowTime - time < 0) {
  1088. logger.warn('需要计算的时间必须在当前时间之前');
  1089. }
  1090. var result = 0;
  1091. switch (type) {
  1092. default:
  1093. case 'day':
  1094. result = (nowTime - time) / (1000 * 60 * 60 * 24);
  1095. break;
  1096. case 'month':
  1097. var yearDifference = now.getFullYear() - date.getFullYear();
  1098. if (yearDifference > 0) {
  1099. result += yearDifference * 12;
  1100. }
  1101. result += now.getMonth() - date.getMonth();
  1102. break;
  1103. case 'year':
  1104. result += now.getFullYear() - date.getFullYear();
  1105. break;
  1106. }
  1107. if (!isCeil) {
  1108. return Math.floor(result);
  1109. } else {
  1110. if (result === 0 && isCeil) {
  1111. result = 1;
  1112. }
  1113. return Math.ceil(result);
  1114. }
  1115. }
  1116. }
  1117. });
  1118.  
  1119. // ArrayUtils
  1120. factory('ArrayUtils', ['BaseUtils'], function (BaseUtils) {
  1121. return {
  1122. isArrayObject: function (arr) {
  1123. return BaseUtils.isArray(arr);
  1124. },
  1125. /**
  1126. * 遍历数组
  1127. * @param context {Object}
  1128. * @param arr {Array}
  1129. * @param cb {Function} 回调函数
  1130. */
  1131. ergodicArrayObject: function (context, arr, cb) {
  1132. if (!context) {
  1133. context = _global;
  1134. }
  1135. if (!BaseUtils.isArray(arr) || !BaseUtils.isFunction(cb)) {
  1136. return;
  1137. }
  1138. for (var i = 0; i < arr.length; i++) {
  1139. var result = cb.call(context, arr[i], i);
  1140. if (result && result === -1) {
  1141. break;
  1142. }
  1143. }
  1144. },
  1145. /**
  1146. * 获取数组对象的一个属性发起动作
  1147. * @param context {Object}
  1148. * @param arr {Array}
  1149. * @param propertyName {String}
  1150. * @param cb {Function}
  1151. * @param checkProperty {boolean} 是否排除不拥有该属性的对象[default:true]
  1152. */
  1153. getPropertyDo: function (context, arr, propertyName, cb, checkProperty) {
  1154. if (checkProperty === null) {
  1155. checkProperty = true;
  1156. }
  1157. this.ergodicArrayObject(context, arr, function (ele) {
  1158. if (!checkProperty || ele.hasOwnProperty(propertyName)) {
  1159. cb.call(context, ele[propertyName], ele);
  1160. }
  1161. })
  1162. },
  1163. /**
  1164. * [私有方法]将多个键值对对象转换为map
  1165. * @param arr {Array}
  1166. * @returns {{}}
  1167. */
  1168. parseKeyValue: function (arr) {
  1169. var map = {};
  1170. if (!(BaseUtils.isArray(arr))) {
  1171. return map;
  1172. }
  1173. this.ergodicArrayObject(this, arr, function (ele) {
  1174. if (ele.key === null) {
  1175. return;
  1176. }
  1177. if (!map.hasOwnProperty(ele.key)) {
  1178. map[ele.key] = ele.value;
  1179. }
  1180. });
  1181. return map;
  1182. },
  1183. /**
  1184. * 获取数组的哈希码
  1185. * @param arr {Array}
  1186. * @returns {number}
  1187. */
  1188. getHashCode: function (arr) {
  1189. var str = arr.toString();
  1190. var hash = 31;
  1191. if (str.length === 0) return hash;
  1192. for (var i = 0; i < str.length; i++) {
  1193. var char = str.charCodeAt(i);
  1194. hash = ((hash << 5) - hash) + char;
  1195. hash = hash & hash; // Convert to 32bit integer
  1196. }
  1197. return hash;
  1198. },
  1199. /**
  1200. * 通过数组中每个对象的指定属性生成一个新数组
  1201. * @param arr {Array}
  1202. * @param propertyName {String}
  1203. */
  1204. parseArrayByProperty: function (arr, propertyName) {
  1205. var result = [];
  1206. if (!this.isArrayObject(arr)) {
  1207. return result;
  1208. }
  1209. this.getPropertyDo(this, arr, propertyName, function (value) {
  1210. result.push(value);
  1211. }, true);
  1212. return result;
  1213. },
  1214. /**
  1215. * 数组对象是否包含一个对象
  1216. * @param arr {Array}
  1217. * @param obj
  1218. * @param cb {function=}
  1219. * @returns {boolean}
  1220. */
  1221. isContainsObject: function (arr, obj, cb) {
  1222. var isContainsObject = false;
  1223. this.ergodicArrayObject(this, arr, function (value, i) {
  1224. if (obj === value) {
  1225. isContainsObject = true;
  1226. if (BaseUtils.isFunction(cb)) {
  1227. cb.call(_global, i);
  1228. }
  1229. return -1;
  1230. }
  1231. });
  1232. return isContainsObject;
  1233. },
  1234. /**
  1235. * 获取数组中的最大值
  1236. * @param arr 若数组中的对象还是数组,则按里面数组的每个对象进行多级比较
  1237. * @param cb
  1238. * @returns {*}
  1239. */
  1240. getMaxInArray: function (arr, cb) {
  1241. var maxObject = null;
  1242. var maxIndex = -1;
  1243. while (maxObject === null && maxIndex < arr.length) {
  1244. maxObject = arr[++maxIndex]
  1245. }
  1246. for (var i = maxIndex + 1; i < arr.length; i++) {
  1247. // 若是比较对象都是数组,则对每个数组的第一个元素进行比较,若相同,则比较第二个元素
  1248. if (maxObject !== null && this.isArrayObject(maxObject) && this.isArrayObject(arr[i])) {
  1249. var classLength = maxObject.length;
  1250. var classLevel = 0;
  1251. // console.log(maxObject[classLevel],arr[i][classLevel]);
  1252. while (maxObject[classLevel] === arr[i][classLevel] && classLevel < classLength) {
  1253. classLevel++
  1254. }
  1255. if (maxObject[classLevel] !== null && maxObject[classLevel] < arr[i][classLevel]) {
  1256. maxObject = arr[i];
  1257. maxIndex = i;
  1258. }
  1259. continue;
  1260. }
  1261. if (maxObject !== null && maxObject < arr[i]) {
  1262. maxObject = arr[i];
  1263. maxIndex = i;
  1264. }
  1265. }
  1266. if (BaseUtils.isFunction(cb)) {
  1267. cb.call(this, maxObject, maxIndex);
  1268. }
  1269. return maxObject;
  1270. },
  1271. /**
  1272. * 获取数组中的总值
  1273. * @param arr{Array<number>}
  1274. * @param cb {function=}
  1275. */
  1276. getSumInArray: function (arr, cb) {
  1277. if (!this.isArrayObject(arr)) {
  1278. return;
  1279. }
  1280. var sum = 0;
  1281. var count = 0;
  1282. this.ergodicArrayObject(this, arr, function (value) {
  1283. if (typeof value === 'number' && !Number.isNaN(value)) {
  1284. sum += value;
  1285. count += 1;
  1286. }
  1287. });
  1288. if (BaseUtils.isFunction(cb)) {
  1289. cb.call(_global, sum, count);
  1290. }
  1291. return sum;
  1292. },
  1293. /**
  1294. * 获取数组中的平均值
  1295. * @param arr{Array<number>}
  1296. */
  1297. getAverageInArray: function (arr) {
  1298. var average = 0;
  1299. this.getSumInArray(arr, function (sum, i) {
  1300. i === 0 || (average = sum / i);
  1301. });
  1302. return average;
  1303. },
  1304. /**
  1305. * 为数组排序
  1306. * @param arr
  1307. * @param order
  1308. * @param sortSetting {object=}
  1309. */
  1310. sortingArrays: function (arr, order, sortSetting) {
  1311. if (!this.isArrayObject(arr)) {
  1312. return;
  1313. }
  1314. var DESC = 0;
  1315. var ASC = 1;
  1316. var thisArr = arr.slice(0);
  1317. var _thisAction = null;
  1318. // 解析配置
  1319. var isSetting = sortSetting && sortSetting.getComparedProperty &&
  1320. BaseUtils.isFunction(sortSetting.getComparedProperty);
  1321. if (isSetting) {
  1322. thisArr = sortSetting.getComparedProperty(arr);
  1323. }
  1324. switch (order) {
  1325. default :
  1326. case DESC:
  1327. _thisAction = thisArr.push;
  1328. break;
  1329. case ASC:
  1330. _thisAction = thisArr.unshift;
  1331. break;
  1332. }
  1333. var resultArr = [];
  1334. for (var j = 0; j < thisArr.length; j++) {
  1335. this.getMaxInArray(thisArr, function (max, i) {
  1336. delete thisArr[i];
  1337. _thisAction.call(resultArr, arr[i]);
  1338. });
  1339. }
  1340. if (sortSetting && sortSetting.createNewData) {
  1341. return resultArr.slice(0);
  1342. }
  1343. return resultArr;
  1344. },
  1345. /**
  1346. * 将类数组转化为数组
  1347. * @param arrLike 类数组对象
  1348. */
  1349. toArray: function (arrLike) {
  1350. if (!arrLike || arrLike.length === 0) {
  1351. return [];
  1352. }
  1353. // 非伪类对象,直接返回最好
  1354. if (!arrLike.length) {
  1355. return arrLike;
  1356. }
  1357. // 针对IE8以前 DOM的COM实现
  1358. try {
  1359. return [].slice.call(arrLike);
  1360. } catch (e) {
  1361. var i = 0,
  1362. j = arrLike.length,
  1363. res = [];
  1364. for (; i < j; i++) {
  1365. res.push(arrLike[i]);
  1366. }
  1367. return res;
  1368. }
  1369. },
  1370. /**
  1371. * 判断是否为类数组
  1372. * @param o
  1373. * @returns {boolean}
  1374. */
  1375. isArrayLick: function (o) {
  1376. if (o && // o is not null, undefined, etc.
  1377. typeof o === 'object' && // o is an object
  1378. isFinite(o.length) && // o.length is a finite number
  1379. o.length >= 0 && // o.length is non-negative
  1380. o.length === Math.floor(o.length) && // o.length is an integer
  1381. o.length < 4294967296) // o.length < 2^32
  1382. return true; // Then o is array-like
  1383. else
  1384. return false; // Otherwise it is not
  1385.  
  1386. },
  1387. /**
  1388. * 判断数组是否包含对象
  1389. * @param arr
  1390. * @param obj
  1391. */
  1392. contains: function (arr, obj) {
  1393. var contains = false;
  1394. this.ergodicArrayObject(this, arr, function (a) {
  1395. if (a === obj) {
  1396. contains = true;
  1397. return -1;
  1398. }
  1399. });
  1400. return contains;
  1401. }
  1402. }
  1403. });
  1404.  
  1405. // ObjectUtils
  1406. factory('ObjectUtils', ['ArrayUtils', 'BaseUtils'], function (ArrayUtils, BaseUtils) {
  1407. return {
  1408. /**
  1409. * 获取对象属性[支持链式表达式,如获取学生所在班级所在的学校(student.class.school):'class.school']
  1410. * @param obj
  1411. * @param linkProperty {string|Array} 属性表达式,获取多个属性则用数组
  1412. * @param cb {function=}
  1413. * @return 对象属性
  1414. */
  1415. readLinkProperty: function (obj, linkProperty, cb) {
  1416. var callback = null;
  1417. if (BaseUtils.isFunction(cb)) {
  1418. callback = cb;
  1419. }
  1420. if (typeof linkProperty === 'string') {
  1421. // 除去所有的空格
  1422. linkProperty = linkProperty.replace(/ /g, '');
  1423. // 不判断为空的值
  1424. if (linkProperty === '') {
  1425. return null;
  1426. }
  1427. // 若是以','隔开的伪数组,则转化为数组再进行操作
  1428. if (linkProperty.indexOf(',') !== -1) {
  1429. var propertyNameArr = linkProperty.split(',');
  1430. return this.readLinkProperty(obj, propertyNameArr, callback);
  1431. }
  1432. if (linkProperty.indexOf('.') !== -1) {
  1433. var names = linkProperty.split('.');
  1434. var iterationObj = obj;
  1435. var result = null;
  1436. ArrayUtils.ergodicArrayObject(this, names, function (name, i) {
  1437. iterationObj = this.readLinkProperty(iterationObj, name);
  1438. if (names[names.length - 1] === name && names.length - 1 === i) {
  1439. result = iterationObj;
  1440. if (callback) {
  1441. callback.call(_global, result, linkProperty);
  1442. }
  1443. }
  1444. // 终止对接下来的属性的遍历
  1445. if (typeof iterationObj === 'undefined') {
  1446. return -1;
  1447. }
  1448. });
  1449. return result;
  1450. }
  1451. var normalResult = null;
  1452. if (linkProperty.slice(linkProperty.length - 2) === '()') {
  1453. var func = linkProperty.slice(0, linkProperty.length - 2);
  1454. normalResult = obj[func]();
  1455. } else {
  1456. normalResult = obj[linkProperty];
  1457. }
  1458. if (normalResult === null) {
  1459. console.warn(obj, '的属性[\'' + linkProperty + '\']值未找到');
  1460. }
  1461. if (callback) {
  1462. callback.call(_global, normalResult, linkProperty);
  1463. }
  1464. return normalResult;
  1465. }
  1466. if (BaseUtils.isArray(linkProperty)) {
  1467. var results = [];
  1468. ArrayUtils.ergodicArrayObject(this, linkProperty, function (name) {
  1469. var value = this.readLinkProperty(obj, name);
  1470. results.push(value);
  1471. if (callback && name !== '') {
  1472. return callback.call(_global, value, name);
  1473. }
  1474. });
  1475. results.isMultipleResults = true;
  1476. return results;
  1477. }
  1478. },
  1479. /**
  1480. * 为对象属性赋值
  1481. * (同一个对象中不能够既有数字开头的属性名和普通属性名)
  1482. * @param obj
  1483. * @param linkProperty {string|Array} 属性表达式,多个属性则用数组
  1484. * @param value
  1485. */
  1486. createLinkProperty: function (obj, linkProperty, value) {
  1487. if (obj === null) {
  1488. obj = {};
  1489. }
  1490. if (typeof linkProperty === 'string') {
  1491. // 除去所有的空格
  1492. linkProperty = linkProperty.replace(/ /g, '');
  1493. // 不判断为空的值
  1494. if (linkProperty === '') {
  1495. throw new TypeError('对象属性名不能为空')
  1496. }
  1497. if (linkProperty.indexOf(',') !== -1) {
  1498. var propertyNameArr = linkProperty.split(',');
  1499. this.createLinkProperty(obj, propertyNameArr, value);
  1500. return obj;
  1501. }
  1502. if (linkProperty.indexOf('.') !== -1) {
  1503. var names = linkProperty.split('.');
  1504. if (!obj.hasOwnProperty(names[0])) {
  1505. obj[names[0]] = {}
  1506. }
  1507. // 判断属性名是否以数字开头(若是代表是一个数组)
  1508. if (!Number.isNaN(parseInt(names[0]))) {
  1509. if (!ArrayUtils.isArrayObject(obj)) {
  1510. obj = [];
  1511. }
  1512. }
  1513. var propertyObj = obj[names[0]];
  1514. var newProperties = names.slice(1, names.length);
  1515. var newLinkProperty = '';
  1516. ArrayUtils.ergodicArrayObject(this, newProperties, function (property, i) {
  1517. if (i < newProperties.length - 1) {
  1518. newLinkProperty = newLinkProperty + property + '.'
  1519. } else {
  1520. newLinkProperty = newLinkProperty + property;
  1521. }
  1522. });
  1523. obj[names[0]] = this.createLinkProperty(propertyObj, newLinkProperty, value);
  1524. return obj;
  1525. }
  1526. // 判断属性名是否以数字开头(若是代表是一个数组)
  1527. if (!Number.isNaN(parseInt(linkProperty))) {
  1528. if (!ArrayUtils.isArrayObject(obj)) {
  1529. obj = [];
  1530. }
  1531. }
  1532. obj[linkProperty] = value;
  1533. return obj;
  1534. } else if (BaseUtils.isArray(linkProperty)) {
  1535. ArrayUtils.ergodicArrayObject(this, linkProperty, function (link) {
  1536. obj = this.createLinkProperty(obj, link, value);
  1537. });
  1538. return obj;
  1539. }
  1540. },
  1541. /**
  1542. * 遍历对象属性
  1543. * @param context {object} 上下文
  1544. * @param obj {object} 遍历对象
  1545. * @param cb {function} 回调函数
  1546. * @param isReadInnerObject {boolean=} 是否遍历内部对象的属性
  1547. */
  1548. ergodicObject: function (context, obj, cb, isReadInnerObject) {
  1549. var keys = Object.keys(obj);
  1550. ArrayUtils.ergodicArrayObject(this, keys, function (propertyName) {
  1551. // 若内部对象需要遍历
  1552. var _propertyName = propertyName;
  1553. if (isReadInnerObject && obj[propertyName] !== null && typeof obj[propertyName] === 'object') {
  1554. this.ergodicObject(this, obj[propertyName], function (value, key) {
  1555. return cb.call(context, value, _propertyName + '.' + key);
  1556. }, true)
  1557. } else {
  1558. return cb.call(context, obj[propertyName], propertyName);
  1559. }
  1560. })
  1561. },
  1562. /**
  1563. * 当指定属性为空或不存在时执行回到函数;
  1564. * @param context {object} 上下文
  1565. * @param obj {object} 检测对象
  1566. * @param propertyNames{Array|string} 需要检测的属性名
  1567. * 可以检查多级属性如:'a.b.c.e',
  1568. * 多个属性使用数组,支持纯字符串多个属性用','隔开
  1569. * @param cb {function} 回调函数[参数:为空或不存在的属性名,返回值为'-1'时,跳过之后的回调函数]
  1570. */
  1571. whileEmptyObjectProperty: function (context, obj, propertyNames, cb) {
  1572. // 解析单个属性名
  1573. if (typeof propertyNames === 'string') {
  1574. // 除去所有的空格
  1575. propertyNames = propertyNames.replace(/ /g, '');
  1576. // 不判断为空的值
  1577. if (propertyNames === '') {
  1578. return;
  1579. }
  1580. // 若是以','隔开的伪数组,则转化为数组再进行操作
  1581. if (propertyNames.indexOf(',') !== -1) {
  1582. var propertyNameArr = propertyNames.split(',');
  1583. return this.whileEmptyObjectProperty(context, obj, propertyNameArr, cb);
  1584. }
  1585. // 若指定级联属性
  1586. if (propertyNames.indexOf('.') !== -1) {
  1587. var names = propertyNames.split('.');
  1588. var iterationObj = obj;
  1589. var result = null;
  1590. ArrayUtils.ergodicArrayObject(this, names, function (name) {
  1591. if (iterationObj && iterationObj.hasOwnProperty(name)) {
  1592. iterationObj = iterationObj[name];
  1593. } else {
  1594. result = cb.call(_global, propertyNames);
  1595. // 终止对接下来的属性的遍历
  1596. return -1;
  1597. }
  1598. });
  1599. return result;
  1600. }
  1601. // 正常流程
  1602. if (!obj.hasOwnProperty(propertyNames)) {
  1603. return cb.call(context, propertyNames);
  1604. }
  1605. if (obj[propertyNames] === null || obj[propertyNames] === '') {
  1606. return cb.call(context, propertyNames);
  1607. }
  1608. } else if (BaseUtils.isArray(propertyNames)) {
  1609. // 解析数组
  1610. var _this = this;
  1611. ArrayUtils.ergodicArrayObject(this, propertyNames, function (propertyName) {
  1612. // 递归调用
  1613. return _this.whileEmptyObjectProperty(context, obj, propertyName, cb);
  1614. })
  1615. }
  1616. },
  1617. whileEmptyObjectPropertyV2: function (context, obj, propertyNames, cb) {
  1618. this.readLinkProperty(obj, propertyNames, function (value, propertyName) {
  1619. if (value === null || value === '' || parseInt(value) < 0) {
  1620. return cb.call(context, propertyName);
  1621. }
  1622. })
  1623. },
  1624. /**
  1625. * 克隆对象[只克隆属性,不克隆原型链]
  1626. * @param obj {*}
  1627. */
  1628. cloneObject: function (obj) {
  1629. var newObj = {};
  1630. // 判断是否为基本数据类型,若是则直接返回
  1631. if (typeof obj === 'string' ||
  1632. typeof obj === 'number' ||
  1633. typeof obj === 'undefined' ||
  1634. typeof obj === 'function' ||
  1635. typeof obj === 'boolean') {
  1636. return obj;
  1637. }
  1638. // 判断是否是数组
  1639. if (BaseUtils.isArray(obj)) {
  1640. newObj = [];
  1641. // 遍历数组并递归调用该方法获取数组内部对象的克隆对象并push到新数组
  1642. ArrayUtils.ergodicArrayObject(this, obj, function (arrObjValue) {
  1643. newObj.push(this.cloneObject(arrObjValue));
  1644. })
  1645. } else if (typeof obj === 'object') {
  1646. // 当目标为一般对象时即 typeof 为 object
  1647. if (obj === null) {
  1648. // 当克隆对象为空时,返回空
  1649. return null;
  1650. }
  1651. // 遍历对象的属性并调用递归方法获得该属性对应的对象的克隆对象并将其重新赋值到该属性
  1652. this.ergodicObject(this, obj, function (value, key) {
  1653. newObj[key] = this.cloneObject(value);
  1654. });
  1655. }
  1656. return newObj;
  1657. },
  1658. /**
  1659. * 获取对象的哈希码
  1660. * @param obj {Object}
  1661. * @returns {number}
  1662. */
  1663. getObjHashCode: function (obj) {
  1664. var str = JSON.stringify(obj);
  1665. var hash = 0, i, chr, len;
  1666. console.log(str)
  1667. console.log(hash)
  1668. if (str.length === 0) return hash;
  1669. for (i = 0, len = str.length; i < len; i++) {
  1670. chr = str.charCodeAt(i);
  1671. hash = ((hash << 5) - hash) + chr;
  1672. hash |= 0; // Convert to 32bit integer
  1673. }
  1674. console.log(str)
  1675. console.log(hash)
  1676. return hash;
  1677. },
  1678. /**
  1679. * 扩展对象属性
  1680. * @param obj 原对象
  1681. * @param extendedObj 被扩展的对象
  1682. * @param isCover {boolean=} 扩展的属性和原来属性冲突时是否覆盖 默认[false]
  1683. * @param isClone {boolean=} 是否返回一个新的对象,默认[false]返回扩展后的原对象
  1684. */
  1685. expandObject: function (obj, extendedObj, isCover, isClone) {
  1686. var resultObj = obj;
  1687. if (isClone) {
  1688. resultObj = this.cloneObject(obj);
  1689. }
  1690. this.ergodicObject(this, extendedObj, function (value, key) {
  1691. if (isCover && this.readLinkProperty(resultObj, key) !== null) {
  1692. return;
  1693. }
  1694. resultObj = this.createLinkProperty(resultObj, key, value);
  1695. }, true);
  1696. return resultObj;
  1697. },
  1698. /**
  1699. * 为数组排序,当数组中的元素为对象时,根据指定对象的属性名进行排序
  1700. * @param arr 数组
  1701. * @param propertyName 属性名(当有多个属性名时,为多级排序)
  1702. * @param order 升降序
  1703. * @returns {*}
  1704. */
  1705. sortingArrayByProperty: function (arr, propertyName, order) {
  1706. var _this = this;
  1707. var sortSetting = {
  1708. // 是否创建新数据
  1709. createNewData: false,
  1710. // 通过该方法获取数组中每个对象中用来比较的属性
  1711. getComparedProperty: function (arr) {
  1712. var compareArr = [];
  1713. ArrayUtils.ergodicArrayObject(_this, arr, function (obj, i) {
  1714. if (typeof obj !== 'object') {
  1715. compareArr.push(obj);
  1716. } else {
  1717. var compareValue = this.readLinkProperty(obj, propertyName);
  1718. if (compareValue !== null) {
  1719. compareArr.push(compareValue);
  1720. } else {
  1721. compareArr.push(obj);
  1722. }
  1723. }
  1724. });
  1725. return compareArr.slice(0);
  1726. }
  1727. };
  1728. return ArrayUtils.sortingArrays(arr, order, sortSetting);
  1729. },
  1730. /**
  1731. * 转话为目标的实例
  1732. * @param constructor {function} 构造函数
  1733. * @param obj {object|Array}判断的对象
  1734. * @param defaultProperty {object=}
  1735. */
  1736. toAimObject: function (obj, constructor, defaultProperty) {
  1737. if (BaseUtils.isArray(obj)) {
  1738. var originArr = [];
  1739. ArrayUtils.ergodicArrayObject(this, obj, function (value) {
  1740. originArr.push(this.toAimObject(value, constructor, defaultProperty));
  1741. });
  1742. return originArr;
  1743. } else if (typeof obj === 'object') {
  1744. if (defaultProperty) {
  1745. this.ergodicObject(this, defaultProperty, function (value, key) {
  1746. if (obj[key] === null) {
  1747. obj[key] = value;
  1748. }
  1749. });
  1750. }
  1751. if (obj instanceof constructor) {
  1752. return obj;
  1753. }
  1754. var originObj = obj;
  1755. while (originObj.__proto__ !== null && originObj.__proto__ !== Object.prototype) {
  1756. originObj = originObj.__proto__;
  1757. }
  1758. originObj.__proto__ = constructor.prototype;
  1759. return originObj;
  1760. }
  1761. },
  1762. /**
  1763. * 将数组中结构类似对象指定属性融合为一个数组
  1764. * @param arr {Array}
  1765. * @param propertyNames
  1766. */
  1767. parseTheSameObjectPropertyInArray: function (arr, propertyNames) {
  1768. var result = {};
  1769. var temp = {};
  1770. ArrayUtils.ergodicArrayObject(this, arr, function (obj) {
  1771. // 获取想要得到的所有属性,以属性名为键值存储到temp中
  1772. this.readLinkProperty(obj, propertyNames, function (value, property) {
  1773. if (!temp.hasOwnProperty(property) || !(BaseUtils.isArray(temp[property]))) {
  1774. temp[property] = [];
  1775. }
  1776. temp[property].push(value);
  1777. });
  1778. });
  1779. // 遍历temp获取每个键值中的值,并单独取出
  1780. this.ergodicObject(this, temp, function (value, key) {
  1781. result = this.createLinkProperty(result, key, value);
  1782. });
  1783. return this.cloneObject(result);
  1784. },
  1785. /**
  1786. * 将数组中结构类似对象指定属性融合为一个数组
  1787. * @param arr {Array}
  1788. */
  1789. parseTheSameObjectAllPropertyInArray: function (arr) {
  1790. if (!ArrayUtils.isArrayObject(arr) || arr.length < 1) {
  1791. return;
  1792. }
  1793. // 获取一个对象的所有属性,包括内部对象的属性
  1794. var propertyNames = [];
  1795. this.ergodicObject(this, arr[0], function (v, k) {
  1796. propertyNames.push(k);
  1797. }, true);
  1798. return this.parseTheSameObjectPropertyInArray(arr, propertyNames);
  1799. },
  1800. /**
  1801. * 获取对象属性,若为数组则计算其中数字的平均值或其它
  1802. * @param obj
  1803. * @param propertyNames{Array<string>|string}
  1804. * @param type
  1805. */
  1806. getCalculationInArrayByLinkPropertyNames: function (obj, propertyNames, type) {
  1807. var resultObject = {};
  1808. var _this = this;
  1809. switch (type) {
  1810. default:
  1811. case 'sum':
  1812. this.readLinkProperty(obj, propertyNames, function (value, key) {
  1813. if (ArrayUtils.isArrayObject(value)) {
  1814. resultObject = _this.createLinkProperty(resultObject, key, ArrayUtils.getSumInArray(value));
  1815. }
  1816. });
  1817. break;
  1818. case 'average':
  1819. this.readLinkProperty(obj, propertyNames, function (value, key) {
  1820. if (ArrayUtils.isArrayObject(value)) {
  1821. resultObject = _this.createLinkProperty(resultObject, key, ArrayUtils.getAverageInArray(value));
  1822. }
  1823. });
  1824. break;
  1825. }
  1826. return resultObject;
  1827. }
  1828. }
  1829. });
  1830.  
  1831. // ColorUtils
  1832. factory('ColorUtils', [], function () {
  1833. return {
  1834. /**
  1835. * 转换颜色rgb为16进制
  1836. * @param r
  1837. * @param g
  1838. * @param b
  1839. * @return {string}
  1840. */
  1841. rgbToHex: function (r, g, b) {
  1842. var hex = ((r << 16) | (g << 8) | b).toString(16);
  1843. return "#" + new Array(Math.abs(hex.length - 7)).join("0") + hex;
  1844. },
  1845. /**
  1846. * 转换颜色16进制为rgb
  1847. * @param hex
  1848. * @return {Array}
  1849. */
  1850. hexToRgb: function (hex) {
  1851. hex = hex.replace(/ /g, '');
  1852. var length = hex.length;
  1853. var rgb = [];
  1854. switch (length) {
  1855. case 4:
  1856. rgb.push(parseInt(hex[1] + hex[1], 16));
  1857. rgb.push(parseInt(hex[2] + hex[2], 16));
  1858. rgb.push(parseInt(hex[3] + hex[3], 16));
  1859. return rgb;
  1860. case 7:
  1861. for (var i = 1; i < 7; i += 2) {
  1862. rgb.push(parseInt("0x" + hex.slice(i, i + 2)));
  1863. }
  1864. return rgb;
  1865. default:
  1866. break
  1867. }
  1868. },
  1869. /**
  1870. * 根据两个颜色以及之间的百分比获取渐进色
  1871. * @param start
  1872. * @param end
  1873. * @param percentage
  1874. * @return {*}
  1875. */
  1876. gradientColorsPercentage: function (start, end, percentage) {
  1877. var resultRgb = [];
  1878. var startRgb = this.hexToRgb(start);
  1879. if (end == null) {
  1880. return start;
  1881. }
  1882. var endRgb = this.hexToRgb(end);
  1883. var totalR = endRgb[0] - startRgb[0];
  1884. var totalG = endRgb[1] - startRgb[1];
  1885. var totalB = endRgb[2] - startRgb[2];
  1886. resultRgb.push(startRgb[0] + totalR * percentage);
  1887. resultRgb.push(startRgb[1] + totalG * percentage);
  1888. resultRgb.push(startRgb[2] + totalB * percentage);
  1889. return this.rgbToHex(resultRgb[0], resultRgb[1], resultRgb[2])
  1890. }
  1891. }
  1892. });
  1893.  
  1894. factory('FunctionUtils', [], function () {
  1895. return {
  1896. /**
  1897. * 获取方法的名字
  1898. * @param func
  1899. * @returns {*}
  1900. */
  1901. getFunctionName: function (func) {
  1902. if (typeof func === 'function' || typeof func === 'object') {
  1903. var name = ('' + func).match(/function\s*([\w\$]*)\s*\(/);
  1904. }
  1905. return func.name || name[1];
  1906. },
  1907. /**
  1908. * 获取方法的参数名
  1909. * @param func
  1910. * @returns {*}
  1911. */
  1912. getFunctionParams: function (func) {
  1913. if (typeof func === 'function' || typeof func === 'object') {
  1914. var name = ('' + func).match(/function.*\(([^)]*)\)/);
  1915. return name[1].replace(/( )|(\n)/g, '').split(',');
  1916. }
  1917. },
  1918. /**
  1919. * 通过方法的arguments获取调用该方法的函数
  1920. * @param func_arguments
  1921. * @returns {string}
  1922. */
  1923. getCallerName: function (func_arguments) {
  1924. var caller = func_arguments.callee.caller;
  1925. var callerName = '';
  1926. if (caller) {
  1927. callerName = this.getFunctionName(caller);
  1928. }
  1929. return callerName;
  1930. },
  1931. FunctionBuilder: function (func) {
  1932. var _this = this;
  1933. var fs = [];
  1934. fs.push(func);
  1935. var properties = ['push', 'unshift', 'slice', 'map', 'forEach', 'keys', 'find', 'concat', 'fill', 'shift', 'values'];
  1936. map.call(properties, function (property) {
  1937. if (typeof Array.prototype[property] === 'function') {
  1938. Object.defineProperty(_this, property, {
  1939. get: function () {
  1940. return function () {
  1941. fs[property].apply(fs, arguments);
  1942. return this;
  1943. }
  1944. }
  1945. });
  1946. }
  1947. });
  1948. this.result = function (context) {
  1949. var rfs = [];
  1950. map.call(fs, function (f, index) {
  1951. if (typeof f === 'function') {
  1952. rfs.push(f);
  1953. }
  1954. });
  1955. return function () {
  1956. var declareVar = {
  1957. arguments: arguments,
  1958. this: this
  1959. };
  1960. map.call(rfs, function (f) {
  1961. var dv = f.apply(context || this, [declareVar]);
  1962. if (dv) {
  1963. map.call(Object.keys(dv), function (key) {
  1964. declareVar[key] = dv[key];
  1965. });
  1966. }
  1967. });
  1968. return declareVar.returnValue;
  1969. }
  1970. }
  1971. },
  1972. invokeMethods: function (context, methods, args) {
  1973. if (!this.isArray(methods)) {
  1974. return;
  1975. }
  1976. var results = [];
  1977. var _this = this;
  1978. this.ergodicArrayObject(context, methods, function (method) {
  1979. if (!_this.isFunction(method)) {
  1980. return;
  1981. }
  1982. results.push(
  1983. method.apply(context, args)
  1984. );
  1985. });
  1986. return results;
  1987. }
  1988. }
  1989. });
  1990.  
  1991. factory('UrlUtils', [], function () {
  1992. return {
  1993. urlMatching: function (url, matchUrl) {
  1994. var pattern = new RegExp(matchUrl);
  1995. return pattern.test(url);
  1996. },
  1997. getUrlWithoutParam: function (url) {
  1998. return url.split('?')[0];
  1999. },
  2000. getParamFromUrl: function (url) {
  2001. var params = [];
  2002. var parts = url.split('?');
  2003. if (parts.length < 2) {
  2004. return params;
  2005. }
  2006. var paramsStr = parts[1].split('&');
  2007. for (var i = 0; i < paramsStr.length; i++) {
  2008. var index = paramsStr[i].indexOf('=');
  2009. var ps = new Array(2);
  2010. if (index !== -1) {
  2011. ps = [
  2012. paramsStr[i].substring(0, index),
  2013. paramsStr[i].substring(index + 1),
  2014. ];
  2015. } else {
  2016. ps[0] = paramsStr[i];
  2017. }
  2018. params.push({
  2019. key: ps[0],
  2020. value: ps[1]
  2021. });
  2022. }
  2023. return params;
  2024. },
  2025. margeUrlAndParams: function (url, params) {
  2026. if (url.indexOf('?') !== -1 || !(params instanceof Array)) {
  2027. return url;
  2028. }
  2029. var paramsStr = [];
  2030. for (var i = 0; i < params.length; i++) {
  2031. if (params[i].key !== null && params[i].value !== null) {
  2032. paramsStr.push(params[i].key + '=' + params[i].value);
  2033. }
  2034. }
  2035. return url + '?' + paramsStr.join('&');
  2036. }
  2037. }
  2038. });
  2039.  
  2040. factory('PointUtils', [], function () {
  2041. var Point2D = function (x, y) {
  2042. this.x = x || 0;
  2043. this.y = y || 0;
  2044. };
  2045. Point2D.prototype = {
  2046. constructor: Point2D,
  2047. /**
  2048. * 获取指定距离和角度对应的平面点
  2049. * @param distance
  2050. * @param deg
  2051. */
  2052. getOtherPointFromDistanceAndDeg: function (distance, deg) {
  2053. var radian = Math.PI / 180 * deg;
  2054. var point = new this.constructor();
  2055. point.x = distance * Math.sin(radian) + this.x;
  2056. point.y = this.y - distance * Math.cos(radian);
  2057. return point;
  2058. },
  2059. /**
  2060. * 获取当前平面点与另一个平面点之间的距离
  2061. * @param p
  2062. * @returns {number}
  2063. */
  2064. getDistanceFromAnotherPoint: function (p) {
  2065. return Math.sqrt((this.x - p.x) * (this.x - p.x) + (this.y - p.y) * (this.y - p.y));
  2066. },
  2067. /**
  2068. * 获取当前平面点与另一个平面点之间的角度
  2069. * @param p
  2070. * @returns {number}
  2071. */
  2072. getDegFromAnotherPoint: function (p) {
  2073. var usedPoint = new Point2D(p.x * 1000000 - this.x * 1000000, p.y * 1000000 - this.y * 1000000);
  2074. var radian = Math.atan2(usedPoint.x * 1000000, usedPoint.y * 1000000);
  2075. var deg = radian * 180 / Math.PI;
  2076. return 180 - deg;
  2077. },
  2078. /**
  2079. * 判断该点是否位于一矩形内部
  2080. * @param x 矩形开始坐标x
  2081. * @param y 矩形开始坐标y
  2082. * @param width 矩形宽
  2083. * @param height 矩形长
  2084. * @returns {boolean}
  2085. */
  2086. isInRect: function (x, y, width, height) {
  2087. var px = this.x;
  2088. var py = this.y;
  2089. if (px < x || px > x + width) {
  2090. return false;
  2091. }
  2092. return !(py < y || py > y + height);
  2093. }
  2094. };
  2095. return {
  2096. Point2D: Point2D
  2097. }
  2098. });
  2099.  
  2100.  
  2101. factory('PropExpand', ['BaseUtils', 'ObjectUtils', 'ArrayUtils', 'UrlUtils'],
  2102. function (BaseUtils, ObjectUtils, ArrayUtils, UrlUtils) {
  2103. return {
  2104. Object: {
  2105. getProperty: function (_self, propertyLink) {
  2106. return ObjectUtils.readLinkProperty(_self, propertyLink);
  2107. },
  2108. setProperty: function (_self, propertyLink, value) {
  2109. ObjectUtils.createLinkProperty(_self, propertyLink, value);
  2110. },
  2111. mapConvert: function (_self, mapper) {
  2112.  
  2113. },
  2114. keyMap: function (_self, cb) {
  2115. },
  2116. keyValues: function (_self, cb) {
  2117. },
  2118. keyFilter: function (_self, cb) {
  2119. },
  2120. },
  2121. Array: {
  2122. map: function () {
  2123. },
  2124. forEach: function () {
  2125. },
  2126. filter: function () {
  2127. },
  2128. reduce: function () {
  2129. },
  2130. keep: function () {
  2131. },
  2132. remove: function () {
  2133. }
  2134. },
  2135. String: {
  2136. join: function (_self, arr) {
  2137. },
  2138. }
  2139. }
  2140. });
  2141.  
  2142. _global.everyUtils = function () {
  2143. if (BaseUtils.isArray(arguments[0])) {
  2144. depend.call(arguments[2] || this, arguments[0], arguments[1]);
  2145. } else if (BaseUtils.isFunction(arguments[0])) {
  2146. var args = arguments;
  2147. depend.call(arguments[1] || this, ['FunctionUtils'], function (FunctionUtils) {
  2148. var depends = FunctionUtils.getFunctionParams(args[0]);
  2149. depend(depends, args[0]);
  2150. })
  2151. }
  2152. };
  2153.  
  2154. _global.eUtils = (function () {
  2155. var utils = {};
  2156. if (_global.everyUtils) {
  2157. _global.everyUtils([
  2158. 'ArrayUtils', 'ObjectUtils', 'BaseUtils', 'FunctionUtils', 'ColorUtils', 'PointUtils', 'UrlUtils'
  2159. ], function (
  2160. ArrayUtils,
  2161. ObjectUtils,
  2162. BaseUtils,
  2163. FunctionUtils,
  2164. ColorUtils,
  2165. PointUtils,
  2166. UrlUtils) {
  2167. utils = {
  2168. ArrayUtils: ArrayUtils,
  2169. ObjectUtils: ObjectUtils,
  2170. BaseUtils: BaseUtils,
  2171. ColorUtils: ColorUtils,
  2172. UrlUtils: UrlUtils,
  2173. urlUtils: UrlUtils,
  2174. PointUtils: PointUtils,
  2175. FunctionUtils: FunctionUtils
  2176. };
  2177. });
  2178. }
  2179. var proxy = {};
  2180. forEach.call(Object.keys(utils), function (utilName) {
  2181. if (!utilName) {
  2182. return;
  2183. }
  2184. Object.defineProperty(proxy, utilName, {
  2185. get: function () {
  2186. return utils[utilName];
  2187. }
  2188. });
  2189. forEach.call(Object.keys(utils[utilName]), function (key) {
  2190. if (!key) {
  2191. return;
  2192. }
  2193. if (proxy[key]) {
  2194. return;
  2195. }
  2196. Object.defineProperty(proxy, key, {
  2197. get: function () {
  2198. return utils[utilName][key];
  2199. }
  2200. })
  2201. })
  2202. });
  2203. return proxy;
  2204. })();
  2205.  
  2206. return _global.eUtils;
  2207. }));
  2208.  
  2209. /***/ })
  2210. /******/ ]);
  2211. /************************************************************************/
  2212. /******/ // The module cache
  2213. /******/ var __webpack_module_cache__ = {};
  2214. /******/
  2215. /******/ // The require function
  2216. /******/ function __webpack_require__(moduleId) {
  2217. /******/ // Check if module is in cache
  2218. /******/ if(__webpack_module_cache__[moduleId]) {
  2219. /******/ return __webpack_module_cache__[moduleId].exports;
  2220. /******/ }
  2221. /******/ // Create a new module (and put it into the cache)
  2222. /******/ var module = __webpack_module_cache__[moduleId] = {
  2223. /******/ // no module.id needed
  2224. /******/ // no module.loaded needed
  2225. /******/ exports: {}
  2226. /******/ };
  2227. /******/
  2228. /******/ // Execute the module function
  2229. /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  2230. /******/
  2231. /******/ // Return the exports of the module
  2232. /******/ return module.exports;
  2233. /******/ }
  2234. /******/
  2235. /************************************************************************/
  2236. /******/ // module exports must be returned from runtime so entry inlining is disabled
  2237. /******/ // startup
  2238. /******/ // Load entry module and return exports
  2239. /******/ return __webpack_require__(0);
  2240. /******/ })()
  2241. ;
  2242. });