Skip to content

Commit

Permalink
add optional permissions request
Browse files Browse the repository at this point in the history
  • Loading branch information
htrinter committed Nov 30, 2023
1 parent 6bef143 commit 508a2d9
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 53 deletions.
14 changes: 11 additions & 3 deletions src/browseraction/assets/browseraction.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,19 @@ input[type='checkbox'] {
color: #004085;
border: 1px solid #b8daff;
border-radius: 5px;
line-height: 1.6em;
}

#permissions-notification #grant-permissions,
#permissions-notification #cancel-grant-permissions {
float: right;
#permissions-notification div {
margin-bottom: 10px;
}

#permissions-notification div:last-of-type {
margin-bottom: 0;
}

#permissions-notification span.url {
background: #ddefff;
}

#permissions-notification #cancel-grant-permissions {
Expand Down
136 changes: 93 additions & 43 deletions src/browseraction/components/ActionBar.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<section id="action-bar">
<button id="extract" tabindex="6" @click="setUrlListInputData">Extract URLs from text</button>
<button id="clipper" tabindex="6" @click="invokePageClipper(false)">Clip links from page</button>
<button id="open" tabindex="2" @click="openURLs">
<button id="extract" tabindex="6" @click="invokeExtractURLs">Extract URLs from text</button>
<button id="clipper" tabindex="6" @click="invokePageClipper">Clip links from page</button>
<button id="open" tabindex="2" @click="invokeOpenURLs">
<strong>Open URLs</strong>
</button>
<span id="tabcount" v-if="tabCount !== '0'">
Expand All @@ -20,9 +20,26 @@
</span>
</section>
<section id="permissions-notification" v-if="showPermissionsNotification">
<button id="cancel-grant-permissions" @click="cancelGrantPermissions">Cancel</button>
<button id="grant-permissions" @click="invokePageClipper(true)"><strong>Grant permission</strong></button>
To clip links from web pages, the extension requires permission to access page contents.
<div>
The page clipper works by enabling you to select areas of a web page to extract links from. To do this, the extension
requires permission to access page contents of <span class="url">{{ currentPermissionTabHost }}</span>.
</div>
<div>
<button id="grant-permissions" @click="requestPageClipperPermissions()">
<strong>Grant permission</strong>
</button>
<button id="cancel-grant-permissions" @click="cancelRequestPageClipperPermissions">
Cancel
</button>
</div>
<div>
<label class="checkbox"
><input
type="checkbox"
/>
Do not show this explanation again</label
>
</div>
</section>
</template>

