Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a chrome extension add a floating bar at the bottom of pages?

I am creating a chrome extension that needs to inject a floating element (i.e position:fixed) at the bottom of pages . My requirements are:

  • I need to access elements inside it from a content script.
    This is because I attach events to buttons so the user can perform actions on the current tab from the floating bar.
  • I want it's styles to remain as independent from styles of the current page.

So far I have tryed three solutions and came up with nothing.

  1. content script injecting a fixed html element.
    The problem with this solution is that the style of the page and the style of my element would effect each other thus resulting in web pages affecting the style of my element an vice versa.

  2. content script injecting an iframe.
    The problem here was it is impossible to access elements inside the iframe from the content script that created the iframe and on the other hand chrome extensions do not allow running content scripts inside a dynamically injected iframes (even when using all_frames: true).

  3. Extending the Devtool panel
    This did not fit my needs since I needed my panel to show on every page. e.g the user can preform an action that opens several tabs and have all of them have my element. in the devtool panel my user would then have to open devtoold in all tabs manually.

Please advise.

like image 885
mooli Avatar asked Dec 11 '22 18:12

mooli


1 Answers

Suggestions for 3 approaches

Content script injecting a fixed html element

Yes, the styles if specified are too generic in web pages

Ex:

div { 
   border:none;
} 

does effect content script(s) elements even you assign rare combination of id(s) and classes to css, Solution is to specify (or) override all styles using css which is very cumbersome

Ex: Over ride every style which is error prone and cumbersome.

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

Content script injecting an iframe.

I suggest this is best approach , regarding your concern on script injection on dynamic iframes; Yes it is possible to inject script to dynamic generated iframes

Sample Implementation

manifest.json

{
    "name": "Iframe",
    "description": "",
    "version": "1",
    "manifest_version": 2,
    "content_scripts": [
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "myscript.js"
            ],
            "run_at": "document_end"
        },
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "anotherscript.js"
            ],
            "all_frames": true
        }
    ],
    "permissions": [
        "<all_urls>"
    ]
}

myscript.js

var iframe = document.createElement("iframe");
iframe.setAttribute("src", "https://www.facebook.com/plugins/like.php?href=http://allofrgb.blogspot.in/");
iframe.setAttribute("style", "border:none; width:150px; height:30px");
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("frameborder", "0");
document.body.appendChild(iframe);

anotherscript.js

iframes = document.getElementsByTagName("iframe");
for (iframe in iframes){
    console.log(iframes[iframe].src);
}
console.log("In another Script");

If you observe console logged messages you observe messages are logged twice (document log + iframe log + [any number of optional iframes in pages]*)

anotherscript.js which runs during document idle states does execute in dynamic generated iframe, how ever you can re-run content script through chrome.tabs.executeScript() any time.

Extending the Devtool panel

You have clearly identified problems, so eliminating it as an alternative.

like image 113
Sudarshan Avatar answered Jan 16 '23 17:01

Sudarshan