Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run javascript in an "isolated world" (chrome)

The chrome extension I developed injects Polymer and other web components into the host page via HTML imports as opposed to the typical method which is to use content scripts - which automatically run in an isolated world.

The reason behind this has to do with two things:

  1. Chrome extensions cannot register custom elements from content scripts
  2. The chrome extension manifest does not support HTML imports running in an isolated environment, only javascript

Due to these limitations, I had to resort to loading my components into the host page's <head> as described here.

The obvious problem I am facing is having my javascript come in conflict with the host page's javascript [on certain sites] since the method I am using to inject my dependencies does not run in an "isolated world".

So far I have resolved most of these issues by having a gulp task rename Polymer & my components to avoid conflicts but, unfortunately it is not perfect and a more robust approach is needed.

Finally to my question: Is it possible to create an "isolated world" for my javascript? Perhaps another document object? If not, are there any strategies I can employ to ensure my code run in isolation?

Update:

A few of you suggested using IIFE which is what I have been using thus far. I am looking for an answer along the lines of an isolated world, similar to how google chrome runs extensions under. This is mainly because Polymer must be attached to the global window object.

like image 229
dipole_moment Avatar asked Mar 21 '16 16:03

dipole_moment


2 Answers

You can scope variables (which includes functions since they are first class objects in javascript) with a closure.

So if you inject the following code with IIFE - immediately invoked function expression -

var someVar = 'this one "conflicts" with page js';
(function(){
    var someVar = 'this one does not "conflict" with page js'; //shadows someVar above
    console.log(someVar);
})();
console.log(someVar);

you'll see that accessing someVar returns different values.

As part of your injected code you can shadow "conflicting" variables that way - like Polymer.

Import a desired version inside an IIFE with something like CommonJS require() and continue accessing anything else from parent scope.

like image 170
Oleg Avatar answered Sep 20 '22 17:09

Oleg


For the sake of definition:

Isolated Scopes

Are widely known as IIFE's which is a design pattern for javascript "closures".

Isolated World

Or "Isolated Worlds" for that matter are as described by dipole, the author of the question, javascript applications that run on the same environment but do not know about each other.

Possible Answer

This questions my have been answered here already.

My suggestion

While "Isolated World" is not a "thing" in javascript, or at least it wasn't until recently, and in the spirit of providing a possible solution take a look at Dynamic Script Loading.

You will still have a conflict if you do not dynamically load your scripts into an "isolated scope" and use your functions within that scope.

like image 32
Wilmer SH Avatar answered Sep 20 '22 17:09

Wilmer SH