forked from davidtodd/landmarks
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Standalone options page; streamline help (#327)
* Move to a stand-alone options page on all browsers (taking some inspiration from #157). * Streamline the content of the Help page. * Streamline styles. Closes #227. Fixes #288. Closes #226.
- Loading branch information
Showing
20 changed files
with
2,298 additions
and
588 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "stylelint-config-standard", | ||
"rules": { | ||
"indentation": "tab" | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
}, | ||
|
||
"options_ui": { | ||
"chrome_style": true | ||
"chrome_style": false | ||
}, | ||
|
||
"permissions": ["<all_urls>"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ | |
}, | ||
|
||
"options_ui": { | ||
"browser_style": true | ||
"browser_style": false | ||
}, | ||
|
||
"applications": { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ | |
}, | ||
|
||
"options_ui": { | ||
"chrome_style": true | ||
"chrome_style": false | ||
}, | ||
|
||
"minimum_opera_version": "57", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,7 +69,7 @@ | |
}, | ||
|
||
"prefsBorderType": { | ||
"message": "Border type:" | ||
"message": "Border type" | ||
}, | ||
|
||
"prefsMomentary": { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,235 +1,59 @@ | ||
let shortcutNotSet = false | ||
import handlePopulateCommandsMessage from './keyboardShortcutTableMaker' | ||
|
||
const shortcutTableRows = [ | ||
{ | ||
element: 'tr', | ||
contains: [ | ||
{ element: 'th', content: 'Action' }, | ||
{ element: 'th', content: 'Keyboard shortcut' } | ||
] | ||
} | ||
] | ||
|
||
function makeLink(description, messageName) { | ||
return { | ||
element: 'a', | ||
class: 'configAction', | ||
tabindex: 0, | ||
content: description, | ||
listen: [{ | ||
event: 'click', | ||
handler: () => browser.runtime.sendMessage({ name: messageName }) | ||
}, { | ||
event: 'keydown', | ||
handler: (event) => { | ||
if (event.key === 'Enter') { | ||
browser.runtime.sendMessage({ name: messageName }) | ||
} | ||
} | ||
}] | ||
} | ||
} | ||
|
||
const keyboardShortcutsLink = makeLink( | ||
'Add or change shortcuts', | ||
'open-configure-shortcuts') | ||
|
||
const settingsLink = makeLink( | ||
'Change preferences (opens in new tab)', | ||
'open-settings') | ||
|
||
function makeHTML(structure, root) { | ||
let newElement | ||
|
||
for (const key in structure) { | ||
switch (key) { | ||
case 'element': | ||
newElement = document.createElement(structure[key]) | ||
root.appendChild(newElement) | ||
break | ||
case 'class': | ||
newElement.classList.add(structure[key]) | ||
break | ||
case 'tabindex': | ||
newElement.setAttribute('tabindex', String(structure[key])) | ||
break | ||
case 'text': | ||
root.appendChild(document.createTextNode(structure[key])) | ||
break | ||
case 'content': | ||
newElement.appendChild(document.createTextNode(structure[key])) | ||
break | ||
case 'listen': | ||
for (const eventHandler of structure[key]) { | ||
newElement.addEventListener( | ||
eventHandler.event, eventHandler.handler) | ||
} | ||
break | ||
case 'contains': | ||
for (const contained of structure[key]) { | ||
makeHTML(contained, newElement ? newElement : root) | ||
} | ||
break | ||
default: | ||
throw Error(`Unexpected structure key ${key} encountered.`) | ||
} | ||
} | ||
|
||
return root | ||
} | ||
|
||
function addCommandRowAndReportIfMissing(command) { | ||
// Work out the command's friendly name | ||
const action = command.name === '_execute_browser_action' | ||
? 'Show pop-up' | ||
: command.description | ||
|
||
// Work out the command's shortcut | ||
let shortcutCellElement | ||
|
||
if (command.shortcut) { | ||
// Firefox gives "Alt+Shift+N" but Chrome gives ⌥⇧N | ||
if (BROWSER === 'chrome' || BROWSER === 'opera') { | ||
shortcutCellElement = { element: 'td', contains: [ | ||
{ element: 'kbd', content: command.shortcut } | ||
]} | ||
} else { | ||
shortcutCellElement = { element: 'td', contains: | ||
firefoxShortcutElements(command.shortcut) | ||
} | ||
} | ||
} else { | ||
shortcutCellElement = { element: 'td', class: 'errorItem', contains: [ | ||
{ text: 'Not set up' } | ||
]} | ||
shortcutNotSet = true | ||
} | ||
|
||
shortcutTableRows.push({ | ||
element: 'tr', | ||
contains: [ | ||
{ element: 'td', content: action }, | ||
shortcutCellElement | ||
] | ||
}) | ||
} | ||
|
||
function firefoxShortcutElements(shortcut) { | ||
const shortcutElements = [] | ||
const shortcutParts = shortcut.split(/(\+)/) | ||
|
||
for (const keyOrPlus of shortcutParts) { | ||
if (keyOrPlus !== '+') { | ||
shortcutElements.push({ element: 'kbd', content: keyOrPlus }) | ||
} else { | ||
shortcutElements.push({ text: ' + ' }) | ||
} | ||
} | ||
|
||
return shortcutElements | ||
} | ||
|
||
function messageHandler(message) { // also sender, sendResponse | ||
function messageHandler(message) { | ||
if (message.name !== 'populate-commands') return | ||
|
||
// Chrome allows only four keyboard shortcuts to be specified in the | ||
// manifest; Firefox allows many. | ||
// | ||
// The extra ones for Firefox are patched in via its specific manifest file | ||
// when the manifest is merged. | ||
// | ||
// The commands are in the manifest in the opposite order to that which | ||
// seems most logical, and need to be reversed to pop out in the right | ||
// order on the splash page. This is because the merging in of the extra | ||
// keyboard shortcuts means that the commands with added keyboard shortucts | ||
// in Firefox are bumped to the top of the commands object. | ||
// | ||
// What is a bit odd is that, on Chrome, it appears the reversal is not | ||
// needed. | ||
const commandsInOrder = (BROWSER === 'chrome' || BROWSER === 'opera') ? | ||
message.commands : message.commands.reverse() | ||
|
||
for (const command of commandsInOrder) { | ||
addCommandRowAndReportIfMissing(command) | ||
} | ||
|
||
makeHTML({ element: 'table', contains: shortcutTableRows }, | ||
document.getElementById('keyboard-shortcuts-table')) | ||
|
||
if (shortcutNotSet) { | ||
document.querySelector('#section-keyboard-navigation summary') | ||
.classList.add('errorItem') | ||
const allShortcutsAreSet = handlePopulateCommandsMessage( | ||
message, 'keyboard-shortcuts-table') | ||
|
||
document.querySelector('[data-link="shortcuts"] a') | ||
.classList.add('errorAction') | ||
document.getElementById('warning-shortcuts').hidden = allShortcutsAreSet | ||
|
||
for (const warning of document.querySelectorAll('[data-warning]')) { | ||
warning.style.display = 'block' | ||
} | ||
|
||
document.getElementById('symbol').style.display = 'inline' | ||
if (!allShortcutsAreSet) { | ||
document.getElementById('section-keyboard-shortcuts-heading') | ||
.classList.add('missing-shortcut') | ||
} | ||
} | ||
|
||
function makeConfigLinks(type, template) { | ||
for (const element of document.querySelectorAll(`[data-link="${type}"`)) { | ||
makeHTML(template, element) | ||
} | ||
} | ||
|
||
function makeSettingsAndShortcutsLinks() { | ||
if (BROWSER === 'chrome' || BROWSER === 'opera') { | ||
makeConfigLinks('shortcuts', keyboardShortcutsLink) | ||
} | ||
|
||
makeConfigLinks('settings', settingsLink) | ||
} | ||
|
||
function includeVersionNumber() { | ||
const manifest = browser.runtime.getManifest() | ||
const version = manifest.version | ||
document.getElementById('version').innerText = version | ||
} | ||
|
||
function reflectInstallOrUpdate() { | ||
// Move the appropriate section to the top | ||
const fragment = window.location.hash.substr(2) | ||
let sectionToMove = null | ||
|
||
switch (fragment) { | ||
case 'install': | ||
document.getElementById('actions-update').remove() | ||
sectionToMove = document.getElementById('section-features') | ||
break | ||
case 'update': | ||
document.getElementById('actions-install').remove() | ||
document.getElementById('section-new').open = true | ||
sectionToMove = document.getElementById('section-new') | ||
break | ||
default: | ||
// User opened the help page during normal use | ||
document.getElementById('actions-install').remove() | ||
document.getElementById('actions-update').remove() | ||
} | ||
} | ||
|
||
function allowLinksToOpenSections() { | ||
for (const link of document.querySelectorAll('a[href]')) { | ||
if (link.getAttribute('href').startsWith('#')) { | ||
link.onclick = function() { | ||
document.querySelector(this.getAttribute('href')).open = true | ||
} | ||
} | ||
if (sectionToMove) { | ||
document.getElementById('placeholder').appendChild(sectionToMove) | ||
} | ||
} | ||
|
||
function main() { | ||
browser.runtime.onMessage.addListener(messageHandler) | ||
browser.runtime.sendMessage({ name: 'get-commands' }) | ||
|
||
if (BROWSER !== 'firefox' && BROWSER !== 'opera') { | ||
document.getElementById('section-sidebar').open = false | ||
if (BROWSER === 'firefox') { | ||
document.getElementById('open-browser-shortcuts-settings') | ||
.parentElement.remove() | ||
} else { | ||
document.getElementById('open-browser-shortcuts-settings').addEventListener( | ||
'click', () => browser.runtime.sendMessage({ | ||
name: 'open-configure-shortcuts' })) | ||
} | ||
|
||
makeSettingsAndShortcutsLinks() | ||
includeVersionNumber() | ||
reflectInstallOrUpdate() | ||
allowLinksToOpenSections() | ||
} | ||
|
||
main() |
Oops, something went wrong.