0

I'm trying to make a Chrome extension that injects CSS at night.

The Browser Action works properly so that on clicking the extension, the CSS is properly injected. But I can't use chrome.tabs.insertCSS because content_scripts doesn't send in the activeTab.

manifest.json:

{
    "manifest_version": 2,

    "name": "Google Calendar Dark Mode",
    "short_name": "Dark Calendar",
    "description": "Google Calendar will enter dark mode.",
    "version": "2.0.0",

    "permissions": [
      "activeTab",
      "tabs",
      "geolocation",
      "https://calendar.google.com/*"
    ],

    "content_scripts": [{
      "js": ["foreground.js"],
      "matches": ["https://calendar.google.com/*"]
    }],

    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },

    "browser_action": {
      "default_title": "Google Dark"
    }
}

foreground.js:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    alert("sent from tab.id=", sender.tab.id);
});

navigator.geolocation.getCurrentPosition(wasSuccessful, notSuccessful);

alert("boop");

chrome.runtime.onMessage.addListener(function(tab) {
    // Note: this may take a second
    alert("Yo!");
    navigator.geolocation.getCurrentPosition(wasSuccessful, notSuccessful);
});

function wasSuccessful(position) {
    var theDate = new Date();
    var times = SunCalc.getTimes(new Date(), position.coords.latitude, position.coords.longitude);

    if ((theDate <= times.sunrise) || (times.sunset <= theDate)) {
        alert("It's night.");
        chrome.tabs.insertCSS({file: 'styles.css'});
    } else {
        alert("It's day.");
    };
}

function notSuccessful(err) {
    alert("Not Successful.");
}





/* ---------------------------------------------------------------------------
 * SunCalc
 *
 * SunCalc is a tiny BSD-licensed JavaScript library for calculating sun
 * position, sunlight phases (times for sunrise, sunset, dusk, etc.), moon
 * position and lunar phase for the given location and time, created by
 * Vladimir Agafonkin (http://agafonkin.com/en, https://github.com/mourner) as
 * a part of the [SunCalc.net project](http://suncalc.net).
 *
 * Most calculations are based on the formulas given on the site Astronomy
 * Answers and Wikipedia.
 * -------------------------------------------------------------------------*/
(function () { 'use strict';

 // shortcuts for easier to read formulas

 var PI   = Math.PI,
 sin  = Math.sin,
 cos  = Math.cos,
 tan  = Math.tan,
 asin = Math.asin,
 atan = Math.atan2,
 acos = Math.acos,
 rad  = PI / 180;

 // sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas


 // date/time constants and conversions

 var dayMs = 1000 * 60 * 60 * 24,
 J1970 = 2440588,
 J2000 = 2451545;

 function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
 function fromJulian(j)  { return new Date((j + 0.5 - J1970) * dayMs); }
 function toDays(date)   { return toJulian(date) - J2000; }


 // general calculations for position

 var e = rad * 23.4397; // obliquity of the Earth

 function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
 function declination(l, b)    { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }

 function azimuth(H, phi, dec)  { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
 function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }

 function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }

 function astroRefraction(h) {
     if (h < 0) // the following formula works for positive altitudes only.
     h = 0; // if h = -0.08901179 a div/0 would occur.

     // formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
     // 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
     return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
 }

 // general sun calculations

 function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }

 function eclipticLongitude(M) {

     var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
     P = rad * 102.9372; // perihelion of the Earth

     return M + C + P + PI;
 }

 function sunCoords(d) {

     var M = solarMeanAnomaly(d),
     L = eclipticLongitude(M);

     return {
         dec: declination(L, 0),
         ra: rightAscension(L, 0)
     };
 }


 var SunCalc = {};


 // sun times configuration (angle, morning name, evening name)

 var times = SunCalc.times = [
     [-0.833, 'sunrise',       'sunset'      ],
     [  -0.3, 'sunriseEnd',    'sunsetStart' ],
     [    -6, 'dawn',          'dusk'        ],
     [   -12, 'nauticalDawn',  'nauticalDusk'],
     [   -18, 'nightEnd',      'night'       ],
     [     6, 'goldenHourEnd', 'goldenHour'  ]
 ];


 // calculations for sun times

 var J0 = 0.0009;

 function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }

 function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
 function solarTransitJ(ds, M, L)  { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }

 function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }

 // returns set time for the given sun altitude
 function getSetJ(h, lw, phi, dec, n, M, L) {

     var w = hourAngle(h, phi, dec),
     a = approxTransit(w, lw, n);
     return solarTransitJ(a, M, L);
 }


 // calculates sun times for a given date and latitude/longitude

 SunCalc.getTimes = function (date, lat, lng) {

     var lw = rad * -lng,
     phi = rad * lat,

     d = toDays(date),
     n = julianCycle(d, lw),
     ds = approxTransit(0, lw, n),

     M = solarMeanAnomaly(ds),
     L = eclipticLongitude(M),
     dec = declination(L, 0),

     Jnoon = solarTransitJ(ds, M, L),

     i, len, time, Jset, Jrise;


     var result = {
         solarNoon: fromJulian(Jnoon),
         nadir: fromJulian(Jnoon - 0.5)
     };

     for (i = 0, len = times.length; i < len; i += 1) {
         time = times[i];

         Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);
         Jrise = Jnoon - (Jset - Jnoon);

         result[time[1]] = fromJulian(Jrise);
         result[time[2]] = fromJulian(Jset);
     }

     return result;
 };
 // export as Node module / AMD module / browser variable
 if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
 else if (typeof define === 'function' && define.amd) define(SunCalc);
 else window.SunCalc = SunCalc;

}());

I've tried to use the solutions to these questions:

But, I'm new to this and I wasn't able to get anything to work

Any help would be greatly appreciated.

Thanks!

Sam
  • 67
  • 8
  • Content scripts can't use chrome.tabs API. The background script can do it. – wOxxOm Jan 25 '19 at 07:17
  • @wOxxOm Is there a alternative way to inject CSS into the page then? Or is there a way to trigger background.js whenever the current page is "https://calendar.google.com/*" (I was only able to get it to trigger with the "Browser Action"? – Sam Jan 25 '19 at 07:24
  • You can insert a `style` DOM element into the web page. Or you can send message to the background script so that it does the injection. Or maybe you can do everything in the background script if navigator.geolocation supports that. To detect the URL you can use chrome.webNavigation.onCompleted with URL filters in the second parameter ([example](https://stackoverflow.com/a/53885209)). – wOxxOm Jan 25 '19 at 07:31

0 Answers0