Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome manifest v3 webpack upgrade #20

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions js/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import Component from 'react-class';
import LangToggle from './LangToggle';
import { domain } from './const'

class Header extends Component {
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
Expand Down
3 changes: 1 addition & 2 deletions js/TextContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import Component from 'react-class';
import PropTypes from 'prop-types';
import TextTitle from './TextTitle';
import { domain } from './const';
import dataApi from './dataApi';


const SCROLL_DEBOUNCE_CONST = 20;
class TextContainer extends Component {
class TextContainer extends React.Component {
componentDidMount() {
const node = ReactDOM.findDOMNode(this);
this.currScrollY = 0;
Expand Down
76 changes: 19 additions & 57 deletions js/background.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
//based on https://developer.chrome.com/extensions/event_pages
//and https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/extensions/gmail/background.js
//Originally based on https://developer.chrome.com/extensions/event_pages, now migrated to https://developer.chrome.com/docs/extensions/develop/concepts/service-workers

import dataApi from './dataApi';

const oldChromeVersion = !chrome.runtime;
var requestTimerId;
const ALARM_MINUTES = 60;

function startRequest() {
const now = new Date();
//DEBUG dataApi.sendSlackMessage(`Starting request at ${now.toString()}`);
dataApi.init((data) => {
if (!!data.calendars) {
if (data.calendars) {
requestAllCalendars(data.calendars);
} else {
dataApi.getCalendars((data) => {
Expand All @@ -22,78 +17,45 @@ function startRequest() {
}

function requestAllCalendars(calendars) {
for (let c of calendars) {
dataApi.getCalendarTextRecursive([c], 0, {}, onGetCalendarText);
for (let calendar of calendars) {
dataApi.getCalendarTextRecursive([calendar], 0, {}, onGetCalendarText);
}
}

function onGetCalendarText(text, responseURL, initScrollPos, fromCache) {
const siteUrl = responseURL.map(tempURL=>dataApi.api2siteUrl(tempURL));
const siteUrls = responseURL.map(dataApi.api2siteUrl);
for (let i = 0; i < fromCache.length; i++) {
const tempFromCache = fromCache[i];
if (!tempFromCache) {
console.log("caching", siteUrl[i]);
dataApi.saveToLocal({[siteUrl[i]]: { text: text[i], responseURL: responseURL[i], }});
if (!fromCache[i]) {
dataApi.saveToLocal({ [siteUrls[i]]: { text: text[i], responseURL: responseURL[i] } });
}
}
}

function scheduleRequest() {
if (oldChromeVersion) {
if (requestTimerId) {
window.clearTimeout(requestTimerId);
}
requestTimerId = window.setTimeout(onAlarm, ALARM_MINUTES*60*1000);
} else {
console.log('Creating alarm');
// Use a repeating alarm so that it fires again if there was a problem
// setting the next alarm.
chrome.alarms.create('refresh', {periodInMinutes: ALARM_MINUTES});
}
chrome.alarms.create('refresh', { periodInMinutes: ALARM_MINUTES });
}

function onInit() {
scheduleRequest();
}
function onAlarm(alarm) {
console.log('Got alarm', alarm);
// |alarm| can be undefined because onAlarm also gets called from
// window.setTimeout on old chrome versions.
if (alarm && alarm.name == 'watchdog') {
onWatchdog();
} else {
if (alarm.name === 'refresh') {
startRequest();
} else if (alarm.name === 'watchdog') {
onWatchdog();
}
}

function onWatchdog() {
chrome.alarms.get('refresh', function(alarm) {
if (alarm) {
console.log('Refresh alarm exists. Yay.');
} else {
console.log('Refresh alarm doesn\'t exist!? ' +
'Refreshing now and rescheduling.');
chrome.alarms.get('refresh', (alarm) => {
if (!alarm) {
startRequest();
}
});
}

if (oldChromeVersion) {
onInit();
} else {
chrome.runtime.onInstalled.addListener(onInit);
chrome.alarms.onAlarm.addListener(onAlarm);
}
chrome.runtime.onInstalled.addListener(scheduleRequest);
chrome.alarms.onAlarm.addListener(onAlarm);

if (chrome.runtime && chrome.runtime.onStartup) {
console.log('Starting browser... updating icon.');
startRequest();
if (chrome.runtime.onStartup) {
chrome.runtime.onStartup.addListener(startRequest);
} else {
// This hack is needed because Chrome 22 does not persist browserAction icon
// state, and also doesn't expose onStartup. So the icon always starts out in
// wrong state. We don't actually use onStartup except as a clue that we're
// in a version of Chrome that has this problem.
chrome.windows.onCreated.addListener(function() {
console.log('Window created... updating icon.');
startRequest();
});
chrome.windows.onCreated.addListener(startRequest);
}
81 changes: 36 additions & 45 deletions js/dataApi.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
import { REDUX_ACTIONS, store, DEFAULT_STATE } from './ReduxStore';
import { domain } from './const'

const dataApi = {
DISABLE_CACHE: false,
init: (cb) => {
chrome.storage.local.get(['tab', 'lastCleared', 'cachedCalendarDay', 'calendars', 'language'] , data => {
chrome.storage.local.get(['tab', 'lastCleared', 'cachedCalendarDay', 'calendars', 'language'], data => {
const now = new Date();


if (!data.cachedCalendarDay && data.cached) {
dataApi.saveToLocal({cachedCalendarDay: (new Date()).toDateString()})
} else if (now.toDateString() !== data.cachedCalendarDay) {
if (!data.cachedCalendarDay) { // If there's no cached day recorded
dataApi.saveToLocal({cachedCalendarDay: now.toDateString()});
} else if (now.toDateString() !== data.cachedCalendarDay) { // If it's a new day
chrome.storage.local.remove('calendars');
data.calendars = null; // this datum is too old
dataApi.saveToLocal({cachedCalendarDay: now.toDateString()});
}

cb(data);
});

},
_currentRequest: null,
_currentRequestName: null,
Expand Down Expand Up @@ -85,7 +82,7 @@ const dataApi = {
//console.log(calendar, "NOT from cache");
const controller = new AbortController();
const signal = controller.signal;
var responseURL;
let responseURL;
fetch(url, {method: 'GET', signal})
.then(response => {
responseURL = response.url;
Expand All @@ -106,8 +103,7 @@ const dataApi = {
getRandomSource: cb => {
const controller = new AbortController();
const signal = controller.signal;
var responseURL;
var topic;
let responseURL, topic;
fetch(`${domain}/api/texts/random-by-topic`, {method: 'GET', signal})
.then(dataApi._handle_response)
.then(data => {
Expand Down Expand Up @@ -193,11 +189,11 @@ const dataApi = {
return n;
}

var values = dataApi.hebrewNumerals;
const values = dataApi.hebrewNumerals;

var heb = "";
let heb = "";
if (n >= 100) {
var hundreds = n - (n % 100);
let hundreds = n - (n % 100);
heb += values[hundreds];
n -= hundreds;
}
Expand All @@ -206,7 +202,7 @@ const dataApi = {
heb += values[n];
} else {
if (n >= 10) {
var tens = n - (n % 10);
let tens = n - (n % 10);
heb += values[tens];
n -= tens;
}
Expand All @@ -220,11 +216,10 @@ const dataApi = {

return heb;
},
encodeHebrewDaf: (daf, form) => {
encodeHebrewDaf: (daf, form = "short") => {
// Ruturns Hebrew daf strings from "32b"
var form = form || "short"
var n = parseInt(daf.slice(0,-1));
var a = daf.slice(-1);
let n = parseInt(daf.slice(0,-1));
let a = daf.slice(-1);
if (form === "short") {
a = {a: ".", b: ":"}[a];
return dataApi.encodeHebrewNumeral(n) + a;
Expand Down Expand Up @@ -302,34 +297,30 @@ const dataApi = {
1100: "\u05EA\u05EA\u05E9",
1200: "\u05EA\u05EA\u05EA"
},
saveToLocal: (obj, cb, _i=0) => {
if (_i > 5) {
console.error("Trying too many times to save", obj);
return;
}
chrome.storage.local.set(obj, dataApi._saveToLocalCB.bind(null, obj, cb, _i))
},
_saveToLocalCB: (obj, cb, _i) => {
if (chrome.runtime.lastError) {
dataApi.clearLocal(() => {
dataApi.saveToLocal(obj, cb, _i + 1);
});
} else {
if (cb) cb();
}
saveToLocal: async (obj, cb, _i = 0) => {
if (_i > 5) {
console.error("Trying too many times to save", obj);
return;
}
try {
await chrome.storage.local.set(obj);
if (cb) cb();
} catch (error) {
await dataApi.clearLocal();
await dataApi.saveToLocal(obj, cb, _i + 1);
}
},
clearLocal: () => {
// clear the main portion of local storage while retaining user preferences
const importantValues = {
"cachedCalendarDay": null,
"language": DEFAULT_STATE.language,
"tab": DEFAULT_STATE.tab,
};
chrome.storage.local.get(importantValues, data => {
chrome.storage.local.clear(() => {
chrome.storage.local.set(data);
});
});

clearLocal: async () => {
// clear the main portion of local storage while retaining user preferences
const importantValues = {
"cachedCalendarDay": null,
"language": DEFAULT_STATE.language,
"tab": DEFAULT_STATE.tab,
};
const data = await chrome.storage.local.get(importantValues);
await chrome.storage.local.clear();
await chrome.storage.local.set(data);
}
}

Expand Down
19 changes: 10 additions & 9 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
{
"manifest_version": 2,

"manifest_version": 3,
"name": "TorahTab by Sefaria",
"description": "Learn Torah daily!",
"version": "2.1.0",
"version": "3.0.0",
"chrome_url_overrides" : {
"newtab": "tab.html"
},
"icons": {
"192": "icons/icon192.png",
"192": "icons/icon192.png",
"144": "icons/icon144.png",
"128": "icons/icon128.png",
"96": "icons/icon96.png",
"72": "icons/icon72.png",
"48": "icons/icon48.png"
},
"browser_action": {
"action": {
"default_icon": {
"192": "icons/icon192.png",
"144": "icons/icon144.png",
Expand All @@ -27,12 +26,14 @@
"default_title": "TorahTab by Sefaria"
},
"background": {
"scripts": ["bundle/background-bundle.js"],
"persistent": false
"service_worker": "bundle/background-bundle.js",
"scripts": ["bundle/background-bundle.js"]
},
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
},
"content_security_policy": "script-src 'self' object-src 'self'",
"permissions": [
"storage",
"alarms"
]
}
}
Loading