commit
d7bbe06161
5
VERSIONS.md
Normal file
5
VERSIONS.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# v0.6
|
||||
## v0.6.1
|
||||
* Replaced internal arrays with sets to prevent accidentally doubly caching values
|
||||
* Perform startup initialization for switches (should now default to ON)
|
||||
* Fixed error appearing right after installing extension
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "FuriKani",
|
||||
"description": "Removes furigana on websites based on your WaniKani level",
|
||||
"version": "0.6",
|
||||
"version": "0.6.1",
|
||||
"icons": {
|
||||
"16": "res/icon16.png",
|
||||
"48": "res/icon48.png",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<body>
|
||||
<header>
|
||||
<h1>FuriKani</h1>
|
||||
<h2>v0.6</h2>
|
||||
<h2>v0.6.1</h2>
|
||||
</header>
|
||||
|
||||
<div id="token-area">
|
||||
|
|
|
@ -1,8 +1,22 @@
|
|||
chrome.storage.local.get("token", (data) => {
|
||||
if(data.token !== undefined)
|
||||
return
|
||||
|
||||
chrome.storage.local.set({
|
||||
"enabled": true,
|
||||
"enabledVocab": true,
|
||||
"enabledKanji": true
|
||||
})
|
||||
})
|
||||
|
||||
// Query a WaniKani API endpoint with the given token
|
||||
const query = (token, url) =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
// Create header with the authorization token
|
||||
const requestHeaders = new Headers()
|
||||
requestHeaders.append("Authorization", "Bearer " + token)
|
||||
|
||||
// Construct request
|
||||
const endpoint = new Request(
|
||||
url,
|
||||
{
|
||||
|
@ -11,6 +25,8 @@ const query = (token, url) =>
|
|||
}
|
||||
)
|
||||
|
||||
// Fetch the response. If it returns HTTP 200, resolve the promise,
|
||||
// otherwise reject it
|
||||
var result = await fetch(endpoint)
|
||||
if(!result.ok)
|
||||
{
|
||||
|
@ -21,6 +37,7 @@ const query = (token, url) =>
|
|||
return resolve(result.json())
|
||||
})
|
||||
|
||||
// Update the local cache with new data
|
||||
const updateCache = async (token, oldLevel, newLevel) => {
|
||||
// If oldLevel is undefined, then a sync has never been performed (first time user)
|
||||
if(oldLevel === undefined)
|
||||
|
@ -39,9 +56,24 @@ const updateCache = async (token, oldLevel, newLevel) => {
|
|||
// Turn the array of levels into a comma separated list
|
||||
var levelURLString = levelArray.join(",")
|
||||
|
||||
// API endpoint + response data buffers
|
||||
// Data buffers
|
||||
var vocabulary = new Set();
|
||||
var kanji = new Set();
|
||||
|
||||
// If the old level is less than the new level add the old data to the new data
|
||||
if(oldLevel < newLevel)
|
||||
{
|
||||
await chrome.storage.local.get(["vocabulary", "kanji"], (data) => {
|
||||
if(data.vocabulary !== undefined && data.kanji !== undefined)
|
||||
{
|
||||
data.vocabulary.forEach(vocabulary.add, vocabulary)
|
||||
data.kanji.forEach(kanji.add, kanji)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// API endpoint
|
||||
var url = "https://api.wanikani.com/v2/subjects?types=vocabulary&levels=" + levelURLString
|
||||
var vocabulary = []
|
||||
|
||||
// WaniKani only sends 1000 elements in one response and then provides us with a link to the
|
||||
// next "page" of the data. We need to loop until the next page is null
|
||||
|
@ -53,14 +85,14 @@ const updateCache = async (token, oldLevel, newLevel) => {
|
|||
break
|
||||
|
||||
for(let i in response.data)
|
||||
vocabulary.push(response.data[i].data.characters)
|
||||
vocabulary.add(response.data[i].data.characters)
|
||||
|
||||
url = response.pages.next_url
|
||||
} while(url !== null)
|
||||
|
||||
// Extract Kanji as well
|
||||
var url = "https://api.wanikani.com/v2/subjects?types=kanji&levels=" + levelURLString
|
||||
var kanji = []
|
||||
var kanji = new Set()
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -69,24 +101,15 @@ const updateCache = async (token, oldLevel, newLevel) => {
|
|||
break
|
||||
|
||||
for(let i in response.data)
|
||||
kanji.push(response.data[i].data.characters)
|
||||
kanji.add(response.data[i].data.characters)
|
||||
|
||||
url = response.pages.next_url
|
||||
} while(url !== null)
|
||||
|
||||
// If the old level is less than the new level add the old data to the new data
|
||||
if(oldLevel < newLevel)
|
||||
{
|
||||
await chrome.storage.local.get(["vocabulary", "kanji"], (data) => {
|
||||
vocabulary.concat(data.vocabulary)
|
||||
kanji.concat(data.kanji)
|
||||
})
|
||||
}
|
||||
|
||||
// Cache the data
|
||||
chrome.storage.local.set({
|
||||
"vocabulary": vocabulary,
|
||||
"kanji": kanji,
|
||||
"vocabulary": [...vocabulary],
|
||||
"kanji": [...kanji],
|
||||
"level": newLevel
|
||||
})
|
||||
}
|
||||
|
@ -142,4 +165,4 @@ chrome.runtime.onMessage.addListener((data, sender, sendResponse) => {
|
|||
})
|
||||
|
||||
// At browser start, sync with wanikani
|
||||
sync().then(value => console.log(value)).catch(reason => console.error(reason))
|
||||
sync().then(value => console.log(value)).catch(reason => {})
|
|
@ -1,15 +1,18 @@
|
|||
// Vocab Furigana CSS
|
||||
var vocabStyle = `
|
||||
.furikani-vocabulary {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
// Kanji Furigana CSS
|
||||
var kanjiStyle = `
|
||||
.furikani-kanji {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
// Create stylesheet elements on the website for the classes
|
||||
var vocabStyleSheet = document.createElement("style")
|
||||
var kanjiStyleSheet = document.createElement("style")
|
||||
|
||||
|
@ -23,6 +26,7 @@ chrome.storage.local.get(["vocabulary", "kanji", "validUserLevel", "enabled", "e
|
|||
if(!data.validUserLevel)
|
||||
return
|
||||
|
||||
// If global setting is enabled, set the stylesheets depending on the other settings
|
||||
if(data.enabled)
|
||||
{
|
||||
if(data.enabledVocab)
|
||||
|
@ -45,7 +49,7 @@ chrome.storage.local.get(["vocabulary", "kanji", "validUserLevel", "enabled", "e
|
|||
var ruby = document.createElement("ruby")
|
||||
ruby.innerHTML = rubyTags.item(tag).innerHTML
|
||||
|
||||
// Remove all tags (except for <rb>)
|
||||
// Remove all tags (except for <rb>, <span>)
|
||||
while(ruby.lastElementChild)
|
||||
{
|
||||
if(ruby.lastElementChild.tagName.toLowerCase() === "rb" ||
|
||||
|
@ -58,7 +62,8 @@ chrome.storage.local.get(["vocabulary", "kanji", "validUserLevel", "enabled", "e
|
|||
ruby.removeChild(ruby.lastElementChild)
|
||||
}
|
||||
|
||||
// If the contents of the <ruby> tag are in the word list, remove the <rt> tag
|
||||
// If the contents of the <ruby> tag are in the word list, tag the <rt> tag
|
||||
// with the correct class
|
||||
var rtTag = rubyTags.item(tag).getElementsByTagName("rt").item(0)
|
||||
if(vocabulary.includes(ruby.innerText))
|
||||
rtTag.classList.add("furikani-vocabulary")
|
||||
|
@ -68,11 +73,12 @@ chrome.storage.local.get(["vocabulary", "kanji", "validUserLevel", "enabled", "e
|
|||
})
|
||||
|
||||
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
// One of the switches was checked/unchecked
|
||||
if(msg.action === "settingsUpdated")
|
||||
{
|
||||
// Retrieve current switch states
|
||||
chrome.storage.local.get(["enabled", "enabledVocab", "enabledKanji"], (data) => {
|
||||
console.log(data)
|
||||
|
||||
// If everything is disabled, disable all stylsheets
|
||||
if(!data.enabled)
|
||||
{
|
||||
vocabStyleSheet.innerHTML = ""
|
||||
|
@ -81,6 +87,7 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
|||
return
|
||||
}
|
||||
|
||||
// Otherwise set the kanji and vocab stylesheets depending on their settings
|
||||
vocabStyleSheet.innerHTML = data.enabledVocab ? vocabStyle : ""
|
||||
kanjiStyleSheet.innerHTML = data.enabledKanji ? kanjiStyle : ""
|
||||
|
||||
|
|
39
src/popup.js
39
src/popup.js
|
@ -9,21 +9,25 @@ const kanjiSetting = document.getElementById("setting-kanji")
|
|||
|
||||
// Set popup content
|
||||
chrome.storage.local.get(["level", "token", "enabled", "enabledVocab", "enabledKanji"], (data) => {
|
||||
// If no token is set, display exlamation mark and checkmark button
|
||||
if(data.token === undefined)
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2757)
|
||||
submitButton.innerHTML = String.fromCodePoint(0x2705)
|
||||
submitButton.classList.add("no-token")
|
||||
}
|
||||
else
|
||||
else // else display checkmark and reload button
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2705)
|
||||
submitButton.innerHTML = String.fromCodePoint(0x1F501)
|
||||
}
|
||||
|
||||
// Display the users current WaniKani level
|
||||
const levelSpan = document.getElementById("level")
|
||||
levelSpan.innerHTML = data.level
|
||||
|
||||
// If the input field contains text that is not the current token, turn the
|
||||
// button into a checkmark (else turn it into a repeat button)
|
||||
inputField.addEventListener("input", () => {
|
||||
if(inputField.value !== "" && inputField.value !== data.token)
|
||||
{
|
||||
|
@ -37,13 +41,15 @@ chrome.storage.local.get(["level", "token", "enabled", "enabledVocab", "enabledK
|
|||
}
|
||||
})
|
||||
|
||||
// Set the switches to thecached values
|
||||
globalSetting.checked = data.enabled
|
||||
vocabSetting.checked = data.enabledVocab
|
||||
kanjiSetting.checked = data.enabledKanji
|
||||
})
|
||||
|
||||
// Set the wanikani token
|
||||
// Submit button pressed
|
||||
submitButton.addEventListener( "click", () => {
|
||||
// If the submit field has a new token, replace the current one with it
|
||||
if(submitButton.classList.contains("new-token"))
|
||||
{
|
||||
chrome.storage.local.set({"token": inputField.value})
|
||||
|
@ -56,24 +62,27 @@ submitButton.addEventListener( "click", () => {
|
|||
|
||||
statusField.innerHTML = String.fromCodePoint(0x23F1)
|
||||
|
||||
// Sync with wanikani
|
||||
chrome.runtime.sendMessage("", {type: "sync"}, response => {
|
||||
if(response.success)
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2705)
|
||||
errorField.innerHTML = ""
|
||||
}
|
||||
else
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2757)
|
||||
errorField.innerHTML = response.error
|
||||
}
|
||||
})
|
||||
if(response.success)
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2705)
|
||||
errorField.innerHTML = ""
|
||||
}
|
||||
else
|
||||
{
|
||||
statusField.innerHTML = String.fromCodePoint(0x2757)
|
||||
errorField.innerHTML = response.error
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Set settings event listeners
|
||||
globalSetting.addEventListener("change", () => {
|
||||
chrome.storage.local.set({"enabled": globalSetting.checked})
|
||||
|
||||
// If the global settings are unchecked, uncheck the other options as well
|
||||
// and disable them
|
||||
if(!globalSetting.checked)
|
||||
{
|
||||
vocabSetting.checked = false
|
||||
|
@ -82,7 +91,8 @@ globalSetting.addEventListener("change", () => {
|
|||
vocabSetting.setAttribute("disabled", true)
|
||||
kanjiSetting.setAttribute("disabled", true)
|
||||
}
|
||||
else
|
||||
// Else restore the values of the switches and activate them agin
|
||||
else
|
||||
{
|
||||
chrome.storage.local.get(["enabledVocab", "enabledKanji"], (data) => {
|
||||
vocabSetting.checked = data.enabledVocab
|
||||
|
@ -93,6 +103,7 @@ globalSetting.addEventListener("change", () => {
|
|||
kanjiSetting.removeAttribute("disabled")
|
||||
}
|
||||
|
||||
// Send a message to content script that the switches were updated
|
||||
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {action: "settingsUpdated"}, (r) => {})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue