边读边看图

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

ของเมื่อวันที่ 20-10-2023 ดู เวอร์ชันล่าสุด

// ==UserScript==
// @name         边读边看图
// @namespace    http://tampermonkey.net/
// @version      0.6.12
// @description  图片预览:1、通过双击按键,把图片固定在页面上,边读文字边看图,同时支持缩放、移动功能; 2、使用浏览器查看在线图片或本地图片时,增加页面背景图,以便清晰显示当前图片轮廓 3、打开链接方式,总是以命名的新窗口 4、点击链接文本时,跳转相应链接 5、一键复制代码块:鼠标悬浮代码块后,点击显示的红色边框,复制到剪贴板  6、csdn(登录弹层移至左下角、代码内容全展示) 7、复制所选文字:鼠标选中文字,0.5秒后,自动复制到剪贴板
// @author       Enjoy
// @icon         https://foruda.gitee.com/avatar/1671100286067517749/4867929_enjoy_li_1671100285.png!avatar60
// @match        *://*/*
// @match        file:///*
// @exclude      *localhost*
// @exclude    *hrwork*
// @exclude    *zhaopinyun*
// @exclude    *zhidegan*
// @grant        GM_addElement
// @grant        GM_setClipboard
// @license      GPL License
// 函数文档 https://www.tampermonkey.net/documentation.php#api:GM_addElement
// @match        *://mp.weixin.qq.com/s/*
// ==/UserScript==

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ 446:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createElement: () => (/* binding */ createElement),
/* harmony export */   createElementTipFn: () => (/* binding */ createElementTipFn),
/* harmony export */   doCopy: () => (/* binding */ doCopy),
/* harmony export */   isContentEditableOfDOM: () => (/* binding */ isContentEditableOfDOM),
/* harmony export */   isOperated: () => (/* binding */ isOperated),
/* harmony export */   numbericalInterval: () => (/* binding */ numbericalInterval),
/* harmony export */   prependMetaUF8: () => (/* binding */ prependMetaUF8)
/* harmony export */ });
/** @描述 函数文档 https://www.tampermonkey.net/documentation.php#api:GM_addElement */
// $GM.createElement
function createElement(tag) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var win = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window;
  if (!win.GM_createElement) {
    win.GM_createElement = GM_createElement;
  }
  return GM_createElement(tag, options);
  /**
   * @param {*} tag
   * @param {*}  options {
   * 			idPrefix = `enjoy_${ENV_CRX}_${tag}`,
   * 			el = 'html',
   * 			autoInsert = true,
   * 			randomType = 'single',
   * 			id = '',
   * 			addPrefix = true,
   * 			insertType = tag === 'style' ? 'appendChild' : 'prepend',
   * 		}
   * @returns {*} dom
   */
  function GM_createElement(tag, options) {
    var _options$idPrefix = options.idPrefix,
      idPrefix = _options$idPrefix === void 0 ? "enjoy_".concat("ImgPreview", "_").concat(tag, "_") : _options$idPrefix,
      _options$el = options.el,
      el = _options$el === void 0 ? 'html' : _options$el,
      _options$autoInsert = options.autoInsert,
      autoInsert = _options$autoInsert === void 0 ? true : _options$autoInsert,
      _options$randomType = options.randomType,
      randomType = _options$randomType === void 0 ? 'single' : _options$randomType,
      _options$id = options.id,
      id = _options$id === void 0 ? '' : _options$id,
      _options$addPrefix = options.addPrefix,
      addPrefix = _options$addPrefix === void 0 ? true : _options$addPrefix,
      _options$insertType = options.insertType,
      insertType = _options$insertType === void 0 ? tag === 'style' ? 'appendChild' : 'prepend' : _options$insertType;
    if (addPrefix) {
      id = "".concat(idPrefix).concat(id);
    }
    if (randomType !== 'single') {
      id = "".concat(id, "_").concat(Math.floor(Math.random() * 1000));
    }
    options.id = id;
    var dom = document.querySelector("#".concat(id));
    if (!dom) {
      dom = document.createElement(tag);
    }
    for (var key in options) {
      if (Object.hasOwnProperty.call(options, key) && key !== 'el') {
        dom[key] = options[key];
      }
    }
    if (autoInsert) {
      if (typeof el === 'string') {
        el = document.querySelector(el);
      }

      //insertType  prepend | appendChild
      el[insertType](dom);
    }
    return dom;
  }
}
/** @描述 进入可以操作的页面 */
function isOperated() {
  var urls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var currentUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : location.href;
  if (typeof urls === 'string') {
    urls = [urls];
  }
  return !!urls.find(function (regUrl) {
    return new RegExp(regUrl).test(currentUrl);
  });
}
function prependMetaUF8() {
  return document.querySelector('meta[charset="UTF-8"]') || createElement('meta', {
    charset: 'utf-8'
  });
}
function doCopy(newValue) {
  var _navigator;
  var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'textarea';
  if ((_navigator = navigator) !== null && _navigator !== void 0 && (_navigator = _navigator.clipboard) !== null && _navigator !== void 0 && _navigator.writeText) {
    // 读取剪贴板
    // navigator.clipboard.readText().then((clipText) => {console.log('clipText=',clipText)})

    // 写入剪贴板
    navigator.clipboard.writeText(newValue)["catch"](function (err) {
      return console.error("clipboard.writeText\uFF1A".concat(err));
    });
    return;
  }
  var textarea = createElement('textarea', {
    el: 'body',
    id: selector,
    style: 'position: absolute;left: -500px;top: -500px;max-width: 50px;opacity: 0;'
  });
  textarea.value = newValue;
  textarea.select();
  setTimeout(function () {
    document.execCommand('Copy');
  }, 200);
}
function createElementTipFn() {
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var _options$setTimeoutSt = options.setTimeoutStep,
    setTimeoutStep = _options$setTimeoutSt === void 0 ? 1000 : _options$setTimeoutSt,
    _options$backgroundCo = options.backgroundColors,
    backgroundColors = _options$backgroundCo === void 0 ? {
      warn: 'rgb(181 156 51 / 60%)',
      success: 'rgb(3 113 3 / 60%)',
      error: 'rgb(165 2 2 / 60%)',
      info: 'rgb(67 62 62 / 60%)'
    } : _options$backgroundCo,
    _options$color = options.color,
    color = _options$color === void 0 ? '#ffffff' : _options$color,
    _options$opacity = options.opacity,
    opacity = _options$opacity === void 0 ? 1 : _options$opacity;
  var setTimeoutStamp = 0;
  return function createElementTip() {
    var configs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var content = configs.content,
      e = configs.e,
      _configs$type = configs.type,
      type = _configs$type === void 0 ? 'info' : _configs$type,
      _configs$tagType = configs.tagType,
      tagType = _configs$tagType === void 0 ? 'span' : _configs$tagType;
    if (!content) return;
    console.log("content => %O ", content);
    clearTimeout(setTimeoutStamp);
    var contentDom = createElement(tagType, {
      id: 'createElementTip',
      innerText: content,
      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            ")
    });
    setTimeoutStamp = setTimeout(function () {
      contentDom.remove();
    }, setTimeoutStep);
  };
}
/**
 * @description dom是否可编辑
 * @param {*} [dom=document.activeElement]
 * @returns {*}  {boolean}
 */
