Skip to content

Commit d192566

Browse files
authored
Merge pull request #51 from wheelercj/restructure
Restructure
2 parents 7a2c240 + 38f2281 commit d192566

19 files changed

+1739
-523
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
node_modules
12
*.zip
23
web-ext-artifacts
34
.web-extension-id
5+
6+
firefox/*
7+
!firefox/manifest.json
8+
!firefox/config.js
9+
10+
chrome/*
11+
!chrome/manifest.json
12+
!chrome/config.js

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,38 @@ Unlike the extensions linked above, Stardown:
9999
* requires only one click to create a markdown link for the current page
100100
* is focused on just the most important features so it's more likely to be maintained and bug-free
101101

102+
## Install from source
103+
104+
Follow these steps to install Stardown using the source code. If you also want to change Stardown's code, instead follow the directions in [Installing Stardown from source for development](./docs/develop.md#installing-stardown-from-source-for-development).
105+
106+
### Chrome and Edge
107+
108+
1. in a terminal, run `git clone https://github.com/wheelercj/Stardown.git && cd Stardown`
109+
2. then run `npm run build-chrome`
110+
3. in your browser, open `chrome://extensions/`
111+
4. click "Load unpacked"
112+
5. select Stardown's `chrome` folder
113+
114+
To get updates:
115+
116+
1. run `npm run update-chrome`
117+
2. in your browser, open `chrome://extensions/`
118+
3. click Stardown's reload button
119+
120+
### Firefox
121+
122+
1. in a terminal, run `git clone https://github.com/wheelercj/Stardown.git && cd Stardown`
123+
2. then `npm run build-firefox`
124+
3. in Firefox, open `about:debugging#/runtime/this-firefox`
125+
4. click "Load Temporary Add-on..."
126+
5. select Stardown's `firefox/manifest.json` file
127+
128+
To get updates:
129+
130+
1. run `npm run update-firefox`
131+
2. in Firefox, open `about:debugging#/runtime/this-firefox`
132+
3. click Stardown's reload button
133+
102134
## Development
103135

104136
Contributions are welcome! Let me know (such as in [an issue](https://github.com/wheelercj/Stardown/issues) or [a discussion](https://github.com/wheelercj/Stardown/discussions)) what you have in mind ahead of time if you think there's a chance it won't be approved.

chrome/config.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Copyright 2024 Chris Wheeler
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import * as menu from './menu.js';
18+
19+
export const browser = chrome;
20+
21+
/**
22+
* createContextMenus creates the context menu options.
23+
* @returns {void}
24+
*/
25+
export function createContextMenus() {
26+
// This function should do nothing. It needs to exist because the Firefox extension
27+
// uses a function by the same name that is imported into the background script.
28+
}
29+
30+
/**
31+
* updateContextMenu updates the options in the context menu based on the message from
32+
* the content script. This only works if the context menu is not visible.
33+
* @param {object} message - the message from the content script.
34+
* @param {boolean} message.isImage - whether the mouse is over an image.
35+
* @param {boolean} message.isLink - whether the mouse is over a link.
36+
* @returns {void}
37+
*/
38+
export function updateContextMenu(message) {
39+
// The `browser.contextMenus.update` method doesn't work well in Chromium because
40+
// when it is used to hide all but one context menu option, the one remaining would
41+
// appear under a "Stardown" parent menu option instead of being in the root of the
42+
// context menu.
43+
browser.contextMenus.removeAll();
44+
45+
if (message.isImage) {
46+
browser.contextMenus.create(menu.imageItem);
47+
} else if (message.isLink) {
48+
browser.contextMenus.create(menu.linkItem);
49+
} else {
50+
browser.contextMenus.create(menu.linkItem);
51+
browser.contextMenus.create(menu.imageItem);
52+
}
53+
54+
browser.contextMenus.create(menu.pageItem);
55+
browser.contextMenus.create(menu.selectionItem);
56+
browser.contextMenus.create(menu.videoItem);
57+
browser.contextMenus.create(menu.audioItem);
58+
}
59+
60+
/**
61+
* @typedef {import('../src/content.js').ContentResponse} ContentResponse
62+
*/
63+
64+
/**
65+
* handleCopyRequest writes text to the clipboard and returns a content response object.
66+
* @param {string} text - the text to copy to the clipboard.
67+
* @returns {Promise<ContentResponse>}
68+
*/
69+
export async function handleCopyRequest(text) {
70+
// `navigator.clipboard.writeText` only works in Chromium if the document is
71+
// focused. Probably for security reasons, `document.body.focus()` doesn't work
72+
// here. Whether the document is focused doesn't seem to be an issue in Firefox.
73+
if (!document.hasFocus()) {
74+
console.info('The document is not focused');
75+
return {
76+
status: 0, // failure
77+
notifTitle: 'Error',
78+
notifBody: 'Please click the page and try again',
79+
};
80+
}
81+
82+
try {
83+
await navigator.clipboard.writeText(text);
84+
} catch (err) {
85+
console.error(err);
86+
return {
87+
status: 0, // failure
88+
notifTitle: 'Failed to copy markdown',
89+
notifBody: err.message,
90+
};
91+
}
92+
return {
93+
status: 1, // successfully copied one item
94+
notifTitle: 'Markdown copied',
95+
notifBody: 'Your markdown can now be pasted',
96+
};
97+
}
File renamed without changes.

docs/develop.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,40 @@ To keep Stardown easy to use, I would like to avoid having a popup and to genera
88

