extension-create 4.1.32 → 4.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.cjs +1 -1
- package/dist/steps/import-external-template.d.ts +1 -1
- package/dist/test-template-javascript/.extension-create.json +2 -2
- package/dist/test-template-javascript/package.json +1 -1
- package/package.json +1 -1
- package/templates/javascript/README.md +1 -0
- package/templates/javascript/src/content/scripts.js +11 -0
- package/templates/javascript/src/manifest.json +2 -1
- package/templates/javascript/src/sidebar/SidebarApp.js +12 -1
- package/templates/javascript/src/sidebar/page-title.js +71 -0
- package/templates/javascript/src/sidebar/styles.css +9 -0
package/dist/module.cjs
CHANGED
|
@@ -783,7 +783,7 @@ const NETWORK_TIMEOUT_MS = (()=>{
|
|
|
783
783
|
return Number.isFinite(raw) && raw > 0 ? raw : 60000;
|
|
784
784
|
})();
|
|
785
785
|
const CODELOAD_BASE = 'https://codeload.github.com/extension-js/examples/zip';
|
|
786
|
-
const DEFAULT_TEMPLATES_REF = '
|
|
786
|
+
const DEFAULT_TEMPLATES_REF = 'd69e46b311c27d11a98d241494023101b337281f';
|
|
787
787
|
const BUNDLED_TEMPLATES = [
|
|
788
788
|
"javascript"
|
|
789
789
|
];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_TEMPLATES_REF = "
|
|
1
|
+
export declare const DEFAULT_TEMPLATES_REF = "d69e46b311c27d11a98d241494023101b337281f";
|
|
2
2
|
export declare const BUNDLED_TEMPLATES: readonly string[];
|
|
3
3
|
export declare const DEFAULT_TEMPLATE_NAME = "typescript";
|
|
4
4
|
export declare const OFFLINE_FALLBACK_TEMPLATE = "javascript";
|
package/package.json
CHANGED
|
@@ -31,11 +31,22 @@ export default function initial() {
|
|
|
31
31
|
const container = createContentApp()
|
|
32
32
|
shadowRoot.appendChild(container)
|
|
33
33
|
|
|
34
|
+
// The sidebar asks this page for its title over runtime messaging, and the
|
|
35
|
+
// answer leaves with the UI on teardown so a reload never answers twice.
|
|
36
|
+
chrome.runtime.onMessage.addListener(answerPageTitle)
|
|
37
|
+
|
|
34
38
|
return () => {
|
|
39
|
+
chrome.runtime.onMessage.removeListener(answerPageTitle)
|
|
35
40
|
rootDiv.remove()
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
44
|
+
function answerPageTitle(message, _sender, sendResponse) {
|
|
45
|
+
if (!message || message.type !== 'getPageTitle') return
|
|
46
|
+
|
|
47
|
+
sendResponse({title: document.title, url: location.href})
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
async function fetchCSS() {
|
|
40
51
|
const cssUrl = new URL('./styles.css', import.meta.url)
|
|
41
52
|
const response = await fetch(cssUrl)
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"default_title": "Side Panel Content",
|
|
50
50
|
"browser_style": false
|
|
51
51
|
},
|
|
52
|
-
"chromium:permissions": ["sidePanel"],
|
|
52
|
+
"chromium:permissions": ["sidePanel", "tabs"],
|
|
53
|
+
"firefox:permissions": ["tabs"],
|
|
53
54
|
"background": {
|
|
54
55
|
"chromium:service_worker": "background.js",
|
|
55
56
|
"firefox:scripts": ["background.js"]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import './styles.css'
|
|
2
2
|
import javascriptLogo from '../images/icon.png'
|
|
3
|
+
import {watchPageTitle} from './page-title.js'
|
|
4
|
+
|
|
5
|
+
const NO_PAGE_TEXT = 'Open a web page to see its title here.'
|
|
3
6
|
|
|
4
7
|
function SidebarApp() {
|
|
5
8
|
const root = document.getElementById('root')
|
|
@@ -27,8 +30,16 @@ function SidebarApp() {
|
|
|
27
30
|
description.className = 'sidebar_description'
|
|
28
31
|
description.append('Learn more in the ', link, ' .')
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
const pageTitle = document.createElement('p')
|
|
34
|
+
pageTitle.className = 'sidebar_page_title'
|
|
35
|
+
pageTitle.textContent = NO_PAGE_TEXT
|
|
36
|
+
|
|
37
|
+
app.append(logo, title, description, pageTitle)
|
|
31
38
|
root.replaceChildren(app)
|
|
39
|
+
|
|
40
|
+
watchPageTitle((answer) => {
|
|
41
|
+
pageTitle.textContent = answer ? answer.title : NO_PAGE_TEXT
|
|
42
|
+
})
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
SidebarApp()
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// The panel's question to the page. The content script answers it with the
|
|
2
|
+
// page title and url, so the panel never reads the page on its own.
|
|
3
|
+
export const PAGE_TITLE_REQUEST = 'getPageTitle'
|
|
4
|
+
|
|
5
|
+
function isWebPage(tab) {
|
|
6
|
+
return typeof tab.url === 'string' && /^https?:/.test(tab.url)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// The page the panel is about. When the panel itself is open as a tab (Safari,
|
|
10
|
+
// or a test harness) the active tab is the panel, so the most recently used
|
|
11
|
+
// web tab stands in for it.
|
|
12
|
+
function findPageTab(callback) {
|
|
13
|
+
chrome.tabs.query({active: true, lastFocusedWindow: true}, (focused) => {
|
|
14
|
+
const current = focused?.[0]
|
|
15
|
+
|
|
16
|
+
if (current && isWebPage(current)) {
|
|
17
|
+
callback(current)
|
|
18
|
+
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
chrome.tabs.query({}, (tabs) => {
|
|
23
|
+
const webTabs = (tabs ?? []).filter(isWebPage)
|
|
24
|
+
webTabs.sort(
|
|
25
|
+
(a, b) =>
|
|
26
|
+
Number(b.active) - Number(a.active) ||
|
|
27
|
+
(b.lastAccessed ?? 0) - (a.lastAccessed ?? 0)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
callback(webTabs[0])
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function askPage(tab, onAnswer) {
|
|
36
|
+
chrome.tabs.sendMessage(tab.id, {type: PAGE_TITLE_REQUEST}, (answer) => {
|
|
37
|
+
// A page with no content script in it (a browser page, or one loaded
|
|
38
|
+
// before the extension was) has nobody to answer, so the hint stays up.
|
|
39
|
+
onAnswer(chrome.runtime.lastError ? undefined : answer)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Keeps onChange fed with the current page's title, asking again whenever the
|
|
44
|
+
// active tab changes or a page finishes loading. Returns the function that
|
|
45
|
+
// stops watching.
|
|
46
|
+
export function watchPageTitle(onChange) {
|
|
47
|
+
const refresh = () => {
|
|
48
|
+
findPageTab((tab) => {
|
|
49
|
+
if (!tab) {
|
|
50
|
+
onChange(undefined)
|
|
51
|
+
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
askPage(tab, onChange)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const onUpdated = (_tabId, changeInfo) => {
|
|
60
|
+
if (changeInfo.status === 'complete' || changeInfo.title) refresh()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
chrome.tabs.onActivated.addListener(refresh)
|
|
64
|
+
chrome.tabs.onUpdated.addListener(onUpdated)
|
|
65
|
+
refresh()
|
|
66
|
+
|
|
67
|
+
return () => {
|
|
68
|
+
chrome.tabs.onActivated.removeListener(refresh)
|
|
69
|
+
chrome.tabs.onUpdated.removeListener(onUpdated)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -61,3 +61,12 @@ body {
|
|
|
61
61
|
color: var(--sidebar-link);
|
|
62
62
|
margin: 0;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
.sidebar_page_title {
|
|
66
|
+
font-size: small;
|
|
67
|
+
margin: 1rem 0 0;
|
|
68
|
+
padding-top: 0.75rem;
|
|
69
|
+
border-top: 1px solid var(--sidebar-border);
|
|
70
|
+
text-align: center;
|
|
71
|
+
word-break: break-word;
|
|
72
|
+
}
|