مۇنازىرىلەر » ئىجادىيەت

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

§
يوللانغان ۋاقتى: 2021-02-09
تەھرىرلەنگەن ۋاقتى: 2021-02-09

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
§
يوللانغان ۋاقتى: 2021-02-09
تەھرىرلەنگەن ۋاقتى: 2021-02-09

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.

§
يوللانغان ۋاقتى: 2021-02-09

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

§
يوللانغان ۋاقتى: 2021-02-09

@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.

§
يوللانغان ۋاقتى: 2021-02-10

@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
§
يوللانغان ۋاقتى: 2021-02-10

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

§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

@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
§
يوللانغان ۋاقتى: 2021-02-10

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);
§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

@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
§
يوللانغان ۋاقتى: 2021-02-10

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()
§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

@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.

§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

**
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
§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

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.

§
يوللانغان ۋاقتى: 2021-02-10
تەھرىرلەنگەن ۋاقتى: 2021-02-10

@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
§
يوللانغان ۋاقتى: 2021-02-10

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)

§
يوللانغان ۋاقتى: 2021-02-10

@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

جاۋاب قايتۇرۇش

جاۋاب قايتۇرۇش ئۈچۈن كىرىش.