Kill drag,swipe gestures and enable selection of text

2/6/2025, 9:53:22 AM

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Kill drag,swipe gestures and enable selection of text
// @namespace   nostrum
// @match       https://epaper.bostonglobe.com/*
// @grant       GM_addStyle
// @version     1.0
// @author      Refael Ackermann<[email protected]>
// @description 2/6/2025, 9:53:22 AM
// @license MIT
// ==/UserScript==
'use strict';


GM_addStyle(`
  div {
    -webkit-user-select: text !important;
  }
`);


// The Argorithm is:
// 1. trap temporary value for window['Ext'] to capture 'blink' function
// 2. proxy window.Ext waiting for 'defaultSetupConfig'
// 3. kludge 'defaultSetupConfig.eventPublishers.touchGesture.recognizers'
// 4. replace proxy with actual target

// We need to act like a regular value and return undefined, until we are `set`
Object.defineProperty(unsafeWindow, "Ext", { configurable: true, set: extPropertySetter });

function extPropertySetter(tempExtValue) {
  // Just this one thing to handle; capturing definition of `blink`, then we disapear;
  Object.defineProperty(tempExtValue, "blink", { configurable: true, set: blinkPropertySetter });

  delete unsafeWindow.Ext;
  unsafeWindow.Ext = new Proxy(extKernel, { set: extProxySetter });;

  return true;
}

function blinkPropertySetter(blinkFunc) {
  extKernel.blink = blinkFunc;
}

const extKernel = new Object();

function extProxySetter(target, prop, value) {
  if (prop == 'defaultSetupConfig') {
    kludgeRecognizers(value.eventPublishers.touchGesture.recognizers)

    // We kludged what we wanted, so we go poof;
    delete unsafeWindow.Ext;
    unsafeWindow.Ext = extKernel;
  }
  target[prop] = value;
  return true;
}

function kludgeRecognizers(config) {
  const necessaryRecognizers = new Set(['doubleTap', 'tap']);
  for (const k in config) {
    if (!necessaryRecognizers.has(k))
      delete config[k];
  }
}