Text Replacer example#612
Conversation
| </div> | ||
| </form> | ||
|
|
||
| <script src="popup.js"></script> |
There was a problem hiding this comment.
Can you use type="module"? Then you can use top-level await in the code, rather than the awkward loading and call to loadFormData.
| }); | ||
| }); | ||
|
|
||
| document.getElementById('clear').addEventListener('click', (event) => { |
There was a problem hiding this comment.
You can get rid of this and change the <button> to be an <input type="reset" />.
There was a problem hiding this comment.
I've replaced the button with <input type="reset">, but still need an event listener in order to persist the changes.
Addressed in #1718.
| const inputs = form.querySelectorAll('input[type=text]'); | ||
|
|
||
| const patterns = [...inputs].reduce((acc, input, index) => { | ||
| const outerIndex = index >> 1; |
There was a problem hiding this comment.
Do a real division and round it. Sorry, but we should be clear to novices.
| // https://developers.google.com/open-source/licenses/bsd | ||
|
|
||
| // Replace text on the page using a static list of patterns | ||
| function textReplacer(replacements) { |
There was a problem hiding this comment.
I think having this method is a bit confusing. I'd just move its two lines into the callback for the fetcher, and expand the comment:
// Get the patterns to replace from storage, then build a regex from them and replace all text on the page.| chrome.runtime.onInstalled.addListener(() => { | ||
| registerContextMenus(); | ||
| }); |
There was a problem hiding this comment.
During extension update, will this cause an error by trying to re-register context menu items?
There was a problem hiding this comment.
Yes, it would. I think I wrote it this way originally because I considered updates to be out of scope. I've updated the code as suggested in order to better set the reader up for success.
Addressed in #1718.
| } | ||
|
|
||
| chrome.contextMenus.onClicked.addListener((info, tab) => { | ||
| if (info.menuItemId == 'replace-text-menuitem') { |
There was a problem hiding this comment.
extract "replace-text-menuitem" into a constant
| chrome.contextMenus.onClicked.addListener((info, tab) => { | ||
| if (info.menuItemId == 'replace-text-menuitem') { | ||
| replaceText(tab.id); | ||
| } |
There was a problem hiding this comment.
I'd normally recommend throwing an assert in here, since this is the only id we ever expect. Similarly for commands.
There was a problem hiding this comment.
Added explicit errors for unknown commands and context menus.
Addressed in #1718.
|
|
||
| function buildReplacementRegex(source) { | ||
| const output = []; | ||
| for (var i = 0; i < source.length; i++) { |
There was a problem hiding this comment.
| for (var i = 0; i < source.length; i++) { | |
| for (let i = 0; i < source.length; i++) { |
| function replaceText(replacements) { | ||
| let node; | ||
| const nodeIterator = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT); | ||
| while (node = nodeIterator.nextNode()) { |
There was a problem hiding this comment.
can we declare node here? We only need it in the body
There was a problem hiding this comment.
No. Unlike for-in statements, which may contain declarations, while statements require an expression in the condition position. We also can't use for-in here because the NodeIterator interface predates JavaScript's iteration protocol. The closest we can do is move the let declaration next to the while to make their relationship more clear. I've applied this change to my new PR.
Addressed in #1718.
| chrome.storage.sync.get(['patterns'], function(data) { | ||
| textReplacer(data.patterns); | ||
| }); |
There was a problem hiding this comment.
We're going to be gradually encouraging developers to avoid storage access by content scripts unless crucial. WDYT about changing this to a message to the background page? (I don't feel strongly)
There was a problem hiding this comment.
Updated the example to route all read/writes through the background context.
Addressed in #1718.
| }, | ||
| "commands": { | ||
| "replace-text": { | ||
| "description": "Replace text on the current page." |
There was a problem hiding this comment.
Doesn't this need a default keybinding?
There was a problem hiding this comment.
Strictly speaking, no, a default keybinding is not required. The user could still manually assign a key binding if they wanted to use it.
For the sake of clarity, I've updated the demo to have a default keyboard shortcut.
Addressed in #1718.
|
README.md |
|
+1 |
|
@sebastianbenz @oliverdunk what should we do with these older PRs? |
|
@dotproto, since we still dont have a textreplacer sample, any chance youd like to update this to get it merged? |
|
I'm no longer able to edit the |
Adds a sample extension called "Text Replacer." As the name implies, this extension will replace a string in the page with a custom string. Currently supports 5 replacements.