边读边看图

图片预览:1、通过双击按键,把图片固定在页面上,边读文字边看图,同时支持缩放、移动功能; 2、使用浏览器查看在线图片或本地图片时,增加页面背景图,以便清晰显示当前图片轮廓 3、打开链接方式,总是以命名的新窗口 4、点击链接文本时,跳转相应链接 5、一键复制代码块:鼠标悬浮代码块后,点击显示的红色边框,复制到剪贴板 6、csdn(登录弹层移至左下角、代码内容全展示) 7、复制所选文字:鼠标选中文字,0.5秒后,自动复制到剪贴板

Verzia zo dňa 20.10.2023. Pozri najnovšiu verziu.

  1. // ==UserScript==
  2. // @name 边读边看图
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.6.12
  5. // @description 图片预览:1、通过双击按键,把图片固定在页面上,边读文字边看图,同时支持缩放、移动功能; 2、使用浏览器查看在线图片或本地图片时,增加页面背景图,以便清晰显示当前图片轮廓 3、打开链接方式,总是以命名的新窗口 4、点击链接文本时,跳转相应链接 5、一键复制代码块:鼠标悬浮代码块后,点击显示的红色边框,复制到剪贴板 6、csdn(登录弹层移至左下角、代码内容全展示) 7、复制所选文字:鼠标选中文字,0.5秒后,自动复制到剪贴板
  6. // @author Enjoy
  7. // @icon https://foruda.gitee.com/avatar/1671100286067517749/4867929_enjoy_li_1671100285.png!avatar60
  8. // @match *://*/*
  9. // @match file:///*
  10. // @exclude *localhost*
  11. // @exclude    *hrwork*
  12. // @exclude    *zhaopinyun*
  13. // @exclude    *zhidegan*
  14. // @grant GM_addElement
  15. // @grant GM_setClipboard
  16. // @license GPL License
  17. // 函数文档 https://www.tampermonkey.net/documentation.php#api:GM_addElement
  18. // @match *://mp.weixin.qq.com/s/*
  19. // ==/UserScript==
  20.  
  21. /******/ (() => { // webpackBootstrap
  22. /******/ "use strict";
  23. /******/ var __webpack_modules__ = ({
  24.  
  25. /***/ 446:
  26. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  27.  
  28. __webpack_require__.r(__webpack_exports__);
  29. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  30. /* harmony export */ createElement: () => (/* binding */ createElement),
  31. /* harmony export */ createElementTipFn: () => (/* binding */ createElementTipFn),
  32. /* harmony export */ doCopy: () => (/* binding */ doCopy),
  33. /* harmony export */ isContentEditableOfDOM: () => (/* binding */ isContentEditableOfDOM),
  34. /* harmony export */ isOperated: () => (/* binding */ isOperated),
  35. /* harmony export */ numbericalInterval: () => (/* binding */ numbericalInterval),
  36. /* harmony export */ prependMetaUF8: () => (/* binding */ prependMetaUF8)
  37. /* harmony export */ });
  38. /** @描述 函数文档 https://www.tampermonkey.net/documentation.php#api:GM_addElement */
  39. // $GM.createElement
  40. function createElement(tag) {
  41. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  42. var win = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window;
  43. if (!win.GM_createElement) {
  44. win.GM_createElement = GM_createElement;
  45. }
  46. return GM_createElement(tag, options);
  47. /**
  48. * @param {*} tag
  49. * @param {*} options {
  50. * idPrefix = `enjoy_${ENV_CRX}_${tag}`,
  51. * el = 'html',
  52. * autoInsert = true,
  53. * randomType = 'single',
  54. * id = '',
  55. * addPrefix = true,
  56. * insertType = tag === 'style' ? 'appendChild' : 'prepend',
  57. * }
  58. * @returns {*} dom
  59. */
  60. function GM_createElement(tag, options) {
  61. var _options$idPrefix = options.idPrefix,
  62. idPrefix = _options$idPrefix === void 0 ? "enjoy_".concat("ImgPreview", "_").concat(tag, "_") : _options$idPrefix,
  63. _options$el = options.el,
  64. el = _options$el === void 0 ? 'html' : _options$el,
  65. _options$autoInsert = options.autoInsert,
  66. autoInsert = _options$autoInsert === void 0 ? true : _options$autoInsert,
  67. _options$randomType = options.randomType,
  68. randomType = _options$randomType === void 0 ? 'single' : _options$randomType,
  69. _options$id = options.id,
  70. id = _options$id === void 0 ? '' : _options$id,
  71. _options$addPrefix = options.addPrefix,
  72. addPrefix = _options$addPrefix === void 0 ? true : _options$addPrefix,
  73. _options$insertType = options.insertType,
  74. insertType = _options$insertType === void 0 ? tag === 'style' ? 'appendChild' : 'prepend' : _options$insertType;
  75. if (addPrefix) {
  76. id = "".concat(idPrefix).concat(id);
  77. }
  78. if (randomType !== 'single') {
  79. id = "".concat(id, "_").concat(Math.floor(Math.random() * 1000));
  80. }
  81. options.id = id;
  82. var dom = document.querySelector("#".concat(id));
  83. if (!dom) {
  84. dom = document.createElement(tag);
  85. }
  86. for (var key in options) {
  87. if (Object.hasOwnProperty.call(options, key) && key !== 'el') {
  88. dom[key] = options[key];
  89. }
  90. }
  91. if (autoInsert) {
  92. if (typeof el === 'string') {
  93. el = document.querySelector(el);
  94. }
  95.  
  96. //insertType prepend | appendChild
  97. el[insertType](dom);
  98. }
  99. return dom;
  100. }
  101. }
  102. /** @描述 进入可以操作的页面 */
  103. function isOperated() {
  104. var urls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  105. var currentUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : location.href;
  106. if (typeof urls === 'string') {
  107. urls = [urls];
  108. }
  109. return !!urls.find(function (regUrl) {
  110. return new RegExp(regUrl).test(currentUrl);
  111. });
  112. }
  113. function prependMetaUF8() {
  114. return document.querySelector('meta[charset="UTF-8"]') || createElement('meta', {
  115. charset: 'utf-8'
  116. });
  117. }
  118. function doCopy(newValue) {
  119. var _navigator;
  120. var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'textarea';
  121. if ((_navigator = navigator) !== null && _navigator !== void 0 && (_navigator = _navigator.clipboard) !== null && _navigator !== void 0 && _navigator.writeText) {
  122. // 读取剪贴板
  123. // navigator.clipboard.readText().then((clipText) => {console.log('clipText=',clipText)})
  124.  
  125. // 写入剪贴板
  126. navigator.clipboard.writeText(newValue)["catch"](function (err) {
  127. return console.error("clipboard.writeText\uFF1A".concat(err));
  128. });
  129. return;
  130. }
  131. var textarea = createElement('textarea', {
  132. el: 'body',
  133. id: selector,
  134. style: 'position: absolute;left: -500px;top: -500px;max-width: 50px;opacity: 0;'
  135. });
  136. textarea.value = newValue;
  137. textarea.select();
  138. setTimeout(function () {
  139. document.execCommand('Copy');
  140. }, 200);
  141. }
  142. function createElementTipFn() {
  143. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  144. var _options$setTimeoutSt = options.setTimeoutStep,
  145. setTimeoutStep = _options$setTimeoutSt === void 0 ? 1000 : _options$setTimeoutSt,
  146. _options$backgroundCo = options.backgroundColors,
  147. backgroundColors = _options$backgroundCo === void 0 ? {
  148. warn: 'rgb(181 156 51 / 60%)',
  149. success: 'rgb(3 113 3 / 60%)',
  150. error: 'rgb(165 2 2 / 60%)',
  151. info: 'rgb(67 62 62 / 60%)'
  152. } : _options$backgroundCo,
  153. _options$color = options.color,
  154. color = _options$color === void 0 ? '#ffffff' : _options$color,
  155. _options$opacity = options.opacity,
  156. opacity = _options$opacity === void 0 ? 1 : _options$opacity;
  157. var setTimeoutStamp = 0;
  158. return function createElementTip() {
  159. var configs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  160. var content = configs.content,
  161. e = configs.e,
  162. _configs$type = configs.type,
  163. type = _configs$type === void 0 ? 'info' : _configs$type,
  164. _configs$tagType = configs.tagType,
  165. tagType = _configs$tagType === void 0 ? 'span' : _configs$tagType;
  166. if (!content) return;
  167. console.log("content => %O ", content);
  168. clearTimeout(setTimeoutStamp);
  169. var contentDom = createElement(tagType, {
  170. id: 'createElementTip',
  171. innerText: content,
  172. style: "\n font-size:14px;\n font-weight:600;\n color:".concat(color, ";\n position: fixed;\n left: ").concat(numbericalInterval(e.clientX - 46), "px;\n top: ").concat(numbericalInterval(e.clientY - 30, [5, window.innerHeight - 35]), "px;\n background-color:").concat(backgroundColors[type], ";\n opacity: ").concat(opacity, ";\n border-radius: 4px;\n padding: 4px 8px;\n box-shadow:0 0 5px 0 rgb(255 255 255 / 60%) inset;\n z-index:").concat((Math.floor(Date.now() / 1000) + '').slice(-5), "\n ")
  173. });
  174. setTimeoutStamp = setTimeout(function () {
  175. contentDom.remove();
  176. }, setTimeoutStep);
  177. };
  178. }
  179. /**
  180. * @description dom是否可编辑
  181. * @param {*} [dom=document.activeElement]
  182. * @returns {*} {boolean}
  183. */
  184. function isContentEditableOfDOM() {
  185. var dom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document.activeElement;
  186. var activeElement = dom;
  187. if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.contenEditable === 'true') return true;
  188. return false;
  189. }
  190. /**
  191. * @description 数字区间
  192. * @param {*} val
  193. * @param {*} [interval=[10, window.innerWidth]]
  194. * @returns {*}
  195. */
  196. function numbericalInterval(val) {
  197. var interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [5, window.innerWidth - 130];
  198. var indexStart = interval[0];
  199. var indexEnd = interval[1];
  200. if (val < indexStart) return indexStart;
  201. if (val > indexEnd) return indexEnd;
  202. return val;
  203. }
  204.  
  205. /***/ })
  206.  
  207. /******/ });
  208. /************************************************************************/
  209. /******/ // The module cache
  210. /******/ var __webpack_module_cache__ = {};
  211. /******/
  212. /******/ // The require function
  213. /******/ function __webpack_require__(moduleId) {
  214. /******/ // Check if module is in cache
  215. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  216. /******/ if (cachedModule !== undefined) {
  217. /******/ return cachedModule.exports;
  218. /******/ }
  219. /******/ // Create a new module (and put it into the cache)
  220. /******/ var module = __webpack_module_cache__[moduleId] = {
  221. /******/ // no module.id needed
  222. /******/ // no module.loaded needed
  223. /******/ exports: {}
  224. /******/ };
  225. /******/
  226. /******/ // Execute the module function
  227. /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  228. /******/
  229. /******/ // Return the exports of the module
  230. /******/ return module.exports;
  231. /******/ }
  232. /******/
  233. /************************************************************************/
  234. /******/ /* webpack/runtime/define property getters */
  235. /******/ (() => {
  236. /******/ // define getter functions for harmony exports
  237. /******/ __webpack_require__.d = (exports, definition) => {
  238. /******/ for(var key in definition) {
  239. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  240. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  241. /******/ }
  242. /******/ }
  243. /******/ };
  244. /******/ })();
  245. /******/
  246. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  247. /******/ (() => {
  248. /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  249. /******/ })();
  250. /******/
  251. /******/ /* webpack/runtime/make namespace object */
  252. /******/ (() => {
  253. /******/ // define __esModule on exports
  254. /******/ __webpack_require__.r = (exports) => {
  255. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  256. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  257. /******/ }
  258. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  259. /******/ };
  260. /******/ })();
  261. /******/
  262. /************************************************************************/
  263. var __webpack_exports__ = {};
  264. // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
  265. (() => {
  266.  
  267. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js
  268. function _arrayLikeToArray(arr, len) {
  269. if (len == null || len > arr.length) len = arr.length;
  270. for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  271. return arr2;
  272. }
  273. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js
  274.  
  275. function _arrayWithoutHoles(arr) {
  276. if (Array.isArray(arr)) return _arrayLikeToArray(arr);
  277. }
  278. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/iterableToArray.js
  279. function _iterableToArray(iter) {
  280. if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
  281. }
  282. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js
  283.  
  284. function _unsupportedIterableToArray(o, minLen) {
  285. if (!o) return;
  286. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  287. var n = Object.prototype.toString.call(o).slice(8, -1);
  288. if (n === "Object" && o.constructor) n = o.constructor.name;
  289. if (n === "Map" || n === "Set") return Array.from(o);
  290. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  291. }
  292. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js
  293. function _nonIterableSpread() {
  294. throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  295. }
  296. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js
  297.  
  298.  
  299.  
  300.  
  301. function _toConsumableArray(arr) {
  302. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
  303. }
  304. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/classCallCheck.js
  305. function _classCallCheck(instance, Constructor) {
  306. if (!(instance instanceof Constructor)) {
  307. throw new TypeError("Cannot call a class as a function");
  308. }
  309. }
  310. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/typeof.js
  311. function _typeof(o) {
  312. "@babel/helpers - typeof";
  313.  
  314. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
  315. return typeof o;
  316. } : function (o) {
  317. return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  318. }, _typeof(o);
  319. }
  320. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/toPrimitive.js
  321.  
  322. function _toPrimitive(input, hint) {
  323. if (_typeof(input) !== "object" || input === null) return input;
  324. var prim = input[Symbol.toPrimitive];
  325. if (prim !== undefined) {
  326. var res = prim.call(input, hint || "default");
  327. if (_typeof(res) !== "object") return res;
  328. throw new TypeError("@@toPrimitive must return a primitive value.");
  329. }
  330. return (hint === "string" ? String : Number)(input);
  331. }
  332. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js
  333.  
  334.  
  335. function _toPropertyKey(arg) {
  336. var key = _toPrimitive(arg, "string");
  337. return _typeof(key) === "symbol" ? key : String(key);
  338. }
  339. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/createClass.js
  340.  
  341. function _defineProperties(target, props) {
  342. for (var i = 0; i < props.length; i++) {
  343. var descriptor = props[i];
  344. descriptor.enumerable = descriptor.enumerable || false;
  345. descriptor.configurable = true;
  346. if ("value" in descriptor) descriptor.writable = true;
  347. Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  348. }
  349. }
  350. function _createClass(Constructor, protoProps, staticProps) {
  351. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  352. if (staticProps) _defineProperties(Constructor, staticProps);
  353. Object.defineProperty(Constructor, "prototype", {
  354. writable: false
  355. });
  356. return Constructor;
  357. }
  358. ;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@babel+runtime@7.22.15/node_modules/@babel/runtime/helpers/esm/defineProperty.js
  359.  
  360. function _defineProperty(obj, key, value) {
  361. key = _toPropertyKey(key);
  362. if (key in obj) {
  363. Object.defineProperty(obj, key, {
  364. value: value,
  365. enumerable: true,
  366. configurable: true,
  367. writable: true
  368. });
  369. } else {
  370. obj[key] = value;
  371. }
  372. return obj;
  373. }
  374. ;// CONCATENATED MODULE: ./src/ImgPreview.js
  375. /* provided dependency */ var $GM = __webpack_require__(446);
  376.  
  377.  
  378.  
  379.  
  380.  
  381. run(window);
  382. function run(win) {
  383. $GM.createElement('style', {
  384. innerHTML: ".pages_skin_pc .rich_media_area_primary_inner,.pages_skin_pc .rich_media_area_extra_inner{margin-left:initial !important;}"
  385. }, win);
  386. var ImgPreviwer = /*#__PURE__*/function () {
  387. function ImgPreviwer() {
  388. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  389. _classCallCheck(this, ImgPreviwer);
  390. /** @描述 状态 */
  391. _defineProperty(this, "state", null);
  392. _defineProperty(this, "shadowRoot", null);
  393. this.state = this.mergeOptions(options);
  394. this.shadowRoot = this.createShadowRoot();
  395. this.onPreviwerEvent();
  396. return this.shadowRoot;
  397. }
  398. _createClass(ImgPreviwer, [{
  399. key: "createShadowRoot",
  400. value: /** @描述 创建 shadowRoot */
  401. function createShadowRoot() {
  402. var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '#imgPreview';
  403. selector = selector.replace(/[.#]/g, '');
  404. var dom = document.querySelector("#".concat(selector));
  405. if (!dom) {
  406. dom = $GM.createElement('div', {
  407. addPrefix: false,
  408. id: selector,
  409. style: 'width:0;height:0'
  410. });
  411. }
  412. if (!dom.shadowRoot) {
  413. // 添加在body下,获取 dom.shadowRoot
  414. dom.attachShadow({
  415. mode: 'open'
  416. });
  417. // dom.shadowRoot.appendChild(maskContent)
  418. // 创建蒙层容器
  419. var maskContent = $GM.createElement('div', {
  420. className: 'modal',
  421. el: dom.shadowRoot
  422. });
  423. maskContent.appendChild(this.createStyle(this.state));
  424. }
  425. return dom.shadowRoot;
  426. }
  427. /** @描述 合并选项 */
  428. }, {
  429. key: "mergeOptions",
  430. value: function mergeOptions(options) {
  431. var opt = {};
  432. var defaultOptions = {
  433. contentSelector: 'body',
  434. selector: 'img',
  435. showRootSelector: '#img_preview',
  436. backgroundColor: 'rgba(0,0,0,0)',
  437. extraStyle: ''
  438. };
  439. Object.assign(opt, defaultOptions, options);
  440. return opt;
  441. }
  442. /** @描述 创建shadowbox中的样式 */
  443. }, {
  444. key: "createStyle",
  445. value: function createStyle(_ref) {
  446. var contentSelector = _ref.contentSelector,
  447. selector = _ref.selector,
  448. backgroundColor = _ref.backgroundColor,
  449. extraStyle = _ref.extraStyle;
  450. return $GM.createElement('style', {
  451. autoInsert: false,
  452. randomType: 'newOne',
  453. innerHTML: "".concat(contentSelector, " ").concat(selector, " {\n cursor: zoom-in;\n }\n /* \u56FE\u7247\u9884\u89C8 */\n .modal {\n touch-action: none;\n position: fixed;\n z-index: 99;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background-color: ").concat(backgroundColor, ";\n user-select: none;\n pointer-events: none;\n }\n .modal>*{\n pointer-events: auto;\n }\n .modal>img {\n position: absolute;\n padding: 0;\n margin: 0;\n box-shadow: rgb(27 115 7 / 71%) 0px 0px 5px 5px;\n border-radius: 10px;\n /* transition: all var(--delay_time); */\n transform: translateZ(0);\n }\n\n img.active {\n animation: activeImg 0.5s 4 ease-out forwards;\n transition: all;\n\n }\n\n @keyframes activeImg {\n 0% {\n box-shadow: rgb(27 115 7 / 71%) 0px 0px 5px 5px;\n }\n 50% {\n box-shadow: rgb(255 0 0 / 66%) 0px 0px 5px 5px;\n }\n 100% {\n box-shadow: rgb(239 126 4 / 75%) 0px 0px 5px 5px;\n }\n }\n ").concat(extraStyle, "\n ")
  454. });
  455. }
  456. /** @描述 预览操作 */
  457. }, {
  458. key: "onPreviwerEvent",
  459. value: function onPreviwerEvent() {
  460. var that = this;
  461. var _that$state = that.state,
  462. contentSelector = _that$state.contentSelector,
  463. selector = _that$state.selector;
  464. var eventsProxy = document.querySelector(contentSelector) || window.document.body;
  465. eventsProxy.addEventListener('dblclick', function (e) {
  466. var src = that.getImgSrc(e.target);
  467. if (!src) return;
  468. e.preventDefault();
  469. var findOneInPage = _toConsumableArray(eventsProxy.querySelectorAll(selector)).find(function (item) {
  470. return item === e.target;
  471. });
  472. if (findOneInPage) {
  473. var findOneInModal = _toConsumableArray(that.shadowRoot.querySelectorAll(selector)).find(function (item) {
  474. return that.getImgSrc(item) === src;
  475. });
  476. if (findOneInModal) {
  477. if (!findOneInModal.classList.contains('active')) {
  478. findOneInModal.classList.add('active');
  479. findOneInModal.remove();
  480. that.shadowRoot.querySelector('.modal').appendChild(findOneInModal);
  481. return;
  482. } else {
  483. findOneInModal.remove();
  484. findOneInModal = null;
  485. }
  486. }
  487. // else
  488. if (!findOneInModal) {
  489. // originalEl.style.opacity = 0
  490. new ImgPreviewer(that.shadowRoot, e.target, src);
  491. }
  492. }
  493. });
  494. }
  495. }, {
  496. key: "getImgSrc",
  497. value: function getImgSrc(dom) {
  498. var _dom$dataset, _window$getComputedSt;
  499. return (dom === null || dom === void 0 || (_dom$dataset = dom.dataset) === null || _dom$dataset === void 0 ? void 0 : _dom$dataset.src) || (dom === null || dom === void 0 ? void 0 : dom.src) || ((_window$getComputedSt = window.getComputedStyle(dom).backgroundImage.match(/^url\("([^\s]+)"\)$/i)) === null || _window$getComputedSt === void 0 ? void 0 : _window$getComputedSt[1]);
  500. }
  501. }]);
  502. return ImgPreviwer;
  503. }();
  504. var ImgPreviewer = /*#__PURE__*/function () {
  505. function ImgPreviewer(shadowRoot, originalEl, src) {
  506. var _this = this;
  507. _classCallCheck(this, ImgPreviewer);
  508. _defineProperty(this, "state", {
  509. scale: 1,
  510. offset: {
  511. left: 0,
  512. top: 0
  513. },
  514. origin: 'center',
  515. initialData: {
  516. offset: {},
  517. origin: 'center',
  518. scale: 1
  519. },
  520. startPoint: {
  521. x: 0,
  522. y: 0
  523. },
  524. // 记录初始触摸点位
  525. isTouching: false,
  526. // 标记是否正在移动
  527. isMove: false,
  528. // 正在移动中,与点击做区别
  529. touches: new Map(),
  530. // 触摸点数组
  531. lastDistance: 0,
  532. lastScale: 1,
  533. // 记录下最后的缩放值
  534. scaleOrigin: {
  535. x: 0,
  536. y: 0
  537. }
  538. });
  539. /** @描述 双击事件 */
  540. _defineProperty(this, "ondblclick", function (e) {
  541. e.preventDefault();
  542. var that = _this;
  543. var state = that.state;
  544. setTimeout(function () {
  545. if (state.isMove) {
  546. state.isMove = false;
  547. } else {
  548. that.changeStyle(state.cloneEl, ['transition: all .3s', "left: ".concat(state.left, "px"), "top: ".concat(state.top, "px"), "transform: translate(0,0)", "width: ".concat(state.offsetWidth, "px")]);
  549. setTimeout(function () {
  550. state.maskContent.removeChild(state.cloneEl);
  551. // originalEl.style.opacity = 1
  552. state.cloneEl.removeEventListener('dblclick', that.ondblclick);
  553. }, 300);
  554. }
  555. }, 280);
  556. });
  557. /** @描述 指针按下事件*/
  558. _defineProperty(this, "onpointerdown", function (e) {
  559. e.preventDefault();
  560. var that = _this;
  561. var state = that.state;
  562. state.touches.set(e.pointerId, e);
  563. // TODO: 点击存入触摸点
  564. state.isTouching = true;
  565. state.startPoint = {
  566. x: e.clientX,
  567. y: e.clientY
  568. };
  569. if (state.touches.size === 2) {
  570. // TODO: 判断双指触摸,并立即记录初始数据
  571. state.lastDistance = that.getDistance();
  572. state.lastScale = state.scale;
  573. }
  574. });
  575. /** @描述 滚轮缩放 */
  576. _defineProperty(this, "onmousewheel", function (e) {
  577. e.preventDefault();
  578. if (!e.deltaY) return;
  579. var that = _this;
  580. var state = that.state;
  581. state.origin = "".concat(e.offsetX, "px ").concat(e.offsetY, "px");
  582.  
  583. // 缩放执行
  584. if (e.deltaY < 0) {
  585. // 放大
  586. state.scale += 0.1;
  587. } else if (e.deltaY > 0) {
  588. state.scale >= 0.2 && (state.scale -= 0.1);
  589. // 缩小
  590. }
  591.  
  592. if (state.scale < state.initialData.scale) {
  593. console.log("state.scale < state.initialData.scale => %O ", state.scale, state.initialData.scale);
  594. that.reduction();
  595. }
  596. state.offset = that.getOffsetPageCenter(e.offsetX, e.offsetY);
  597. that.changeStyle(state.cloneEl, ['transition: all .15s', "transform-origin: ".concat(state.origin), "transform: translate(".concat(state.offset.left + 'px', ", ").concat(state.offset.top + 'px', ") scale(").concat(state.scale, ")")]);
  598. });
  599. /** @描述 松开指针 事件 */
  600. _defineProperty(this, "onpointerup", function (e) {
  601. e.preventDefault();
  602. var that = _this;
  603. var state = that.state;
  604. state.touches["delete"](e.pointerId);
  605. // TODO: 抬起移除触摸点
  606. if (state.touches.size <= 0) {
  607. state.isTouching = false;
  608. } else {
  609. var touchArr = Array.from(state.touches);
  610. // 更新点位
  611. state.startPoint = {
  612. x: touchArr[0][1].clientX,
  613. y: touchArr[0][1].clientY
  614. };
  615. }
  616. setTimeout(function () {
  617. state.isMove = false;
  618. }, 300);
  619. });
  620. /** @描述 指针移动事件 */
  621. _defineProperty(this, "onpointermove", function (e) {
  622. e.preventDefault();
  623. var that = _this;
  624. var state = that.state;
  625. if (state.isTouching) {
  626. state.isMove = true;
  627. if (state.touches.size < 2) {
  628. // 单指滑动
  629. state.offset = {
  630. left: state.offset.left + (e.clientX - state.startPoint.x),
  631. top: state.offset.top + (e.clientY - state.startPoint.y)
  632. };
  633. that.changeStyle(state.cloneEl, ['transition: all 0s', "transform: translate(".concat(state.offset.left + 'px', ", ").concat(state.offset.top + 'px', ") scale(").concat(state.scale, ")"), "transform-origin: ".concat(origin)]);
  634. // 更新点位
  635. state.startPoint = {
  636. x: e.clientX,
  637. y: e.clientY
  638. };
  639. } else {
  640. // 双指缩放
  641. state.touches.set(e.pointerId, e);
  642. var ratio = that.getDistance() / state.lastDistance;
  643. state.scale = ratio * state.lastScale;
  644. state.offset = that.getOffsetPageCenter();
  645. if (state.scale < state.initialData.scale) {
  646. that.reduction();
  647. }
  648. that.changeStyle(state.cloneEl, ['transition: all 0s', "transform: translate(".concat(state.offset.left + 'px', ", ").concat(state.offset.top + 'px', ") scale(").concat(state.scale, ")"), "transform-origin: ".concat(state.origin)]);
  649. }
  650. }
  651. });
  652. /** @描述 取消指针事件 */
  653. _defineProperty(this, "onpointercancel", function (e) {
  654. e.preventDefault();
  655. _this.state.touches.clear();
  656. // 可能存在特定事件导致中断,真机操作时 pointerup 在某些边界情况下不会生效,所以需要清空
  657. });
  658. this.state = Object.assign({}, this.state, this.mergeOptions(shadowRoot, originalEl, src));
  659. var cloneEl = this.appendImg(src, originalEl);
  660. this.state.cloneEl = cloneEl;
  661. this.fixPosition(cloneEl);
  662. this.addEvents(cloneEl);
  663. return cloneEl;
  664. }
  665. _createClass(ImgPreviewer, [{
  666. key: "mergeOptions",
  667. value: function mergeOptions(shadowRoot, originalEl, src) {
  668. var _window = window,
  669. winWidth = _window.innerWidth,
  670. winHeight = _window.innerHeight;
  671. var offsetWidth = originalEl.offsetWidth,
  672. offsetHeight = originalEl.offsetHeight;
  673.  
  674. // Element.getBoundingClientRect() 方法返回元素的大小及其相对于【视口】的位置
  675. var _originalEl$getBoundi = originalEl.getBoundingClientRect(),
  676. top = _originalEl$getBoundi.top,
  677. left = _originalEl$getBoundi.left;
  678. return {
  679. shadowRoot: shadowRoot,
  680. originalEl: originalEl,
  681. src: src,
  682. winWidth: winWidth,
  683. winHeight: winHeight,
  684. offsetWidth: offsetWidth,
  685. offsetHeight: offsetHeight,
  686. top: top,
  687. left: left,
  688. maskContent: shadowRoot.querySelector('.modal')
  689. };
  690. }
  691. /** @描述 添加图片 */
  692. }, {
  693. key: "appendImg",
  694. value: function appendImg(src, originalEl) {
  695. // let cloneEl = document.createElement('img')
  696. // cloneEl.src = src
  697. // 克隆节点 能从缓存中获取图片,以便节省流量
  698. var cloneEl = originalEl.cloneNode();
  699. this.state.maskContent.appendChild(cloneEl);
  700. return cloneEl;
  701. }
  702. /** @描述 添加监听事件 */
  703. }, {
  704. key: "addEvents",
  705. value: function addEvents(cloneEl) {
  706. var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['dblclick', 'mousewheel', 'pointerdown', 'pointerup', 'pointermove', 'pointercancel'];
  707. var that = this;
  708. events.forEach(function (item) {
  709. if (item === 'mousewheel') {
  710. cloneEl.addEventListener('mousewheel', that["on".concat(item)], {
  711. passive: false
  712. });
  713. return;
  714. }
  715. cloneEl.addEventListener(item, that["on".concat(item)]);
  716. });
  717. }
  718. }, {
  719. key: "getOffsetPageCenter",
  720. value: /** @描述 获取中心改变的偏差 */
  721. function getOffsetPageCenter() {
  722. var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  723. var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  724. var state = this.state;
  725. var touchArr = Array.from(state.touches);
  726. if (touchArr.length === 2) {
  727. var start = touchArr[0][1];
  728. var end = touchArr[1][1];
  729. x = (start.offsetX + end.offsetX) / 2;
  730. y = (start.offsetY + end.offsetY) / 2;
  731. }
  732. state.origin = "".concat(x, "px ").concat(y, "px");
  733. var offsetLeft = (state.scale - 1) * (x - state.scaleOrigin.x) + state.offset.left;
  734. var offsetTop = (state.scale - 1) * (y - state.scaleOrigin.y) + state.offset.top;
  735. state.scaleOrigin = {
  736. x: x,
  737. y: y
  738. };
  739. return {
  740. left: offsetLeft,
  741. top: offsetTop
  742. };
  743. }
  744.  
  745. /** @描述 获取距离*/
  746. }, {
  747. key: "getDistance",
  748. value: function getDistance() {
  749. var touchArr = Array.from(this.state.touches);
  750. if (touchArr.length < 2) {
  751. return 0;
  752. }
  753. var start = touchArr[0][1];
  754. var end = touchArr[1][1];
  755. return Math.hypot(end.x - start.x, end.y - start.y);
  756. }
  757.  
  758. /** @描述 修改样式,减少回流重绘*/
  759. }, {
  760. key: "changeStyle",
  761. value: function changeStyle(el, arr) {
  762. var original = el.style.cssText.split(';');
  763. original.pop();
  764. el.style.cssText = original.concat(arr).join(';') + ';';
  765. }
  766.  
  767. /** @描述 还原记录,用于边界处理 */
  768. }, {
  769. key: "reduction",
  770. value: function reduction() {
  771. var that = this;
  772. var state = that.state;
  773. that.timer && clearTimeout(that.timer);
  774. that.timer = setTimeout(function () {
  775. // offset = state.initialData.offset
  776. // origin = state.initialData.origin
  777. // scale = state.initialData.scale
  778. console.log("state => %O ", state);
  779. that.changeStyle(state.cloneEl, ["transform: translate(".concat(state.offset.left + 'px', ", ").concat(state.offset.top + 'px', ") scale(").concat(state.scale, ")"), "transform-origin: ".concat(state.origin)]);
  780. }, 300);
  781. }
  782. }, {
  783. key: "fixPosition",
  784. value: /** @描述 移动图片到屏幕中心位置 */
  785. function fixPosition(cloneEl) {
  786. var that = this;
  787. var state = that.state;
  788.  
  789. /** @描述 原图片 中心点 */
  790. var originalCenterPoint = {
  791. x: state.offsetWidth / 2 + state.left,
  792. y: state.offsetHeight / 2 + state.top
  793. };
  794.  
  795. /** @描述 页面 中心点 */
  796. var winCenterPoint = {
  797. x: state.winWidth / 2,
  798. y: state.winHeight / 2
  799. };
  800.  
  801. /** @描述 新建图片的定位点:通过原图片中心点到页面中心点的 偏移量*/
  802. var offsetDistance = {
  803. left: winCenterPoint.x - originalCenterPoint.x + state.left,
  804. top: winCenterPoint.y - originalCenterPoint.y + state.top
  805. };
  806.  
  807. /** @描述 放大后的 */
  808. var scaleNum = this.adaptScale();
  809. var diffs = {
  810. left: (scaleNum - 1) * state.offsetWidth / 2,
  811. top: (scaleNum - 1) * state.offsetHeight / 2
  812. };
  813. this.changeStyle(cloneEl, ["left: ".concat(state.left, "px"), "top: ".concat(state.top, "px"), 'transition: all 0.3s', "width: ".concat(state.offsetWidth * scaleNum + 'px'), "transform: translate(".concat(offsetDistance.left - state.left - diffs.left, "px, ").concat(offsetDistance.top - state.top - diffs.top, "px)")]);
  814.  
  815. /** @描述 消除偏差:让图片相对于window 0 0定位,通过translate设置中心点重合*/
  816. setTimeout(function () {
  817. that.changeStyle(cloneEl, ['transition: all 0s', "left: 0", "top: 0", "transform: translate(".concat(offsetDistance.left - diffs.left, "px, ").concat(offsetDistance.top - diffs.top, "px)")]);
  818. that.state.offset = {
  819. left: offsetDistance.left - diffs.left,
  820. top: offsetDistance.top - diffs.top
  821. };
  822. // 记录值
  823. that.record();
  824. }, 300);
  825. }
  826. /** @描述 记录初始化数据 */
  827. }, {
  828. key: "record",
  829. value: function record() {
  830. var state = this.state;
  831. state.initialData = Object.assign({}, {
  832. offset: state.offset,
  833. origin: state.origin,
  834. scale: state.scale
  835. });
  836. }
  837. /** @描述 计算自适应屏幕的缩放 */
  838. }, {
  839. key: "adaptScale",
  840. value: function adaptScale() {
  841. var _this$state = this.state,
  842. winWidth = _this$state.winWidth,
  843. winHeight = _this$state.winHeight,
  844. originalEl = _this$state.originalEl;
  845. var w = originalEl.offsetWidth,
  846. h = originalEl.offsetHeight;
  847. var scale = winWidth / w;
  848. if (h * scale > winHeight - 80) {
  849. scale = (winHeight - 80) / h;
  850. }
  851. return scale;
  852. }
  853. }]);
  854. return ImgPreviewer;
  855. }();
  856. var shadowRoot = new ImgPreviwer({
  857. backgroundColor: 'transparent'
  858. });
  859. addBackgroundImg();
  860.  
  861. /** @描述 添加背景色*/
  862. function addBackgroundImg() {
  863. var bgImage = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDY0IDY0Ij4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLmNscy0xIHsKICAgICAgICBmaWxsOiAjMzAzMDMwOwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICMyMDIwMjA7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxyZWN0IGlkPSJsdCIgY2xhc3M9ImNscy0xIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiLz4KICA8cmVjdCBpZD0icmIiIGNsYXNzPSJjbHMtMSIgeD0iMzIiIHk9IjMyIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiLz4KICA8cmVjdCBpZD0ibGIiIGNsYXNzPSJjbHMtMiIgeT0iMzIiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIvPgogIDxyZWN0IGlkPSJydCIgY2xhc3M9ImNscy0yIiB4PSIzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIi8+Cjwvc3ZnPgo=";
  864. var ua = navigator.userAgent.toLowerCase();
  865. var doc = document.body || document.documentElement;
  866. var isQQBrowser = ua.indexOf('qqbrowser/') > -1;
  867. var isQQBrowserPS = function isQQBrowserPS() {
  868. return document && document.body && document.body.classList.contains('qb-picture-ps');
  869. };
  870. if (document.contentType.startsWith('image/')) {
  871. if (isQQBrowser && doc.tagName !== 'svg') {
  872. setTimeout(function () {
  873. loaded();
  874. }, 666);
  875. } else {
  876. loaded();
  877. }
  878. }
  879. return;
  880. function loaded() {
  881. var docTagName = function (tag) {
  882. var tagName = tag && tag.tagName.toLowerCase();
  883. if (tagName) {
  884. if (tagName == 'svg') {
  885. return tagName;
  886. }
  887. if (tagName == 'body' && tag.children && tag.children.length) {
  888. tagName = tag.children[0].tagName.toLowerCase();
  889. if (tagName == 'img') {
  890. return tagName;
  891. } else {
  892. tagName = document.querySelector('img');
  893. return tagName && tagName.tagName && tagName.tagName.toLowerCase();
  894. }
  895. }
  896. }
  897. }(doc);
  898. var isViewerMode = docTagName == 'svg' || docTagName == 'img';
  899. if (isViewerMode) {
  900. if (document.head) {
  901. var styleText = [];
  902. if (isQQBrowserPS()) {
  903. styleText.push("body{box-sizing: border-box;background-attachment: fixed !important;background-repeat: repeat !important;}");
  904. styleText.push("body{background: url(".concat(bgImage, ") !important;}"));
  905. } else {
  906. styleText.push("img{position: static !important;background: none !important;background-color: transparent !important;}");
  907. }
  908. $GM.createElement('style', {
  909. randomType: 'newOne',
  910. el: 'head',
  911. type: 'text/css',
  912. innerHTML: styleText.join('')
  913. }, win);
  914. }
  915. if (isQQBrowserPS()) {
  916. doc.style.position = 'static';
  917. doc.style.top = 'auto';
  918. doc.style.left = 'auto';
  919. doc.style.transform = 'none';
  920. } else {
  921. doc.style.backgroundImage = "url(".concat(bgImage, ")");
  922. doc.style.backgroundAttachment = 'fixed';
  923. doc.style.boxSizing = 'border-box';
  924. if (docTagName == 'svg') {
  925. doc.style.position = 'absolute';
  926. doc.style.top = '50%';
  927. doc.style.left = '50%';
  928. doc.style.transform = 'translate(-50%, -50%)';
  929. doc.style.margin = '10px';
  930. doc.style.width = 'auto';
  931. doc.style.height = 'auto';
  932. doc.style.maxWidth = '100%';
  933. doc.style.maxHeight = '100%';
  934. }
  935. }
  936. }
  937. }
  938. }
  939. function createFaviconElementInMyPageByIP() {
  940. if (location.hostname === '127.0.0.1') {
  941. $GM.createElement('link', {
  942. el: 'head',
  943. rel: 'shortcut icon',
  944. href: 'https://www.runoob.com/images/compatible_opera.gif',
  945. type: 'image/x-icon'
  946. });
  947. }
  948. }
  949. createFaviconElementInMyPageByIP();
  950.  
  951. // 新页面打开链接 3、打开链接方式,总是以命名的新窗口 4、点击链接文本时,跳转相应链接 5、一键复制代码:鼠标悬浮代码,点击红色边框 6、csdn登录弹层移至左侧
  952. $GM.createElement('style', {
  953. el: 'head',
  954. id: 'a_click_target',
  955. randomType: 'newOne',
  956. textContent: "\n /* \u6253\u5F00\u94FE\u63A5\u65B9\u5F0F\uFF0C\u603B\u662F\u4EE5\u547D\u540D\u7684\u65B0\u7A97\u53E3 */\n a[href*='/']>*{\n pointer-events: none;\n }\n a{\n display: inline-block;\n }\n\n /* \u4E00\u952E\u590D\u5236\u4EE3\u7801\uFF1A\u9F20\u6807\u60AC\u6D6E\u4EE3\u7801\uFF0C\u70B9\u51FB\u7EA2\u8272\u8FB9\u6846 */\n pre,blockquote{\n border-left:10px solid transparent !important;\n }\n pre:hover,blockquote:hover{\n border-left-color: #670303 !important;\n }\n /* \u9690\u85CF\u3010\u767B\u5F55\u540E\u590D\u5236\u3011\u6587\u6848*/\n .hljs-button.signin{\n opacity:0;\n }\n\n /* csdn\u767B\u5F55\u5F39\u5C42\u79FB\u81F3\u5DE6\u4E0B\u89D2 */\n .passport-login-container {\n top:calc(100vh - 485px) !important;\n width:410px !important;\n height: 520px !important;\n border-radius: 8px !important;\n box-shadow: -5px 5px 10px 5px #979393 !important;\n transform: scale(0.8) !important;\n left: -24px;\n }\n .passport-login-mark {\n display:none !important;\n }\n\n /* csdn \u4EE3\u7801\u5185\u5BB9\u5168\u5C55\u793A */\n .hide-preCode-box{\n padding-top:0px !important;\n }\n "
  957. });
  958. /*
  959. .passport-login-container{
  960. display:none;
  961. }
  962. .toolbar-btn-loginfun{}
  963. */
  964. // 2、a链接方式,总是以命名方式在新窗口打开
  965. var createElementTip = $GM.createElementTipFn();
  966. window.addEventListener('click', function (e) {
  967. var _location$href, _dom$getAttribute, _dom$getAttribute$mat, _dom$getAttribute2, _dom$getAttribute2$re, _dom$getAttribute2$re2;
  968. // boss不支持操作
  969. if ((_location$href = location.href) !== null && _location$href !== void 0 && _location$href.includes('www.zhipin.com')) return;
  970. var dom = e.target;
  971. // 非锚点的a 打开链接方式,总是以命名的新窗口
  972. if (dom.tagName === 'A' && !((_dom$getAttribute = dom.getAttribute('href')) !== null && _dom$getAttribute !== void 0 && (_dom$getAttribute$mat = _dom$getAttribute.match) !== null && _dom$getAttribute$mat !== void 0 && _dom$getAttribute$mat.call(_dom$getAttribute, /^javascript:/)) && !((_dom$getAttribute2 = dom.getAttribute('href')) !== null && _dom$getAttribute2 !== void 0 && (_dom$getAttribute2$re = _dom$getAttribute2.replace) !== null && _dom$getAttribute2$re !== void 0 && (_dom$getAttribute2$re = _dom$getAttribute2$re.call(_dom$getAttribute2, location.href, '')) !== null && _dom$getAttribute2$re !== void 0 && (_dom$getAttribute2$re2 = _dom$getAttribute2$re.match) !== null && _dom$getAttribute2$re2 !== void 0 && _dom$getAttribute2$re2.call(_dom$getAttribute2$re, /^#/))) {
  973. var newTabWindosName = dom.innerText.replace(/\s/g, '').slice(0, 30);
  974. if (window.name === newTabWindosName) {
  975. newTabWindosName = newTabWindosName + 'extra';
  976. }
  977. dom.setAttribute('target', newTabWindosName);
  978. }
  979. }, {
  980. capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  981. });
  982.  
  983. // 代码code时,复制代码内容
  984. window.addEventListener('click', function (e) {
  985. if ($GM.isContentEditableOfDOM()) return;
  986. var dom = e.target;
  987. var selectedText = window.getSelection().toString();
  988. if (dom.tagName === 'PRE' || dom.tagName === 'BLOCKQUOTE') {
  989. var _dom$querySelector;
  990. var willCopyText = selectedText || ((_dom$querySelector = dom.querySelector('code')) === null || _dom$querySelector === void 0 ? void 0 : _dom$querySelector.innerText) || dom.innerText;
  991. copyTextAndTip(e, willCopyText, selectedText);
  992. } else if (selectedText) {
  993. copyTextAndTip(e, '', selectedText);
  994. }
  995. }, {
  996. capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  997. });
  998.  
  999. function copyTextAndTip(e, willCopyText, selectedText) {
  1000. setTimeout(function () {
  1001. createElementTip({
  1002. e: e,
  1003. content: selectedText ? '文字_复制成功' : '代码块_复制成功'
  1004. });
  1005. $GM.doCopy(willCopyText || selectedText);
  1006. }, 500);
  1007. }
  1008.  
  1009. // 3、含有链接的文本,点击时跳转相应链接
  1010. window.addEventListener('click', function (e) {
  1011. var _innerTextsOfAllText$;
  1012. if ($GM.isContentEditableOfDOM()) return;
  1013.  
  1014. // 如果处于选中文字状态,则不进行跳转操作
  1015. if (window.getSelection().toString()) return;
  1016. var dom = e.target;
  1017. if (!(e.button === 0 && dom.tagName !== 'A')) return;
  1018. var innerTextsOfAllText = _toConsumableArray(dom.childNodes).reduce(function (pre, cur) {
  1019. if (!(cur.nodeName === '#text' && cur.textContent)) return pre;
  1020. return pre = "".concat(pre, " ").concat(cur.textContent);
  1021. }, '');
  1022. var url = innerTextsOfAllText === null || innerTextsOfAllText === void 0 || (_innerTextsOfAllText$ = innerTextsOfAllText.match) === null || _innerTextsOfAllText$ === void 0 ? void 0 : _innerTextsOfAllText$.call(innerTextsOfAllText, /https?:\/\/[\S]{4,}/);
  1023. if (url) {
  1024. window.open(url[0], url[0]);
  1025. }
  1026. }, {
  1027. capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  1028. });
  1029. }
  1030. })();
  1031.  
  1032. /******/ })()
  1033. ;