0

I'm not familiar with JavaScript.

I wrote an extension myself, but it didn't work.

The extended function is very simple, that is to activate the onselectstart parameter, because this parameter in the web page makes it impossible to select the text of the web page and then copy it. If I activate this parameter, I can select and copy.

I can execute this JavaScript command directly in the chrome console, and enable the onselectstart, works well:

document.body.onselectstart = function(){return true;}; 

but it will not take effect after put it into the extension.

My extension is very simple, just two files:

manifest.json:

{
  "manifest_version": 2,
  "name": "Copy unblocker",
  "version": "1.0",
  "description": "enable onselectstart",
  "icons": { "16": "images/logo.png" },  

  "permissions": [
    "activeTab"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["js/content_script.js"]
    }
  ]
}

content_ script.js:

document.body.onselectstart= function(){
  return true;
}

What's wrong, or can you give me an chrome extension script that can change the onselectstart parameter?

file trees

enter image description here

The web page is generated by JS. This parameter prevents me from selecting text

1 Answers1

1

Returning true won't help, this value doesn't do anything in DOM events. It worked in console because your listener simply replaced the listener of the page, but it doesn't work in content scripts as their JS code and objects are isolated form the page by design.

One solution is to add that code in a script element to the page as explained in this answer, but running code in the page context is not 100% safe due to a bug in both Chrome extensions and Firefox WebExtensions implementations (wrappedJSObject is also affected).

Here's a simpler solution: preventing the page from seeing the event.

// Specifying `true` to register a capturing phase listener
window.addEventListener('selectstart', e => e.stopPropagation(), true);

Some explanation. DOM events are dispatched in two phases: 1) the capturing phase where the event travels from window to document to <html> to <body> and down to the element that triggered the event, and 2) the bubbling phase where the event bubbles up from the target element all the way upwards through the DOM tree hierarchy to window.

The default phase for event listeners is "bubbling", so the easiest solution is to register your listener in the "capturing" phase where it will stop the event's "propagation" to prevent subsequent listeners from seeing the event. We did it on window, which is the first recipient in this phase, so our listener is the first one.

Some sites can circumvent it by using the same code and running it first, which can easily happen because content scripts run after DOMContentLoaded by default. To fight that you can declare your content script with "run_at": "document_start" so it runs before the page has run its scripts.

  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["js/content_script.js"],
    "run_at": "document_start"
  }]
}
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Yes, This solution solved my problem. In addition, the explanation is also great, although I still don't understand it very well. – stackoverflow26 Feb 22 '22 at 02:13