Greasy Fork is available in English.

Discussions » Development

How do I prevent CSS interference in an injected js element?

§
Posted: 09.02.2021.
Edited: 09.02.2021.

My script Search/copy menu works fine on most websites when any text is selected
https://greasyfork.org/en/scripts/419825-opera-browser-rocker-mouse-gestures-search-highlight

But sometimes some websites like this one
https://www.epicdope.com/how-to-watch-free-easy-watch-order-guide/

Style the whole elements.
How can I make sure that the page css won't change my script css?

woxxomMod
§
Posted: 09.02.2021.
Edited: 09.02.2021.

Either use ShadowDOM (look for tutorials on style isolation via ShadowDOM) or add explicit style attribute on your added elements that specify the basic parameters like color, background, margins, padding - all with !important priority.

§
Posted: 09.02.2021.

Do you mean that your script menu styles was changed by a website css styles? You can use an iframe for your script menu. Some styles still could be overrided though, but less likely

§
Posted: 09.02.2021.

@wOxxOm
Thanks. I will search for that.

@Konf

Yes that's what I mean. Interesting idea, I may also try your idea.

I'm adding the menu styles of my script to the page using insertadjacenthtml, when I searched on google someone said that using append would stop sites from changing my script menu style.

§
Posted: 10.02.2021.

@wOxxOm

I've tried what you said, but anything I tried with the code below just makes the whole website white.

https://www.epicdope.com/how-to-watch-free-easy-watch-order-guide/

var Element = document.createElement('a');
Element.innerHTML = 'Whatever';

document.body.attachShadow({ mode: 'open' }).append(Element);

woxxomMod
§
Posted: 10.02.2021.

That's because you need to attach the shadow to a separate div, then document.body.appendChild(div).

§
Posted: 10.02.2021.
Edited: 10.02.2021.

@wOxxOm

I tried changing
var Element = document.createElement('a');
to
var Element = document.createElement('div');
But this makes the same result

The codes below works, but the element css are still being changed.
*The menu should be "search | copy" side by side, not one above the other.

let shadowRoot = document.createElement('div').attachShadow({ mode: 'open' });

shadowRoot.innerHTML = https://pastebin.com/bBpEyAQ6

document.body.appendChild(shadowRoot);

woxxomMod
§
Posted: 10.02.2021.

You're inventing something instead of using code from a tutorial which is why it doesn't work.

const el = document.createElement('div');
const root = el.attachShadow({ mode: 'open' });
root.innerHTML = '<div>foo</div>';
document.body.appendChild(el);
§
Posted: 10.02.2021.
Edited: 10.02.2021.

@wOxxOm

By looking and testing your code I was finally able to understand it, thanks!
I was able to manage it to work, but the problem is that my script relies on jquery to display the menu on the correct page position, and for some reason the jquery commands aren't working with the selected shadown element.

https://pastebin.com/ePBZg88d After the shadown element is appended I get some errors like
$("#highlight_menu_div")[0].shadowRoot.querySelector("#highlight_menu").height()
$("#highlight_menu_div")[0].shadowRoot.querySelector("#highlight_menu").width()
$("#highlight_menu_div")[0].shadowRoot.querySelector("#highlight_menu").css()

"are not a function"

Is there an easy way to fix this, or would I need to rewrite this function from 0?

woxxomMod
§
Posted: 10.02.2021.

querySelector returns a standard DOM element, not a jQuery object so to use height() and other jQuery methods you should wrap the result like this:

$("#highlight_menu", $("#highlight_menu_div")[0].shadowRoot).height()
§
Posted: 10.02.2021.
Edited: 10.02.2021.

@wOxxOm

That makes sense. Everything is working fine now, but the previous style that I appended to the page
.highlight_menu_animate .popuptext::after {
content: ""; height: 35px !important; top: 100%; left: 50%; margin-left: -10px !important; border-width: 10px !important; position: absolute; border-style: solid; border-color: #292929 transparent transparent transparent;
}

Isn't working now.

§
Posted: 10.02.2021.
Edited: 10.02.2021.

**
I've fixed that by doing this
https://pastebin.com/UntLAk8P

But I'm not sure if what I did is "wrong" or if there's a better method of doing this.

woxxomMod
§
Posted: 10.02.2021.
Edited: 10.02.2021.

That's because you need to add the style inside the ShadowDOM. It should have been explained in tutorials. Style isolation was the entire point of my suggestion to use ShadowDOM.

§
Posted: 10.02.2021.
Edited: 10.02.2021.

@wOxxOm

Got it, so there's no better method of doing this...

Btw do you know why the advent listener of mouseup isn't being added to text areas?
This is making the script not show the menu when a text is selected on this reply box for example

woxxomMod
§
Posted: 10.02.2021.

If the textarea is inside ShadowDOM then you need to listen to events inside this shadow root e.g. something like $('#highlight_menu', root).on('mouseup', yourFunction)

§
Posted: 10.02.2021.

@wOxxOm

This greasyfork reply text area isn't inside ShadowDOM, even though the script doesn't add the mouseup advent listener to the textbox, only to the document.body.

And I also had that same problem with all previous versions (12 and less) of my script

Post reply

Sign in to post a reply.