vycb / InvertImage

The addon for Firefox that inverts color of an image to black for night reading
3 stars 0 forks source link

invert selected images #3

Open milahu opened 5 years ago

milahu commented 5 years ago

i use firefox-darkreader to get white-on-black pages

images are not inverted, but sometimes i need some images inverted when text is encoded as image file

for example on this page https://www.dsprelated.com/freebooks/mdft/Logarithmic_Number_Systems_Audio.html

i want to select multiple images and invert all of them at once

vycb commented 5 years ago

there is a some sort of hack, multiple images can be inverted by selecting and inverting a parent element of the images on the page

milahu commented 5 years ago

not working on the sample page

when i right-click on a whole paragraph and run "invert images" then images are inverted, but also all the text is inverted

screenshot:

firefox plugin invert images request invert selection

i expect the "invert images" plugin to only invert images, not invert all html tags

or did i miss something?

vycb commented 5 years ago

yes, this is unique style on unique site. img1

For this purpose Stylus addon can be used. For example: after inverting a parent element on the page I turned on style written in Stylus

bookchapter {

color: #220; } img2

milahu commented 5 years ago

same effect with only stylus addon:

@-moz-document url-prefix("https://www.dsprelated.com/freebooks/mdft/") {
    div#bookchapter img {
        filter: invert(1);
        -webkit-filter: invert(1);
        background: #fff;
    }
}

but i still want a "point and click" solution ....

i did a quick edit of your code, to optimize for speed and readability, and to "only invert images"

code is not tested, feel free to use it = no warranty + public domain

// target node from "context menu" click
var clicked_node = null // not a dictionary

// css code to invert image
// we use the css comments /*[*/..../*]*/ for more uniqueness
// so we dont accidentaly replace any original css code
// at the cost of a slower s.indexOf(invert_style)
const invert_style = "/*[*/;filter:invert(1);/*]*/"

browser.runtime.onMessage.addListener(function(msg){
    if (msg.cmd !== "invert") return

    // css selectors for ancestor node
    // TODO sort by frequency, most frequent first
    // TODO maybe remove to avoid "magic numbers"
    const invert_ancestors = [
        ".media-image",
        "#AdaptiveMedia"
        ".css-1dbjc4n",
        ".rn-156q2ks",
        ".rn-16y2uox",
        ".rn-10m9thr",
        "._26ii _-_b",
        "._2a2q",
        "._2rea",
        "._5rgt",
        "._5dec",
        ".uiScaledImageContainer",
        ".tcu-imageWrapper",
        "._5rgu",
        "._3x-2",
    ]

    // search ancestor node
    var ancestor_node = null // not a list
    for(let s of invert_ancestors){
        ancestor_node = clicked_node.closest(s)
        if(ancestor_node){
            toggle_invert(ancestor_node)
            return
        }
    }

    // ancestor node was not found
    // invert images in clicked node
    for(let i of clicked_node.getElementsByTagName("img")){
        toggle_invert(i)
    }

    //// ancestor node was not found
    //// invert clicked node
    //toggle_invert(clicked_node)

})

function toggle_invert(e){
    var s = e.getAttribute("style")
    var i = -1
    if(!s){
        // set style
        s = invert_style
    }else{
        i = s.indexOf(invert_style)
        if(i == -1){
            // append style
            s = s + invert_style
        }else{
            // delete style
            // re-use the result of s.indexOf(invert_style)
            s = s.substr(0, i) + s.substr(i + invert_style.length)
        }
    }
    e.setAttribute("style", s)
}

addEventListener('contextmenu', function (e) {
    clicked_node = e.target
}, false)
vycb commented 5 years ago

Thanks for advice. This addon made for very general case in mind, to work with all type of web pages and elements. Even common case to invert video element or whole pdf document.