Expand All @@ -33,14 +50,19 @@ import { store } from '@/browseraction/components/store/store'
import browser from 'webextension-polyfill'
import { version } from '../../../package.json'
const NO_CLIP_MESSAGE = 'Clipping is not possible on this page.'
export default {
data() {
return {
showPermissionsNotification: false
showPermissionsNotification: false,
currentPermissionTabUrl: '',
currentPermissionTabHost: '',
currentPermissionsTabId: 0
}
},
methods: {
openURLs() {
invokeOpenURLs() {
loadSites(
store.urlList,
store.lazyLoadingChecked,
Expand All @@ -49,57 +71,85 @@ export default {
store.deduplicateURLsChecked
)
},
setUrlListInputData() {
invokeExtractURLs() {
store.setUrlList(extractURLs(store.urlList))
},
cancelGrantPermissions() {
this.showPermissionsNotification = false
},
async invokePageClipper(isGrantPermissionsRequest: boolean) {
const permissions: browser.Permissions.Permissions = {
permissions: ["activeTab", "scripting"],
origins: ["*://*/*"]
async invokePageClipper() {
const { tabId, tabUrl } = await this.getCurrentTabInfo()
if (tabId === undefined || tabUrl === undefined) {
alert(NO_CLIP_MESSAGE)
return
}
if (isGrantPermissionsRequest) {
const isPermissionGranted = await browser.permissions.request(permissions)
if (isPermissionGranted) {
this.showPermissionsNotification = false
await this.invokePageClipper(false)
}
this.currentPermissionTabUrl = tabUrl
this.currentPermissionTabHost = new URL(tabUrl).host
this.currentPermissionsTabId = tabId
let hasPermissions = false
try {
hasPermissions = await browser.permissions.contains(
this.buildClipperPermissionsObject()
)
} catch (e) {
console.error(e)
alert(NO_CLIP_MESSAGE)
return
}
if (hasPermissions) {
await this.injectClipperScript()
} else {
const hasPermissions = await browser.permissions.contains(permissions)
if (!hasPermissions) {
this.showPermissionsNotification = true
return
}
this.showPermissionsNotification = true
}
},
async getCurrentTabInfo(): Promise<{ tabId: number | undefined; tabUrl: string | undefined }> {
const tabs = await browser.tabs.query({ active: true, currentWindow: true })
return { tabId: tabs[0].id, tabUrl: tabs[0].url }
},
buildClipperPermissionsObject(): browser.Permissions.Permissions {
return {
permissions: ['scripting'],
origins: [this.currentPermissionTabUrl]
}
},
async injectClipperScript() {
try {
const currentTab = await browser.tabs.query({ active: true, currentWindow: true })
const currentTabId = currentTab[0]?.id
if (currentTabId !== undefined) {
const executeResponse = await browser.scripting.executeScript({
target: { tabId: currentTabId, allFrames: true },
files: [`assets/ClipperContentScript-${version}.js`]
})
const executeResponse = await browser.scripting.executeScript({
target: { tabId: this.currentPermissionsTabId, allFrames: true },
files: [`assets/ClipperContentScript-${version}.js`]
})
console.log("executeResponse", executeResponse)
if (!executeResponse || executeResponse.filter(r => !r).length) {
alert("Clipping is not possible on this page.")
} else {
window.close()
}
if (!executeResponse || executeResponse.filter((r) => !r).length) {
alert(NO_CLIP_MESSAGE)
} else {
window.close()
}
} catch (e) {
console.error(e)
alert((e as Error).message)
}
},
async requestPageClipperPermissions() {
try {
const isPermissionGranted = await browser.permissions.request(
this.buildClipperPermissionsObject()
)
if (isPermissionGranted) {
this.showPermissionsNotification = false
await this.injectClipperScript()
}
} catch (e) {
console.error(e)
alert(NO_CLIP_MESSAGE)
}
},
cancelRequestPageClipperPermissions() {
this.showPermissionsNotification = false
}
},
computed: {
store() {
return store
},
tabCount: function () {
return getTabCount(store.urlList, store.deduplicateURLsChecked)
}
Expand Down
2 changes: 1 addition & 1 deletion src/clipper/content-script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) {
selectedElement.style.outline = ''
}

document.querySelector("#opmurls-overlay")?.remove()
document.querySelector('#opmurls-overlay')?.remove()
document.body.removeAttribute('omu-clipper-initialized')
}
})
Expand Down
6 changes: 3 additions & 3 deletions src/manifest/chrome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"default": "CTRL+M"
}
},
"permissions": ["storage"],
"optional_permissions": ["activeTab", "scripting"],
"optional_host_permissions": ["*://*/*"],
"permissions": ["storage", "activeTab"],
"optional_permissions": ["scripting"],
"optional_host_permissions": ["<all_urls>"],
"incognito": "split"
}
6 changes: 3 additions & 3 deletions src/manifest/firefox/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"default_icon": "icon19.png",
"default_popup": "browseraction.html"
},
"permissions": ["storage"],
"optional_permissions": ["activeTab", "scripting"],
"host_permissions": ["*://*/*"],
"permissions": ["storage", "activeTab"],
"optional_permissions": ["scripting"],
"host_permissions": ["<all_urls>"],
"incognito": "spanning"
}

0 comments on commit 508a2d9

Please sign in to comment.