0

I would like to save the DOM of <body> into a variable with:

var body = document.querySelector('body');

The Problem

If there is a browser extension that will manipulate the DOM, users could have different values.

Maybe a solution

I could save the <body> from source code instead of DOM in a variable. So all values would be the same. And if my JavaScript edits the DOM, I need a function that remembers what exactly has been added, removed or edited from the value of the source code and rewrite that variable. That would work but I think there must be a better and easier solution.

Is there a way to exclude all extensions (no matter what browser) when saving the DOM into a variable?

Reza Saadati
  • 5,018
  • 4
  • 27
  • 64
  • 1
    I'm not sure what u want to do, you want your variable is mutable or immutable ? – John Jun 14 '18 at 05:56
  • 3
    It look like you are stuck in a X/Y problem, you have a problem, and think the solution is to copy the DOM. What is the original problem? Why do you want to do such a unmaintanable thing? The original problem may be a lot easier to solve than this one. – DrakaSAN Jun 14 '18 at 10:27
  • 1
    You are about to develop a bad and unmaintainable solution to a problem that is unknown to us. Can you please provide some details on why you feel like you need to do this? – Nico Van Belle Jun 15 '18 at 08:20

2 Answers2

3

No, there is no way to "exclude all extensions". That is, to ensure that no one else writes in the DOM except you.

You can make an attempt at it. Basically, the DOM is "written" using techniques like innerHTML, appendChild, insertAdjacentHTML, etc.

You'd have to rewrite functions, implement getters and setters etc.

Implementing these changes for document.body is not enough, as each element has the ability to make such changes, so you'd have to follow the prototype chain where you'll see facts like appendChild being a member of Node and innerHTML a member of Element and make the changes there.

Rewriting the appendChild would be easy. For the sake of argument, I'll forbid the <p> tag anywhere in the body (rough example):

var old = Node.prototype.appendChild;
Node.prototype.appendChild = function (n){ 
  try { 
    if (n.tagName.toLowerCase() == "p"){ 
       return; 
    } 
  } catch(e) {
  }
  old.apply(this, [n]); 
}

As already stated, if we'd just rewrite the document.body.appendChild, anyone would be able to appendChild a <p> to a <div> or what not - so we have to go to the root of it.

And after taking care of all of these stuff, who's to say that no one else comes along and rewrites what you've just written?

And on top of it all, there are other ways to change these values, like man-in-the-middle "attacks", where user (or attacker) will modify whatever comes from the server (all scripts) through a Proxy, before those ever reaching the browser - and the browser will blindly obey.

Or the user can extend an opensource browser like Chromium and implement whatever rendering logic they want, etc.

Bottom line: you have no control over code that reaches the client, so don't rely on that.

Adelin
  • 7,809
  • 5
  • 37
  • 65
  • The example you give does not even *start* do to what the OP wants. Using your method works just fine for code that executes in the page's context itself. However, Chrome provides separate execution contexts for the extensions. Open in Chrome a page with your example, open the console, try stuff at the console. Yep, it works: can't append `p`. Then change the context to the context of an extension (that's the drop down menu which initially shows "top" and is located immediately right of the button for clearing the console). Try again. Oops, now you can insert `p` as much as you want. – Louis Jun 14 '18 at 11:04
  • @Louis - indeed - but that's not the point of my answer. I just answered OPs question: `Is there a way to exclude all extensions`: **no**. You can sense from OPs wording that they actually meant: "can I prevent someone from rewriting my DOM?" – Adelin Jun 14 '18 at 11:09
  • Your `appendChild` example is an unnecessary rhetorical detour. – Louis Jun 14 '18 at 11:21
  • @Louis - I show how the function can be rewritten but at the same time make the point that anybody else can come along and rewrite it as well. I don't see how the answer could be better without this point, and I don't think I should rewrite all functions and implement all needed setters and getters - that's not the point of the answer. That said, if you still think it's not ok - downvote and move on – Adelin Jun 14 '18 at 11:26
0

You don't need to save the DOM into a variable.

I would suggest you make this app and keep everything separate so you can plug anything you want any where you want.

step 1. Just create the html.

step 2. Store your user values somewhere. For example a database.

step 3. When the page loads, grab the users values and use JavaScript to manipulate the dom values.

Train
  • 3,420
  • 2
  • 29
  • 59