99
I would like to keep Stardown relatively simple so that it's reliable, has few bugs that get fixed quickly, and is easy to maintain.
1010

11+
## Installing Stardown from source for development
12+
13+
### Chrome and Edge
14+
15+
1. in a terminal, run `git clone https://github.com/wheelercj/Stardown.git && cd Stardown`
16+
2. then run `npm install && npm run dev-chrome`
17+
3. in your browser, open `chrome://extensions/`
18+
4. click "Load unpacked"
19+
5. select Stardown's `chrome` folder
20+
21+
In the `chrome` folder, don't make any changes unless they're to `config.js` or `manifest.json` because the other files get overwritten or deleted each time `npm run dev-chrome` runs.
22+
23+
To update Stardown after you make changes or you `git pull` changes:
24+
25+
1. run `npm run dev-chrome`
26+
2. in your browser, open `chrome://extensions/`
27+
3. click Stardown's reload button
28+
29+
### Firefox
30+
31+
1. in a terminal, run `git clone https://github.com/wheelercj/Stardown.git && cd Stardown`
32+
2. then run `npm install && npm run dev-firefox`
33+
3. in Firefox, open `about:debugging#/runtime/this-firefox`
34+
4. click "Load Temporary Add-on..."
35+
5. select Stardown's `firefox/manifest.json` file
36+
37+
In the `firefox` folder, don't make any changes unless they're to `config.js` or `manifest.json` because the other files get overwritten or deleted each time `npm run dev-firefox` runs.
38+
39+
To update Stardown after you make changes or you `git pull` changes:
40+
41+
1. run `npm run dev-firefox`
42+
2. in Firefox, open `about:debugging#/runtime/this-firefox`
43+
3. click Stardown's reload button
44+
1145
## Git workflow for collaboration
1246

1347
Let's create feature branches with descriptive names and make pull requests as described in [Getting started with Git and GitHub](https://chriswheeler.dev/posts/getting-started-with-git-and-github/#git-workflows).
@@ -89,8 +123,7 @@ When something goes wrong, Stardown should still respond well.
89123
- In Firefox, [Manifest V3 extensions with low privilege activeTab shows annoying blue dot for all websites](https://bugzilla.mozilla.org/show_bug.cgi?id=1851083). This is why I changed the Firefox version of Stardown from manifest v3 to v2.
90124
- Although Stardown no longer uses Firefox's manifest v3, [Firefox does not support service_worker in manifest v3](https://stackoverflow.com/questions/75043889/manifest-v3-background-scripts-service-worker-on-firefox).
91125
- Firefox [sometimes requires an add-on ID](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/) in `browser_specific_settings` in manifest.json, but Chromium doesn't allow `browser_specific_settings`.
92-
93-
Stardown's code is written to work in both Firefox and Chromium, except that they require different manifest files.
126+
- Based on testing I took notes on in [#11](https://github.com/wheelercj/Stardown/issues/11), it appears Firefox manifest v2 does not allow use of the `import` and `export` keywords, and Chrome manifest v3 does not allow their use in content scripts. That's why Stardown requires using a bundler.
94127

95128
## Text fragments
96129

firefox/config.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
Copyright 2024 Chris Wheeler
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import * as menu from './menu.js';
18+
19+
browser.action = browser.browserAction; // for manifest v2 compatibility
20+
21+
/**
22+
* createContextMenus creates the context menu options.
23+
* @returns {void}
24+
*/
25+
export function createContextMenus() {
26+
browser.runtime.onInstalled.addListener(() => {
27+
browser.contextMenus.create(menu.pageItem);
28+
browser.contextMenus.create(menu.selectionItem);
29+
browser.contextMenus.create(menu.linkItem);
30+
browser.contextMenus.create(menu.imageItem);
31+
browser.contextMenus.create(menu.videoItem);
32+
browser.contextMenus.create(menu.audioItem);
33+
});
34+
}
35+
36+
/**
37+
* updateContextMenu updates the options in the context menu based on the message from
38+
* the content script. This only works if the context menu is not visible.
39+
* @param {object} message - the message from the content script.
40+
* @param {boolean} message.isImage - whether the mouse is over an image.
41+
* @param {boolean} message.isLink - whether the mouse is over a link.
42+
* @returns {void}
43+
*/
44+
export function updateContextMenu(message) {
45+
if (message.isImage) {
46+
browser.contextMenus.update('link', { visible: false });
47+
browser.contextMenus.update('image', { visible: true });
48+
} else if (message.isLink) {
49+
browser.contextMenus.update('link', { visible: true });
50+
browser.contextMenus.update('image', { visible: false });
51+
}
52+
}
53+
54+
/**
55+
* @typedef {import('../src/content.js').ContentResponse} ContentResponse
56+
*/
57+
58+
/**
59+
* handleCopyRequest writes text to the clipboard and returns a content response object.
60+
* @param {string} text - the text to copy to the clipboard.
61+
* @returns {Promise<ContentResponse>}
62+
*/
63+
export async function handleCopyRequest(text) {
64+
try {
65+
await navigator.clipboard.writeText(text);
66+
} catch (err) {
67+
console.error(err);
68+
return {
69+
status: 0, // failure
70+
notifTitle: 'Failed to copy markdown',
71+
notifBody: err.message,
72+
};
73+
}
74+
return {
75+
status: 1, // successfully copied one item
76+
notifTitle: 'Markdown copied',
77+
notifBody: 'Your markdown can now be pasted',
78+
};
79+
}
File renamed without changes.

0 commit comments

Comments
 (0)