aclave1
aclave1

Reputation: 1711

Chrome extension content scripts custom ui

I'm in the process of writing a chrome extension which displays some custom UI in multiple web pages via script injection. The script which I am injecting into the page appends some Dom items onto the document's body which can be interacted with by the user. The problem is, the items' styles are being affected by the page's css. I have solved this for the most part by applying css to each item as it's inserted into the dom.

$('item').css({....});

The problem with this is, I end up with huge blocks of styling that look like this:

$('.item').css({
            '-webkit-box-sizing' : 'border-box',
            'box-sizing' : 'border-box',
            'resize' : 'both',
            'overflow' : 'hidden',
            'position' : 'absolute',
            'padding-top' : '.2em',
            'padding-right' : '.2em',
            'padding-left' : '.2em',
            'padding-bottom' : '.4em',
            'opacity' : '.8',
            'background' : 'rgba(0,0,0,.5)',
            'background-image' : '-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#111111))',
            'background-image' : '-webkit-linear-gradient(#444444, #111111)',
            'background-image' : 'linear-gradient(#444444, #111111)',
            'border-radius' : '4px',
            'box-shadow' : '3px 2px 4px 1px #111111',
        });
        this.$el.children(".default").css({
            'font-size':'medium',
            '-webkit-box-sizing' : 'border-box',
            'box-sizing' : 'border-box',
            'resize' : 'none',
            'overflow' : 'auto',
            'display' : 'inherit',
            'position' : 'relative',
            'padding' : '.25em',
            'width' : '100%',
            'height' : '90%',
            'background' : '#efefef',
            'border-radius' : '2px',
        });

This whole method is going to become a problem because:

Is there a better way to display these dom elements, inject these scripts, and style them? I would like as little clash with the parent page as possible. An idea that I came up with was covering the entire page in a transparent iframe and injecting everything into that, but I don't believe the items would display since the iframe would be transparent.

Upvotes: 3

Views: 5023

Answers (1)

gkalpak
gkalpak

Reputation: 48211

First of all, as far as your consideration about interfering with the webpage's JS context is concerned, there is nothing to worry about since content scripts live in an isolated world:

Isolated worlds allow each content script to make changes to its JavaScript environment without worrying about conflicting with the page or with other content scripts. For example, a content script could include JQuery v1 and the page could include JQuery v2, and they wouldn't conflict with each other.

Another important benefit of isolated worlds is that they completely separate the JavaScript on the page from the JavaScript in extensions. This allows us to offer extra functionality to content scripts that should not be accessible from web pages without worrying about web pages accessing it.

Now, regarding the styling "interference" it is an actual problem, which I can think of 3 solutions for:

  1. Use inline element styling (i.e. what youhave been doing so far) and: a. Try to define as many properties as you can or at least the ones you really care about (and make sense for the underlying HTML). b. Accept the fact that there will be a slight chance of your elements getting affected by the wdbpages CSS.

  2. Use iframe's to embed each element. This is more "safe", but, if styling to the last detail isn't so important, this method would introduce unnecessary overhead.

  3. There is the (probably "proper"), high-end method of utilizing the Shadow DOM. (Take a look at this tutorial as well.)

Upvotes: 4

Related Questions