myhook3

myhook3 lib

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/468164/1201636/myhook3.js

  1. (function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap
  2. /******/ // The module cache
  3. /******/ var installedModules = {};
  4. /******/
  5. /******/ // The require function
  6. /******/ function __webpack_require__(moduleId) {
  7. /******/
  8. /******/ // Check if module is in cache
  9. /******/ if(installedModules[moduleId]) {
  10. /******/ return installedModules[moduleId].exports;
  11. /******/ }
  12. /******/ // Create a new module (and put it into the cache)
  13. /******/ var module = installedModules[moduleId] = {
  14. /******/ i: moduleId,
  15. /******/ l: false,
  16. /******/ exports: {}
  17. /******/ };
  18. /******/
  19. /******/ // Execute the module function
  20. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  21. /******/
  22. /******/ // Flag the module as loaded
  23. /******/ module.l = true;
  24. /******/
  25. /******/ // Return the exports of the module
  26. /******/ return module.exports;
  27. /******/ }
  28. /******/
  29. /******/
  30. /******/ // expose the modules object (__webpack_modules__)
  31. /******/ __webpack_require__.m = modules;
  32. /******/
  33. /******/ // expose the module cache
  34. /******/ __webpack_require__.c = installedModules;
  35. /******/
  36. /******/ // identity function for calling harmony imports with the correct context
  37. /******/ __webpack_require__.i = function(value) { return value; };
  38. /******/
  39. /******/ // define getter function for harmony exports
  40. /******/ __webpack_require__.d = function(exports, name, getter) {
  41. /******/ if(!__webpack_require__.o(exports, name)) {
  42. /******/ Object.defineProperty(exports, name, {
  43. /******/ configurable: false,
  44. /******/ enumerable: true,
  45. /******/ get: getter
  46. /******/ });
  47. /******/ }
  48. /******/ };
  49. /******/
  50. /******/ // getDefaultExport function for compatibility with non-harmony modules
  51. /******/ __webpack_require__.n = function(module) {
  52. /******/ var getter = module && module.__esModule ?
  53. /******/ function getDefault() { return module['default']; } :
  54. /******/ function getModuleExports() { return module; };
  55. /******/ __webpack_require__.d(getter, 'a', getter);
  56. /******/ return getter;
  57. /******/ };
  58. /******/
  59. /******/ // Object.prototype.hasOwnProperty.call
  60. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  61. /******/
  62. /******/ // __webpack_public_path__
  63. /******/ __webpack_require__.p = "";
  64. /******/
  65. /******/ // Load entry module and return exports
  66. /******/ return __webpack_require__(__webpack_require__.s = 3);
  67. /******/ })
  68. /************************************************************************/
  69. /******/ ([
  70. /* 0 */
  71. /***/ (function(module, exports, __webpack_require__) {
  72.  
  73. "use strict";
  74.  
  75.  
  76. Object.defineProperty(exports, "__esModule", {
  77. value: true
  78. });
  79.  
  80. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  81.  
  82. exports.configEvent = configEvent;
  83. exports.hook = hook;
  84. exports.unHook = unHook;
  85. /*
  86. * author: wendux
  87. * email: 824783146@qq.com
  88. * source code: https://github.com/wendux/Ajax-hook
  89. */
  90.  
  91. // Save original XMLHttpRequest as _rxhr
  92. var realXhr = "__xhr";
  93.  
  94. var events = exports.events = ['load', 'loadend', 'timeout', 'error', 'readystatechange', 'abort'];
  95.  
  96. function configEvent(event, xhrProxy) {
  97. var e = {};
  98. for (var attr in event) {
  99. e[attr] = event[attr];
  100. } // xhrProxy instead
  101. e.target = e.currentTarget = xhrProxy;
  102. return e;
  103. }
  104.  
  105. function hook(proxy, win) {
  106. win = win || window;
  107. // Avoid double hookAjax
  108. win[realXhr] = win[realXhr] || win.XMLHttpRequest;
  109.  
  110. win.XMLHttpRequest = function () {
  111.  
  112. // We shouldn't hookAjax XMLHttpRequest.prototype because we can't
  113. // guarantee that all attributes are on the prototype。
  114. // Instead, hooking XMLHttpRequest instance can avoid this problem.
  115.  
  116. var xhr = new win[realXhr]();
  117.  
  118. // Generate all callbacks(eg. onload) are enumerable (not undefined).
  119. for (var i = 0; i < events.length; ++i) {
  120. var key = 'on' + events[i];
  121. if (xhr[key] === undefined) xhr[key] = null;
  122. }
  123.  
  124. for (var attr in xhr) {
  125. var type = "";
  126. try {
  127. type = _typeof(xhr[attr]); // May cause exception on some browser
  128. } catch (e) {}
  129. if (type === "function") {
  130. // hookAjax methods of xhr, such as `open`、`send` ...
  131. this[attr] = hookFunction(attr);
  132. } else {
  133. Object.defineProperty(this, attr, {
  134. get: getterFactory(attr),
  135. set: setterFactory(attr),
  136. enumerable: true
  137. });
  138. }
  139. }
  140. var that = this;
  141. xhr.getProxy = function () {
  142. return that;
  143. };
  144. this.xhr = xhr;
  145. };
  146.  
  147. Object.assign(win.XMLHttpRequest, { UNSENT: 0, OPENED: 1, HEADERS_RECEIVED: 2, LOADING: 3, DONE: 4 });
  148.  
  149. // Generate getter for attributes of xhr
  150. function getterFactory(attr) {
  151. return function () {
  152. var v = this.hasOwnProperty(attr + "_") ? this[attr + "_"] : this.xhr[attr];
  153. var attrGetterHook = (proxy[attr] || {})["getter"];
  154. return attrGetterHook && attrGetterHook(v, this) || v;
  155. };
  156. }
  157.  
  158. // Generate setter for attributes of xhr; by this we have an opportunity
  159. // to hookAjax event callbacks (eg: `onload`) of xhr;
  160. function setterFactory(attr) {
  161. return function (v) {
  162. var xhr = this.xhr;
  163. var that = this;
  164. var hook = proxy[attr];
  165. // hookAjax event callbacks such as `onload`、`onreadystatechange`...
  166. if (attr.substring(0, 2) === 'on') {
  167. that[attr + "_"] = v;
  168. xhr[attr] = function (e) {
  169. e = configEvent(e, that);
  170. var ret = proxy[attr] && proxy[attr].call(that, xhr, e);
  171. ret || v.call(that, e);
  172. };
  173. } else {
  174. //If the attribute isn't writable, generate proxy attribute
  175. var attrSetterHook = (hook || {})["setter"];
  176. v = attrSetterHook && attrSetterHook(v, that) || v;
  177. this[attr + "_"] = v;
  178. try {
  179. // Not all attributes of xhr are writable(setter may undefined).
  180. xhr[attr] = v;
  181. } catch (e) {}
  182. }
  183. };
  184. }
  185.  
  186. // Hook methods of xhr.
  187. function hookFunction(fun) {
  188. return function () {
  189. var args = [].slice.call(arguments);
  190. if (proxy[fun]) {
  191. var ret = proxy[fun].call(this, args, this.xhr);
  192. // If the proxy return value exists, return it directly,
  193. // otherwise call the function of xhr.
  194. if (ret) return ret;
  195. }
  196. return this.xhr[fun].apply(this.xhr, args);
  197. };
  198. }
  199.  
  200. // Return the real XMLHttpRequest
  201. return win[realXhr];
  202. }
  203.  
  204. function unHook(win) {
  205. win = win || window;
  206. if (win[realXhr]) win.XMLHttpRequest = win[realXhr];
  207. win[realXhr] = undefined;
  208. }
  209.  
  210. /***/ }),
  211. /* 1 */
  212. /***/ (function(module, exports, __webpack_require__) {
  213.  
  214. "use strict";
  215.  
  216.  
  217. Object.defineProperty(exports, "__esModule", {
  218. value: true
  219. });
  220. exports.proxy = proxy;
  221. exports.unProxy = unProxy;
  222.  
  223. var _xhrHook = __webpack_require__(0);
  224.  
  225. var eventLoad = _xhrHook.events[0],
  226. eventLoadEnd = _xhrHook.events[1],
  227. eventTimeout = _xhrHook.events[2],
  228. eventError = _xhrHook.events[3],
  229. eventReadyStateChange = _xhrHook.events[4],
  230. eventAbort = _xhrHook.events[5]; /*
  231. * author: wendux
  232. * email: 824783146@qq.com
  233. * source code: https://github.com/wendux/Ajax-hook
  234. */
  235.  
  236. var prototype = 'prototype';
  237.  
  238. function proxy(proxy, win) {
  239. win = win || window;
  240. if (win['__xhr']) throw "Ajax is already hooked.";
  241. return proxyAjax(proxy, win);
  242. }
  243.  
  244. function unProxy(win) {
  245. (0, _xhrHook.unHook)(win);
  246. }
  247.  
  248. function trim(str) {
  249. return str.replace(/^\s+|\s+$/g, '');
  250. }
  251.  
  252. function getEventTarget(xhr) {
  253. return xhr.watcher || (xhr.watcher = document.createElement('a'));
  254. }
  255.  
  256. function triggerListener(xhr, name) {
  257. var xhrProxy = xhr.getProxy();
  258. var callback = 'on' + name + '_';
  259. var event = (0, _xhrHook.configEvent)({ type: name }, xhrProxy);
  260. xhrProxy[callback] && xhrProxy[callback](event);
  261. var evt;
  262. if (typeof Event === 'function') {
  263. evt = new Event(name, { bubbles: false });
  264. } else {
  265. // https://stackoverflow.com/questions/27176983/dispatchevent-not-working-in-ie11
  266. evt = document.createEvent('Event');
  267. evt.initEvent(name, false, true);
  268. }
  269. getEventTarget(xhr).dispatchEvent(evt);
  270. }
  271.  
  272. function Handler(xhr) {
  273. this.xhr = xhr;
  274. this.xhrProxy = xhr.getProxy();
  275. }
  276.  
  277. Handler[prototype] = Object.create({
  278. resolve: function resolve(response) {
  279. var xhrProxy = this.xhrProxy;
  280. var xhr = this.xhr;
  281. xhrProxy.readyState = 4;
  282. xhr.resHeader = response.headers;
  283. xhrProxy.response = xhrProxy.responseText = response.response;
  284. xhrProxy.statusText = response.statusText;
  285. xhrProxy.status = response.status;
  286. triggerListener(xhr, eventReadyStateChange);
  287. triggerListener(xhr, eventLoad);
  288. triggerListener(xhr, eventLoadEnd);
  289. },
  290. reject: function reject(error) {
  291. this.xhrProxy.status = 0;
  292. triggerListener(this.xhr, error.type);
  293. triggerListener(this.xhr, eventLoadEnd);
  294. }
  295. });
  296.  
  297. function makeHandler(next) {
  298. function sub(xhr) {
  299. Handler.call(this, xhr);
  300. }
  301.  
  302. sub[prototype] = Object.create(Handler[prototype]);
  303. sub[prototype].next = next;
  304. return sub;
  305. }
  306.  
  307. var RequestHandler = makeHandler(function (rq) {
  308. var xhr = this.xhr;
  309. rq = rq || xhr.config;
  310. xhr.withCredentials = rq.withCredentials;
  311. xhr.open(rq.method, rq.url, rq.async !== false, rq.user, rq.password);
  312. for (var key in rq.headers) {
  313. xhr.setRequestHeader(key, rq.headers[key]);
  314. }
  315. xhr.send(rq.body);
  316. });
  317.  
  318. var ResponseHandler = makeHandler(function (response) {
  319. this.resolve(response);
  320. });
  321.  
  322. var ErrorHandler = makeHandler(function (error) {
  323. this.reject(error);
  324. });
  325.  
  326. function proxyAjax(proxy, win) {
  327. var onRequest = proxy.onRequest,
  328. onResponse = proxy.onResponse,
  329. onError = proxy.onError;
  330.  
  331. function handleResponse(xhr, xhrProxy) {
  332. var handler = new ResponseHandler(xhr);
  333. var ret = {
  334. response: xhrProxy.response || xhrProxy.responseText, //ie9
  335. status: xhrProxy.status,
  336. statusText: xhrProxy.statusText,
  337. config: xhr.config,
  338. headers: xhr.resHeader || xhr.getAllResponseHeaders().split('\r\n').reduce(function (ob, str) {
  339. if (str === "") return ob;
  340. var m = str.split(":");
  341. ob[m.shift()] = trim(m.join(':'));
  342. return ob;
  343. }, {})
  344. };
  345. if (!onResponse) return handler.resolve(ret);
  346. onResponse(ret, handler);
  347. }
  348.  
  349. function onerror(xhr, xhrProxy, error, errorType) {
  350. var handler = new ErrorHandler(xhr);
  351. error = { config: xhr.config, error: error, type: errorType };
  352. if (onError) {
  353. onError(error, handler);
  354. } else {
  355. handler.next(error);
  356. }
  357. }
  358.  
  359. function preventXhrProxyCallback() {
  360. return true;
  361. }
  362.  
  363. function errorCallback(errorType) {
  364. return function (xhr, e) {
  365. onerror(xhr, this, e, errorType);
  366. return true;
  367. };
  368. }
  369.  
  370. function stateChangeCallback(xhr, xhrProxy) {
  371. if (xhr.readyState === 4 && xhr.status !== 0) {
  372. handleResponse(xhr, xhrProxy);
  373. } else if (xhr.readyState !== 4) {
  374. triggerListener(xhr, eventReadyStateChange);
  375. }
  376. return true;
  377. }
  378.  
  379. return (0, _xhrHook.hook)({
  380. onload: preventXhrProxyCallback,
  381. onloadend: preventXhrProxyCallback,
  382. onerror: errorCallback(eventError),
  383. ontimeout: errorCallback(eventTimeout),
  384. onabort: errorCallback(eventAbort),
  385. onreadystatechange: function onreadystatechange(xhr) {
  386. return stateChangeCallback(xhr, this);
  387. },
  388. open: function open(args, xhr) {
  389. var _this = this;
  390. var config = xhr.config = { headers: {} };
  391. config.method = args[0];
  392. config.url = args[1];
  393. config.async = args[2];
  394. config.user = args[3];
  395. config.password = args[4];
  396. config.xhr = xhr;
  397. var evName = 'on' + eventReadyStateChange;
  398. if (!xhr[evName]) {
  399. xhr[evName] = function () {
  400. return stateChangeCallback(xhr, _this);
  401. };
  402. }
  403.  
  404. // 如果有请求拦截器,则在调用onRequest后再打开链接。因为onRequest最佳调用时机是在send前,
  405. // 所以我们在send拦截函数中再手动调用open,因此返回true阻止xhr.open调用。
  406. //
  407. // 如果没有请求拦截器,则不用阻断xhr.open调用
  408. if (onRequest) return true;
  409. },
  410. send: function send(args, xhr) {
  411. var config = xhr.config;
  412. config.withCredentials = xhr.withCredentials;
  413. config.body = args[0];
  414. if (onRequest) {
  415. // In 'onRequest', we may call XHR's event handler, such as `xhr.onload`.
  416. // However, XHR's event handler may not be set until xhr.send is called in
  417. // the user's code, so we use `setTimeout` to avoid this situation
  418. var req = function req() {
  419. onRequest(config, new RequestHandler(xhr));
  420. };
  421. config.async === false ? req() : setTimeout(req);
  422. return true;
  423. }
  424. },
  425. setRequestHeader: function setRequestHeader(args, xhr) {
  426. // Collect request headers
  427. xhr.config.headers[args[0].toLowerCase()] = args[1];
  428. if (onRequest) return true;
  429. },
  430. addEventListener: function addEventListener(args, xhr) {
  431. var _this = this;
  432. if (_xhrHook.events.indexOf(args[0]) !== -1) {
  433. var handler = args[1];
  434. getEventTarget(xhr).addEventListener(args[0], function (e) {
  435. var event = (0, _xhrHook.configEvent)(e, _this);
  436. event.type = args[0];
  437. event.isTrusted = true;
  438. handler.call(_this, event);
  439. });
  440. return true;
  441. }
  442. },
  443. getAllResponseHeaders: function getAllResponseHeaders(_, xhr) {
  444. var headers = xhr.resHeader;
  445. if (headers) {
  446. var header = "";
  447. for (var key in headers) {
  448. header += key + ': ' + headers[key] + '\r\n';
  449. }
  450. return header;
  451. }
  452. },
  453. getResponseHeader: function getResponseHeader(args, xhr) {
  454. var headers = xhr.resHeader;
  455. if (headers) {
  456. return headers[(args[0] || '').toLowerCase()];
  457. }
  458. }
  459. }, win);
  460. }
  461.  
  462. /***/ }),
  463. /* 2 */,
  464. /* 3 */
  465. /***/ (function(module, exports, __webpack_require__) {
  466.  
  467. "use strict";
  468.  
  469.  
  470. Object.defineProperty(exports, "__esModule", {
  471. value: true
  472. });
  473. exports.ah = undefined;
  474.  
  475. var _xhrHook = __webpack_require__(0);
  476.  
  477. var _xhrProxy = __webpack_require__(1);
  478.  
  479. // ah(ajax hook)
  480. /*
  481. * author: wendux
  482. * email: 824783146@qq.com
  483. * source code: https://github.com/wendux/Ajax-hook
  484. */
  485.  
  486. var ah = exports.ah = {
  487. proxy: _xhrProxy.proxy,
  488. unProxy: _xhrProxy.unProxy,
  489. hook: _xhrHook.hook,
  490. unHook: _xhrHook.unHook
  491. };
  492.  
  493. /***/ })
  494. /******/ ])));