Search code examples
javascriptcssgoogle-chrome-extension

Chrome Extension - Change styles.CSS var not working


Sorry, I messed that up. I did not update the manifest from the last post and I forgot the content.js, that is how the Change button was sending the value and the page was getting the new style attribute value from the one entered in the text field and then to the content.js, existing content.js file added below.


I have a styles.css that changes the web page and is loaded from the popup but want to change a variable in the styles.css from the data entered at the popup.

I've added a content.js file and I can now pass a value from the Popup and it adds a new style attribute to the page but it's not updating the --ptwidth in the styles.css file. I think I need to have it in the styles.css to give the correct location and add the !important option.

I tried to ask this question before an it was closed\linked to one about webpage DOMs and don't have the reputation to post a comment and not sure I should ask my questions there if I could:

How to access the webpage DOM rather than the extension page DOM?


The styles.css injection works using the Wider button and the --ptwidth var is passed the value given (310) in the styles.CSS, at the very least I'd like to be able to enter a new value in the textbox and then use the existing Wider button to load the updated styles.css but it would be nice to have it auto update and maybe even use the slider.

The change button moves the new value entered in the text field to the content.js file and it then adds the new style attribute but it's not working. The insertCSS on the Wider button works but the info it adds is different.

Content.js adds the Style attribute section and the insertCSS adds the :root section that works.

Added by Content.js No Work: enter image description here

Added by insertCSS Works and adds these two: enter image description hereenter image description here

Columns before: enter image description here

Columns after: enter image description here

Rule before using the working Wider button with insertCSS: enter image description here

Rules after the insertCSS injections of styles.css: insertCSS

Popup: enter image description here

manifest:

{
  "manifest_version": 3,
  "name": "Hellper",
  "description": "Extension",
  "version": "0.1",

  "icons": { "16": "logo_16_T.png",
             "48": "logo_48_T.png",
            "128": "logo_128_T.png" 
           },

  "action": {
    "default_icon": "logo_16_T.png",
    "default_popup":"popup.html"
            },

  "permissions": ["scripting", "tabs", "activeTab", "content.js"],
  "host_permissions": ["<all_urls>"],
  
  "content_scripts": [{
    "js": ["jquery-2.2.0.min.js", "popup.js"],
    "matches": ["https://www.google.com/*",
                "https://en.wikipedia.org/*",
                "https://stackoverflow.com/*"]
  }]
}

popup.html:

<!doctype html>
<html>
  <head>
    <title>Popup</title>
  </head>
  <body>
    <input id="button1" type=button value=clickme>
    <button class="format">Wider</button>
    <button class="reset">Reset</button>
        <script src="jquery-2.2.0.min.js"></script>
        <script src="popup.js"></script>
      <!--
        <h2>Background Color</h2>
      <input type="color" id="color-changer" />
      <h2>Rotate Page</h2>
      <input type="range" min="0" max="360" step="1" value="0" id="rotate" />
      -->
    <h1>New Width</h1>
    <p>
      <input type="text" id="newWidth" value="120"/>
      <input type="submit" id="btnChange" value="Change"/>
    </p>
  <div class="form-group">
    <lable for="slider">Project/Task Width</lable>
    <input type="range" min="0" max="999" step="1" value="160" id="slider" />
  </div>
  </body>
</html>

styles.css:

:root {
    --ptwidth: 310px
}

.quixote .qx-grid .editor_grid tbody tr td input, .quixote .qx-grid .editor_grid tbody tr td .input-group {
    /*max-width: 450px !important;
    min-width: 450px !important;*/
    max-width: var(--ptwidth) !important;
    min-width: var(--ptwidth) !important;

popup.js:

$(document).ready(function() {
    $('.reset').click(function() {
    chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
    var activeTab = tabs[0];
            chrome.scripting.removeCSS({
                target: { tabId: activeTab.id },
                files: ["styles.css"]
    });
   });
    })

    $('.format').click(function() {
    chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
    var activeTab = tabs[0];
            chrome.scripting.insertCSS({
                target: { tabId: activeTab.id, allFrames: true },
                files: ["styles.css"]
            });
    /*chrome.tabs.sendMessage(activeTab.id, {"buttonclicked": "wider"});*/
   });
    })
})

$(function(){
    var width = $('#newWidth').val();
    $('#newWidth').on("change paste keyup", function(){
      width = $(this).val();
    });
    $('#btnChange').click(function(){
      chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
        chrome.tabs.sendMessage(tabs[0].id, {todo: "changeWidth", sliderWidth: width})
      });
    });
});

content.js

let root = document.documentElement;

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      if( request.todo == "changeWidth"){
        var updateWidth = request.sliderWidth;
        root.style.setProperty('--ptwidth', updateWidth + "px");
//      start();
      }
    });

Solution

  • I got this working by using the chrome.scripting.insertCSS to replace the --ptwidth value after the styles.css has been injected. So far everything works with just the popup.js and no need for the content.js file.

    I use this to load the styles.css with it's default value.

    chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
      var activeTab = tabs[0];
        chrome.scripting.insertCSS({
          target: { tabId: activeTab.id, allFrames: true },
        files: ["styles.css"]
        });
    });
    

    Then this when I get a new value from the textbox or slider.

      chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
        var activeTab = tabs[0];
        //alert(readsavewidth);
        $("#slider").val(readsavewidth);
        $("#newWidth").val(readsavewidth);
      chrome.scripting.insertCSS({
        target: { tabId: activeTab.id, allFrames: true },
        css: `:root { --ptwidth: ${readsavewidth + "px"} }`
      });
      });
    });
    

    I also used the chrome.storage.local to set and get the last value used.

    $(function () {
      // text input listener
      $("#newWidth").on("change paste keyup", function () {
        width = $(this).val();
                //Save it to the localStorage variable which will always remember what you store in it
                chrome.storage.local.set({'savewidth': width});
        // update slider
        $("#slider").val(width);
          chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
            var activeTab = tabs[0];
          chrome.scripting.insertCSS({
            target: { tabId: activeTab.id, allFrames: true },
            css: `:root { --ptwidth: ${width + "px"} }`
          });
        });
      });
      // listener for slider changes
      $("#slider").on("input", function () {
        width = $("#slider").val();
        // update text box
        $("#newWidth").val(width);
            chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
                var activeTab = tabs[0];
            chrome.scripting.insertCSS({
                target: { tabId: activeTab.id, allFrames: true },
                css: `:root { --ptwidth: ${width + "px"} }`
            });
        });
    
        //Pull text from user inputbox
        var data = width;
        //Save it to the localStorage variable which will always remember what you store in it
          chrome.storage.local.set({'savewidth': data});
      });
    });
    

    Then I get the value when the popup opens and it then overights the --ptwidth value using the chrome.scripting.insertCSS funtion.

    chrome.storage.local.get('savewidth', function (result) {
      readsavewidth = result.savewidth;
    
      chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
        var activeTab = tabs[0];
        //alert(readsavewidth);
        $("#slider").val(readsavewidth);
        $("#newWidth").val(readsavewidth);
      chrome.scripting.insertCSS({
        target: { tabId: activeTab.id, allFrames: true },
        css: `:root { --ptwidth: ${readsavewidth + "px"} }`
      });
      });
    });