-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Add options menu for extension * feat: Add options.html to manifest and storage permissions * fix: delete option without id error * feat: Update native client ff2mpv.py * feat: Update ff2mpv.js to allow multiple context menus * refactor: Remove logs * refactor: Add new line at end of file * feat: Update ruby client to support options * refactor: Reduce unnecessary function calls * refactor: Trim lines and prevent sending empty arguments * fix: Prevent access to dead objects * refactor: Remove uuid wrapper function * refactor: Improve css handling for light and dark theme * feat: Add warning message on top of options page * refactor: Expand control flow on save/update * refactor: Prevent unnecesary operations when deleting a new profile
- Loading branch information
Showing
7 changed files
with
426 additions
and
23 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
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,40 +1,99 @@ | ||
const contexts = ["link", "image", "video", "audio", "selection", "frame"]; | ||
|
||
function onError(error) { | ||
console.log(`${error}`); | ||
console.log(`${error}`); | ||
} | ||
|
||
function ff2mpv(url) { | ||
browser.tabs.executeScript({ | ||
code: "video = document.getElementsByTagName('video');video[0].pause();" | ||
}); | ||
browser.runtime.sendNativeMessage("ff2mpv", { url: url }).catch(onError); | ||
function ff2mpv(url, options = []) { | ||
browser.tabs.executeScript({ | ||
code: "video = document.getElementsByTagName('video');video[0].pause();" | ||
}); | ||
browser.runtime.sendNativeMessage("ff2mpv", { url, options }).catch(onError); | ||
} | ||
|
||
async function getOS() { | ||
return browser.runtime.getPlatformInfo().then((i) => i.os); | ||
} | ||
|
||
getOS().then((os) => { | ||
async function getProfiles() { | ||
return (await browser.storage.sync.get('profiles'))['profiles'] || []; | ||
}; | ||
|
||
async function getOptions(id) { | ||
const profiles = await getProfiles(); | ||
const profile = profiles.find(pf => pf.id === id); | ||
|
||
// If profile, remove empty lines | ||
return profile | ||
? profile.content.filter(line => !!line) | ||
: []; | ||
} | ||
|
||
async function submenuClicked(info) { | ||
switch (info.parentMenuItemId) { | ||
case "ff2mpv": | ||
/* These should be mutually exclusive, but, | ||
if they aren't, this is a reasonable priority. | ||
*/ | ||
url = info.linkUrl || info.srcUrl || info.selectionText || info.frameUrl; | ||
if (url) { | ||
const options = await getOptions(info.menuItemId); | ||
ff2mpv(url, options); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
function createProfile(profile) { | ||
browser.contextMenus.create({ | ||
parentId: "ff2mpv", | ||
id: profile.id, | ||
title: profile.name, | ||
contexts, | ||
onclick: submenuClicked, | ||
}) | ||
} | ||
|
||
function deleteProfile(menuItemId) { | ||
browser.contextMenus.remove(menuItemId); | ||
} | ||
|
||
function updateProfile(profile) { | ||
browser.contextMenus.update(profile.id, { | ||
title: profile.name, | ||
}); | ||
} | ||
|
||
getOS().then(async (os) => { | ||
var title = os == "win" ? "Play in MP&V" : "Play in MPV (&W)"; | ||
|
||
browser.contextMenus.create({ | ||
id: "ff2mpv", | ||
title: title, | ||
contexts: ["link", "image", "video", "audio", "selection", "frame"] | ||
id: "ff2mpv", | ||
title: "Profiles", | ||
contexts, | ||
}); | ||
|
||
browser.contextMenus.onClicked.addListener((info, tab) => { | ||
switch (info.menuItemId) { | ||
case "ff2mpv": | ||
/* These should be mutually exclusive, but, | ||
if they aren't, this is a reasonable priority. | ||
*/ | ||
url = info.linkUrl || info.srcUrl || info.selectionText || info.frameUrl; | ||
if (url) ff2mpv(url); | ||
break; | ||
} | ||
// Default entry | ||
browser.contextMenus.create({ | ||
parentId: "ff2mpv", | ||
title, | ||
contexts, | ||
onclick: submenuClicked, | ||
}); | ||
|
||
const profiles = await getProfiles(); | ||
|
||
profiles.forEach(profile => { | ||
browser.contextMenus.create({ | ||
parentId: "ff2mpv", | ||
id: profile.id, | ||
title: profile.name, | ||
contexts, | ||
onclick: submenuClicked, | ||
}) | ||
}); | ||
|
||
browser.browserAction.onClicked.addListener((tab) => { | ||
ff2mpv(tab.url); | ||
ff2mpv(tab.url); | ||
}); | ||
}); |
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
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,173 @@ | ||
:root { | ||
--light-theme-profile-odd: hsl(0, 0%, 95%); | ||
--light-theme-profile-border: hsl(0, 0%, 0%); | ||
--light-theme-color: hsl(0, 0%, 0%); | ||
--light-theme-background: hsl(0, 0%, 100%); | ||
--light-theme-background-input: hsl(0, 0%, 100%); | ||
--light-theme-normal-button: hsl(300, 67%, 42%); | ||
--light-theme-delete-button: hsl(0, 100%, 50%); | ||
--light-theme-button-color: hsl(0, 0%, 100%); | ||
--light-theme-normal-button-hover: hsl(300, 67%, 22%); | ||
--light-theme-delete-button-hover: hsl(0, 100%, 30%); | ||
--light-theme-warning-background: hsl(62, 90%, 85%); | ||
--light-theme-warning-text: hsl(49, 26%, 20%); | ||
--light-theme-warning-url: hsl(240, 100%, 40%); | ||
--light-theme-warning-url-visited: hsl(271, 68%, 32%); | ||
|
||
--dark-theme-profile-odd: hsl(255, 6%, 8%); | ||
--dark-theme-profile-border: hsl(0, 0%, 56%); | ||
--dark-theme-color: hsl(0, 0%, 89%); | ||
--dark-theme-background: hsl(255, 6%, 13%); | ||
--dark-theme-background-input: hsl(255, 6%, 28%); | ||
--dark-theme-normal-button: hsl(300, 67%, 22%); | ||
--dark-theme-delete-button: hsl(0, 100%, 30%); | ||
--dark-theme-button-color: hsl(0, 0%, 89%); | ||
--dark-theme-normal-button-hover: hsl(300, 67%, 42%); | ||
--dark-theme-delete-button-hover: hsl(0, 100%, 50%); | ||
--dark-theme-warning-background: hsl(49, 26%, 20%); | ||
--dark-theme-warning-text: hsl(45, 97%, 70%); | ||
--dark-theme-warning-url: hsl(93, 65%, 50%); | ||
--dark-theme-warning-url-visited: hsl(93, 45%, 30%); | ||
|
||
/* Use light theme as default */ | ||
--profile-odd: var(--light-theme-profile-odd); | ||
--profile-border: var(--light-theme-profile-border); | ||
--color: var(--light-theme-color); | ||
--background: var(--light-theme-background); | ||
--backgraund-input: var(--light-theme-background-input); | ||
--normal-button: var(--light-theme-normal-button); | ||
--delete-button: var(--light-theme-delete-button); | ||
--button-color: var(--light-theme-button-color); | ||
--normal-button-hover: var(--light-theme-normal-button-hover); | ||
--delete-button-hover: var(--light-theme-delete-button-hover); | ||
--warning-background: var(--light-theme-warning-background); | ||
--warning-text: var(--light-theme-warning-text); | ||
--warning-url: var(--light-theme-warning-url); | ||
--warning-url-visited: var(--light-theme-warning-url-visited); | ||
} | ||
|
||
body { | ||
min-width: 600px; | ||
min-height: 300px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
color: var(--color); | ||
background-color: var(--background); | ||
box-sizing: border-box; | ||
} | ||
|
||
.warning { | ||
display: flex; | ||
font-size: 16px; | ||
padding: 20px; | ||
border: 2px solid var(--warning-text); | ||
border-radius: 10px; | ||
margin: 20px 0; | ||
color: var(--warning-text); | ||
background-color: var(--warning-background); | ||
} | ||
|
||
.warning a { | ||
color: var(--warning-url); | ||
} | ||
|
||
.warning a:visited { | ||
color: var(--warning-url-visited); | ||
} | ||
|
||
#profiles-wrapper { | ||
width: 100%; | ||
} | ||
|
||
.profile:nth-child(2n + 1) { | ||
background-color: var(--profile-odd); | ||
} | ||
|
||
.profile { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 10px; | ||
box-sizing: border-box; | ||
border: 2px solid var(--profile-border); | ||
border-radius: 10px; | ||
padding: 10px; | ||
} | ||
|
||
.profile textarea, .profile input { | ||
color: var(--color); | ||
background-color: var(--background-input); | ||
} | ||
|
||
.profile textarea:focus-visible, .profile input:focus-visible { | ||
outline: dotted; | ||
outline-color: var(--profile-border); | ||
} | ||
|
||
.profile textarea { | ||
height: 120px; | ||
} | ||
|
||
.profile + .profile { | ||
margin-top: 10px; | ||
} | ||
|
||
.new-profile { | ||
border-color: var(--normal-button); | ||
} | ||
|
||
.button { | ||
border-radius: 5px; | ||
color: var(--button-color); | ||
background-color: var(--normal-button); | ||
} | ||
|
||
.button:focus-visible { | ||
outline: dotted; | ||
outline-color: var(--profile-border); | ||
} | ||
|
||
.button:hover { | ||
background-color: var(--normal-button-hover); | ||
} | ||
|
||
.delete-button { | ||
background-color: var(--delete-button); | ||
} | ||
|
||
.delete-button:hover { | ||
background-color: var(--delete-button-hover); | ||
} | ||
|
||
.buttons-wrapper { | ||
display: flex; | ||
justify-content: flex-end; | ||
gap: 10px; | ||
} | ||
|
||
#add { | ||
margin-top: 20px; | ||
width: 80%; | ||
height: 2rem; | ||
text-align: center; | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
/* If browser settings use dark theme, override styles */ | ||
--profile-odd: var(--dark-theme-profile-odd); | ||
--profile-border: var(--dark-theme-profile-border); | ||
--color: var(--dark-theme-color); | ||
--background: var(--dark-theme-background); | ||
--backgraund-input: var(--dark-theme-background-input); | ||
--normal-button: var(--dark-theme-normal-button); | ||
--delete-button: var(--dark-theme-delete-button); | ||
--button-color: var(--dark-theme-button-color); | ||
--normal-button-hover: var(--dark-theme-normal-button-hover); | ||
--delete-button-hover: var(--dark-theme-delete-button-hover); | ||
--warning-background: var(--dark-theme-warning-background); | ||
--warning-text: var(--dark-theme-warning-text); | ||
--warning-url: var(--dark-theme-warning-url); | ||
--warning-url-visited: var(--dark-theme-warning-url-visited); | ||
} | ||
} |
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,21 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>ff2mpv options</title> | ||
<link rel="stylesheet" href="options.css"> | ||
</head> | ||
<body> | ||
<div class="warning"> | ||
<p> | ||
<strong>Warning</strong>: Only add profiles that you trust! Arbitrary MPV flags should be considered arbitrary code, and should be reviewed carefully. <a href="https://mpv.io/manual">See Manual.</a> | ||
</p> | ||
</div> | ||
<div id="profiles-wrapper"> | ||
</div> | ||
<div id="status"></div> | ||
<button id="add" class="button">Add</button> | ||
|
||
<script src="../browser-polyfill.js"></script> | ||
<script src="options.js"></script> | ||
</body> | ||
</html> |
Oops, something went wrong.