function isContentEditableOfDOM() {
  var dom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document.activeElement;
  var activeElement = dom;
  if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.contenEditable === 'true') return true;
  return false;
}
/**
 * @description 数字区间
 * @param {*} val
 * @param {*} [interval=[10, window.innerWidth]]
 * @returns {*}
 */
function numbericalInterval(val) {
  var interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [5, window.innerWidth - 130];
  var indexStart = interval[0];
  var indexEnd = interval[1];
  if (val < indexStart) return indexStart;
  if (val > indexEnd) return indexEnd;
  return val;
}

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {

;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  return arr2;
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js

function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/iterableToArray.js
function _iterableToArray(iter) {
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js
function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js




function _toConsumableArray(arr) {
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/classCallCheck.js
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/typeof.js
function _typeof(o) {
  "@babel/helpers - typeof";

  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
    return typeof o;
  } : function (o) {
    return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  }, _typeof(o);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/toPrimitive.js

function _toPrimitive(input, hint) {
  if (_typeof(input) !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (_typeof(res) !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js


function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return _typeof(key) === "symbol" ? key : String(key);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/createClass.js

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  }
}
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/defineProperty.js

function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
;// CONCATENATED MODULE: ./src/ImgPreview.js
/* provided dependency */ var $GM = __webpack_require__(446);





run(window);
function run(win) {
  $GM.createElement('style', {
    innerHTML: ".pages_skin_pc .rich_media_area_primary_inner,.pages_skin_pc .rich_media_area_extra_inner{margin-left:initial !important;}"
  }, win);
  var ImgPreviwer = /*#__PURE__*/function () {
    function ImgPreviwer() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      _classCallCheck(this, ImgPreviwer);
      /** @描述 状态 */
      _defineProperty(this, "state", null);
      _defineProperty(this, "shadowRoot", null);
      this.state = this.mergeOptions(options);
      this.shadowRoot = this.createShadowRoot();
      this.onPreviwerEvent();
      return this.shadowRoot;
    }
    _createClass(ImgPreviwer, [{
      key: "createShadowRoot",
      value: /** @描述 创建 shadowRoot */
      function createShadowRoot() {
        var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '#imgPreview';
        selector = selector.replace(/[.#]/g, '');
        var dom = document.querySelector("#".concat(selector));
        if (!dom) {
          dom = $GM.createElement('div', {
            addPrefix: false,
            id: selector,
            style: 'width:0;height:0'
          });
        }
        if (!dom.shadowRoot) {
          // 添加在body下,获取 dom.shadowRoot
          dom.attachShadow({
            mode: 'open'
          });
          // dom.shadowRoot.appendChild(maskContent)
          // 创建蒙层容器
          var maskContent = $GM.createElement('div', {
            className: 'modal',
            el: dom.shadowRoot
          });
          maskContent.appendChild(this.createStyle(this.state));
        }
        return dom.shadowRoot;
      }
      /** @描述 合并选项 */
    }, {
      key: "mergeOptions",
      value: function mergeOptions(options) {
        var opt = {};
        var defaultOptions = {
          contentSelector: 'body',
          selector: 'img',
          showRootSelector: '#img_preview',
          backgroundColor: 'rgba(0,0,0,0)',
          extraStyle: ''
        };
        Object.assign(opt, defaultOptions, options);
        return opt;
      }
      /** @描述 创建shadowbox中的样式 */
    }, {
      key: "createStyle",
      value: function createStyle(_ref) {
        var contentSelector = _ref.contentSelector,
          selector = _ref.selector,
          backgroundColor = _ref.backgroundColor,
          extraStyle = _ref.extraStyle;
        return $GM.createElement('style', {
          autoInsert: false,
          randomType: 'newOne',
          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          ")
        });
      }
      /** @描述 预览操作 */
    }, {
      key: "onPreviwerEvent",
      value: function onPreviwerEvent() {
        var that = this;
        var _that$state = that.state,
          contentSelector = _that$state.contentSelector,
          selector = _that$state.selector;
        var eventsProxy = document.querySelector(contentSelector) || window.document.body;
        eventsProxy.addEventListener('dblclick', function (e) {
          var src = that.getImgSrc(e.target);
          if (!src) return;
          e.preventDefault();
          var findOneInPage = _toConsumableArray(eventsProxy.querySelectorAll(selector)).find(function (item) {
            return item === e.target;
          });
          if (findOneInPage) {
            var findOneInModal = _toConsumableArray(that.shadowRoot.querySelectorAll(selector)).find(function (item) {
              return that.getImgSrc(item) === src;
            });
            if (findOneInModal) {
              if (!findOneInModal.classList.contains('active')) {
                findOneInModal.classList.add('active');
                findOneInModal.remove();
                that.shadowRoot.querySelector('.modal').appendChild(findOneInModal);
                return;
              } else {
                findOneInModal.remove();
                findOneInModal = null;
              }
            }
            // else
            if (!findOneInModal) {
              // originalEl.style.opacity = 0
              new ImgPreviewer(that.shadowRoot, e.target, src);
            }
          }
        });
      }
    }, {
      key: "getImgSrc",
      value: function getImgSrc(dom) {
        var _dom$dataset, _window$getComputedSt;
        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]);
      }
    }]);
    return ImgPreviwer;
  }();
  var ImgPreviewer = /*#__PURE__*/function () {
    function ImgPreviewer(shadowRoot, originalEl, src) {
      var _this = this;
      _classCallCheck(this, ImgPreviewer);
      _defineProperty(this, "state", {
        scale: 1,
        offset: {
          left: 0,
          top: 0
        },
        origin: 'center',
        initialData: {
          offset: {},
          origin: 'center',
          scale: 1
        },
        startPoint: {
          x: 0,
          y: 0
        },
        // 记录初始触摸点位
        isTouching: false,
        // 标记是否正在移动
        isMove: false,
        // 正在移动中,与点击做区别
        touches: new Map(),
        // 触摸点数组
        lastDistance: 0,
        lastScale: 1,
        // 记录下最后的缩放值
        scaleOrigin: {
          x: 0,
          y: 0
        }
      });
      /** @描述 双击事件 */
      _defineProperty(this, "ondblclick", function (e) {
        e.preventDefault();
        var that = _this;
        var state = that.state;
        setTimeout(function () {
          if (state.isMove) {
            state.isMove = false;
          } else {
            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")]);
            setTimeout(function () {
              state.maskContent.removeChild(state.cloneEl);
              // originalEl.style.opacity = 1
              state.cloneEl.removeEventListener('dblclick', that.ondblclick);
            }, 300);
          }
        }, 280);
      });
      /** @描述  指针按下事件*/
      _defineProperty(this, "onpointerdown", function (e) {
        e.preventDefault();
        var that = _this;
        var state = that.state;
        state.touches.set(e.pointerId, e);
        // TODO: 点击存入触摸点
        state.isTouching = true;
        state.startPoint = {
          x: e.clientX,
          y: e.clientY
        };
        if (state.touches.size === 2) {
          // TODO: 判断双指触摸,并立即记录初始数据
          state.lastDistance = that.getDistance();
          state.lastScale = state.scale;
        }
      });
      /** @描述 滚轮缩放 */
      _defineProperty(this, "onmousewheel", function (e) {
        e.preventDefault();
        if (!e.deltaY) return;
        var that = _this;
        var state = that.state;
        state.origin = "".concat(e.offsetX, "px ").concat(e.offsetY, "px");

        // 缩放执行
        if (e.deltaY < 0) {
          // 放大
          state.scale += 0.1;
        } else if (e.deltaY > 0) {
          state.scale >= 0.2 && (state.scale -= 0.1);
          // 缩小
        }

        if (state.scale < state.initialData.scale) {
          console.log("state.scale < state.initialData.scale => %O ", state.scale, state.initialData.scale);
          that.reduction();
        }
        state.offset = that.getOffsetPageCenter(e.offsetX, e.offsetY);
        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, ")")]);
      });
      /** @描述 松开指针 事件 */
      _defineProperty(this, "onpointerup", function (e) {
        e.preventDefault();
        var that = _this;
        var state = that.state;
        state.touches["delete"](e.pointerId);
        // TODO: 抬起移除触摸点
        if (state.touches.size <= 0) {
          state.isTouching = false;
        } else {
          var touchArr = Array.from(state.touches);
          // 更新点位
          state.startPoint = {
            x: touchArr[0][1].clientX,
            y: touchArr[0][1].clientY
          };
        }
        setTimeout(function () {
          state.isMove = false;
        }, 300);
      });
      /** @描述 指针移动事件 */
      _defineProperty(this, "onpointermove", function (e) {
        e.preventDefault();
        var that = _this;
        var state = that.state;
        if (state.isTouching) {
          state.isMove = true;
          if (state.touches.size < 2) {
            // 单指滑动
            state.offset = {
              left: state.offset.left + (e.clientX - state.startPoint.x),
              top: state.offset.top + (e.clientY - state.startPoint.y)
            };
            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)]);
            // 更新点位
            state.startPoint = {
              x: e.clientX,
              y: e.clientY
            };
          } else {
            // 双指缩放
            state.touches.set(e.pointerId, e);
            var ratio = that.getDistance() / state.lastDistance;
            state.scale = ratio * state.lastScale;
            state.offset = that.getOffsetPageCenter();
            if (state.scale < state.initialData.scale) {
              that.reduction();
            }
            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)]);
          }
        }
      });
      /** @描述 取消指针事件 */
      _defineProperty(this, "onpointercancel", function (e) {
        e.preventDefault();
        _this.state.touches.clear();
        // 可能存在特定事件导致中断,真机操作时 pointerup 在某些边界情况下不会生效,所以需要清空
      });
      this.state = Object.assign({}, this.state, this.mergeOptions(shadowRoot, originalEl, src));
      var cloneEl = this.appendImg(src, originalEl);
      this.state.cloneEl = cloneEl;
      this.fixPosition(cloneEl);
      this.addEvents(cloneEl);
      return cloneEl;
    }
    _createClass(ImgPreviewer, [{
      key: "mergeOptions",
      value: function mergeOptions(shadowRoot, originalEl, src) {
        var _window = window,
          winWidth = _window.innerWidth,
          winHeight = _window.innerHeight;
        var offsetWidth = originalEl.offsetWidth,
          offsetHeight = originalEl.offsetHeight;

        // Element.getBoundingClientRect() 方法返回元素的大小及其相对于【视口】的位置
        var _originalEl$getBoundi = originalEl.getBoundingClientRect(),
          top = _originalEl$getBoundi.top,
          left = _originalEl$getBoundi.left;
        return {
          shadowRoot: shadowRoot,
          originalEl: originalEl,
          src: src,
          winWidth: winWidth,
          winHeight: winHeight,
          offsetWidth: offsetWidth,
          offsetHeight: offsetHeight,
          top: top,
          left: left,
          maskContent: shadowRoot.querySelector('.modal')
        };
      }
      /** @描述 添加图片 */
    }, {
      key: "appendImg",
      value: function appendImg(src, originalEl) {
        // let cloneEl = document.createElement('img')
        // cloneEl.src = src
        // 克隆节点 能从缓存中获取图片,以便节省流量
        var cloneEl = originalEl.cloneNode();
        this.state.maskContent.appendChild(cloneEl);
        return cloneEl;
      }
      /** @描述 添加监听事件 */
    }, {
      key: "addEvents",
      value: function addEvents(cloneEl) {
        var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['dblclick', 'mousewheel', 'pointerdown', 'pointerup', 'pointermove', 'pointercancel'];
        var that = this;
        events.forEach(function (item) {
          if (item === 'mousewheel') {
            cloneEl.addEventListener('mousewheel', that["on".concat(item)], {
              passive: false
            });
            return;
          }
          cloneEl.addEventListener(item, that["on".concat(item)]);
        });
      }
    }, {
      key: "getOffsetPageCenter",
      value: /** @描述 获取中心改变的偏差 */
      function getOffsetPageCenter() {
        var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
        var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
        var state = this.state;
        var touchArr = Array.from(state.touches);
        if (touchArr.length === 2) {
          var start = touchArr[0][1];
          var end = touchArr[1][1];
          x = (start.offsetX + end.offsetX) / 2;
          y = (start.offsetY + end.offsetY) / 2;
        }
        state.origin = "".concat(x, "px ").concat(y, "px");
        var offsetLeft = (state.scale - 1) * (x - state.scaleOrigin.x) + state.offset.left;
        var offsetTop = (state.scale - 1) * (y - state.scaleOrigin.y) + state.offset.top;
        state.scaleOrigin = {
          x: x,
          y: y
        };
        return {
          left: offsetLeft,
          top: offsetTop
        };
      }

      /** @描述  获取距离*/
    }, {
      key: "getDistance",
      value: function getDistance() {
        var touchArr = Array.from(this.state.touches);
        if (touchArr.length < 2) {
          return 0;
        }
        var start = touchArr[0][1];
        var end = touchArr[1][1];
        return Math.hypot(end.x - start.x, end.y - start.y);
      }

      /** @描述  修改样式,减少回流重绘*/
    }, {
      key: "changeStyle",
      value: function changeStyle(el, arr) {
        var original = el.style.cssText.split(';');
        original.pop();
        el.style.cssText = original.concat(arr).join(';') + ';';
      }

      /** @描述 还原记录,用于边界处理 */
    }, {
      key: "reduction",
      value: function reduction() {
        var that = this;
        var state = that.state;
        that.timer && clearTimeout(that.timer);
        that.timer = setTimeout(function () {
          // offset = state.initialData.offset
          // origin = state.initialData.origin
          // scale = state.initialData.scale
          console.log("state => %O ", state);
          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)]);
        }, 300);
      }
    }, {
      key: "fixPosition",
      value: /** @描述 移动图片到屏幕中心位置 */
      function fixPosition(cloneEl) {
        var that = this;
        var state = that.state;

        /** @描述 原图片 中心点 */
        var originalCenterPoint = {
          x: state.offsetWidth / 2 + state.left,
          y: state.offsetHeight / 2 + state.top
        };

        /** @描述 页面 中心点 */
        var winCenterPoint = {
          x: state.winWidth / 2,
          y: state.winHeight / 2
        };

        /** @描述  新建图片的定位点:通过原图片中心点到页面中心点的 偏移量*/
        var offsetDistance = {
          left: winCenterPoint.x - originalCenterPoint.x + state.left,
          top: winCenterPoint.y - originalCenterPoint.y + state.top
        };

        /** @描述 放大后的 */
        var scaleNum = this.adaptScale();
        var diffs = {
          left: (scaleNum - 1) * state.offsetWidth / 2,
          top: (scaleNum - 1) * state.offsetHeight / 2
        };
        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)")]);

        /** @描述 消除偏差:让图片相对于window  0 0定位,通过translate设置中心点重合*/
        setTimeout(function () {
          that.changeStyle(cloneEl, ['transition: all 0s', "left: 0", "top: 0", "transform: translate(".concat(offsetDistance.left - diffs.left, "px, ").concat(offsetDistance.top - diffs.top, "px)")]);
          that.state.offset = {
            left: offsetDistance.left - diffs.left,
            top: offsetDistance.top - diffs.top
          };
          // 记录值
          that.record();
        }, 300);
      }
      /** @描述 记录初始化数据 */
    }, {
      key: "record",
      value: function record() {
        var state = this.state;
        state.initialData = Object.assign({}, {
          offset: state.offset,
          origin: state.origin,
          scale: state.scale
        });
      }
      /** @描述 计算自适应屏幕的缩放 */
    }, {
      key: "adaptScale",
      value: function adaptScale() {
        var _this$state = this.state,
          winWidth = _this$state.winWidth,
          winHeight = _this$state.winHeight,
          originalEl = _this$state.originalEl;
        var w = originalEl.offsetWidth,
          h = originalEl.offsetHeight;
        var scale = winWidth / w;
        if (h * scale > winHeight - 80) {
          scale = (winHeight - 80) / h;
        }
        return scale;
      }
    }]);
    return ImgPreviewer;
  }();
  var shadowRoot = new ImgPreviwer({
    backgroundColor: 'transparent'
  });
  addBackgroundImg();

  /** @描述  添加背景色*/
  function addBackgroundImg() {
    var bgImage = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDY0IDY0Ij4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLmNscy0xIHsKICAgICAgICBmaWxsOiAjMzAzMDMwOwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICMyMDIwMjA7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxyZWN0IGlkPSJsdCIgY2xhc3M9ImNscy0xIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiLz4KICA8cmVjdCBpZD0icmIiIGNsYXNzPSJjbHMtMSIgeD0iMzIiIHk9IjMyIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiLz4KICA8cmVjdCBpZD0ibGIiIGNsYXNzPSJjbHMtMiIgeT0iMzIiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIvPgogIDxyZWN0IGlkPSJydCIgY2xhc3M9ImNscy0yIiB4PSIzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIi8+Cjwvc3ZnPgo=";
    var ua = navigator.userAgent.toLowerCase();
    var doc = document.body || document.documentElement;
    var isQQBrowser = ua.indexOf('qqbrowser/') > -1;
    var isQQBrowserPS = function isQQBrowserPS() {
      return document && document.body && document.body.classList.contains('qb-picture-ps');
    };
    if (document.contentType.startsWith('image/')) {
      if (isQQBrowser && doc.tagName !== 'svg') {
        setTimeout(function () {
          loaded();
        }, 666);
      } else {
        loaded();
      }
    }
    return;
    function loaded() {
      var docTagName = function (tag) {
        var tagName = tag && tag.tagName.toLowerCase();
        if (tagName) {
          if (tagName == 'svg') {
            return tagName;
          }
          if (tagName == 'body' && tag.children && tag.children.length) {
            tagName = tag.children[0].tagName.toLowerCase();
            if (tagName == 'img') {
              return tagName;
            } else {
              tagName = document.querySelector('img');
              return tagName && tagName.tagName && tagName.tagName.toLowerCase();
            }
          }
        }
      }(doc);
      var isViewerMode = docTagName == 'svg' || docTagName == 'img';
      if (isViewerMode) {
        if (document.head) {
          var styleText = [];
          if (isQQBrowserPS()) {
            styleText.push("body{box-sizing: border-box;background-attachment: fixed !important;background-repeat: repeat !important;}");
            styleText.push("body{background: url(".concat(bgImage, ") !important;}"));
          } else {
            styleText.push("img{position: static !important;background: none !important;background-color: transparent !important;}");
          }
          $GM.createElement('style', {
            randomType: 'newOne',
            el: 'head',
            type: 'text/css',
            innerHTML: styleText.join('')
          }, win);
        }
        if (isQQBrowserPS()) {
          doc.style.position = 'static';
          doc.style.top = 'auto';
          doc.style.left = 'auto';
          doc.style.transform = 'none';
        } else {
          doc.style.backgroundImage = "url(".concat(bgImage, ")");
          doc.style.backgroundAttachment = 'fixed';
          doc.style.boxSizing = 'border-box';
          if (docTagName == 'svg') {
            doc.style.position = 'absolute';
            doc.style.top = '50%';
            doc.style.left = '50%';
            doc.style.transform = 'translate(-50%, -50%)';
            doc.style.margin = '10px';
            doc.style.width = 'auto';
            doc.style.height = 'auto';
            doc.style.maxWidth = '100%';
            doc.style.maxHeight = '100%';
          }
        }
      }
    }
  }
  function createFaviconElementInMyPageByIP() {
    if (location.hostname === '127.0.0.1') {
      $GM.createElement('link', {
        el: 'head',
        rel: 'shortcut icon',
        href: 'https://www.runoob.com/images/compatible_opera.gif',
        type: 'image/x-icon'
      });
    }
  }
  createFaviconElementInMyPageByIP();

  // 新页面打开链接  3、打开链接方式,总是以命名的新窗口 4、点击链接文本时,跳转相应链接 5、一键复制代码:鼠标悬浮代码,点击红色边框 6、csdn登录弹层移至左侧
  $GM.createElement('style', {
    el: 'head',
    id: 'a_click_target',
    randomType: 'newOne',
    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        "
  });
  /*
  .passport-login-container{
             display:none;
         }
         .toolbar-btn-loginfun{}
          */
  // 2、a链接方式,总是以命名方式在新窗口打开
  var createElementTip = $GM.createElementTipFn();
  window.addEventListener('click', function (e) {
    var _location$href, _dom$getAttribute, _dom$getAttribute$mat, _dom$getAttribute2, _dom$getAttribute2$re, _dom$getAttribute2$re2;
    // boss不支持操作
    if ((_location$href = location.href) !== null && _location$href !== void 0 && _location$href.includes('www.zhipin.com')) return;
    var dom = e.target;
    // 非锚点的a 打开链接方式,总是以命名的新窗口
    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, /^#/))) {
      var newTabWindosName = dom.innerText.replace(/\s/g, '').slice(0, 30);
      if (window.name === newTabWindosName) {
        newTabWindosName = newTabWindosName + 'extra';
      }
      dom.setAttribute('target', newTabWindosName);
    }
  }, {
    capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  });

  // 代码code时,复制代码内容
  window.addEventListener('click', function (e) {
    if ($GM.isContentEditableOfDOM()) return;
    var dom = e.target;
    var selectedText = window.getSelection().toString();
    if (dom.tagName === 'PRE' || dom.tagName === 'BLOCKQUOTE') {
      var _dom$querySelector;
      var willCopyText = selectedText || ((_dom$querySelector = dom.querySelector('code')) === null || _dom$querySelector === void 0 ? void 0 : _dom$querySelector.innerText) || dom.innerText;
      copyTextAndTip(e, willCopyText, selectedText);
    } else if (selectedText) {
      copyTextAndTip(e, '', selectedText);
    }
  }, {
    capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  });

  function copyTextAndTip(e, willCopyText, selectedText) {
    setTimeout(function () {
      createElementTip({
        e: e,
        content: selectedText ? '文字_复制成功' : '代码块_复制成功'
      });
      $GM.doCopy(willCopyText || selectedText);
    }, 500);
  }

  // 3、含有链接的文本,点击时跳转相应链接
  window.addEventListener('click', function (e) {
    var _innerTextsOfAllText$;
    if ($GM.isContentEditableOfDOM()) return;

    // 如果处于选中文字状态,则不进行跳转操作
    if (window.getSelection().toString()) return;
    var dom = e.target;
    if (!(e.button === 0 && dom.tagName !== 'A')) return;
    var innerTextsOfAllText = _toConsumableArray(dom.childNodes).reduce(function (pre, cur) {
      if (!(cur.nodeName === '#text' && cur.textContent)) return pre;
      return pre = "".concat(pre, " ").concat(cur.textContent);
    }, '');
    var url = innerTextsOfAllText === null || innerTextsOfAllText === void 0 || (_innerTextsOfAllText$ = innerTextsOfAllText.match) === null || _innerTextsOfAllText$ === void 0 ? void 0 : _innerTextsOfAllText$.call(innerTextsOfAllText, /https?:\/\/[\S]{4,}/);
    if (url) {
      window.open(url[0], url[0]);
    }
  }, {
    capture: true //利用捕获阶段,解决【阻止冒泡】阻断事件传播
  });
}
})();

/******/ })()
;