Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copycat is not working in Chrome (especially the Hotkey) #44

Closed
Norlandz opened this issue Mar 22, 2023 · 33 comments
Closed

Copycat is not working in Chrome (especially the Hotkey) #44

Norlandz opened this issue Mar 22, 2023 · 33 comments
Labels

Comments

@Norlandz
Copy link

Norlandz commented Mar 22, 2023

in_short

Copycat has been working fine before in Chrome.

But in the recent 2~3? weeks, Copycat starts to not working sometimes (especially the Hotkey).

I have not idea what is the cause.

details

  • I have set hotkey shortcuts for Copycat in Chrome,
    and it has been working before.

  • Recently,
    when I:

    1. open a web page (a tab)
    2. select some text & try to copy into Markdown/Html/PlainText ...

    -> 70% of the time, the Copycat Hotkey fails to copy -- nothing is copied/updated to the Clipboard (-- Clipboard remains unchanged).

    • (70% -- the percentage is base on the page-open actions, not the copy actions (see below [page-open action based]))
  • I tired to refresh the page / restart the browser / disable&enable the extension / disable all other extension.
    Still, cant solve the problem -- it still only works sometimes
    (--ie: if you refresh multiple times, you may eventually get a page that have Copycat working...)

    I tried to reinstall the extension, not helping.

  • If the page was opened & copycat works, then it remains to work, as long as I dont refresh the page.
    If the page was opened & copycat doesnt work, then it remains to doesnt work, as long as I dont refresh the page.
    (page-open action based)

    So, it may be:
    working in one web page (one tab),
    while failing to work in another web page (another tab).

    Its not for a specific website -- it can happen to any website.

  • If I right click and use the context menu (not hotkey) to select Copycat to copy,
    -> still.... 60% of the time, the Copycat (Context Menu) fails to copy,

    There could be a case where: Hotkey is not working & Context menu is not working either. (most of the time)
    There could be a case where: Hotkey is not working, but Context menu works. (sometimes)

  • I tried to assign the same Hotkey to other extensions -- the Hotkey is working fine for others, but not for Copycat.

@Norlandz
Copy link
Author

Norlandz commented Mar 22, 2023

Is there a way to: execute a Javascript command in the Chrome Dev Console -- in order to do the copy action?

Or is there any hotkey to navigate through the context menu
--ie: only use the keyboard to navigate to the command; dont need to use mouse to click.

@Norlandz
Copy link
Author

Btw,

DevTools failed to load source map: Could not load content for chrome-extension://cfhdojbkjhnklbpkdaibdccddilifddb/browser-polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND
DevTools failed to load source map: Could not load content for chrome-extension://jdjbiojkklnaeoanimopafmnmhldejbg/copycat.js.map: System error: net::ERR_BLOCKED_BY_CLIENT

I often times see these outputs in the Chrome Dev Console.
But it worked fine before, even it had these output.
Plus, I often see other similar outputs like these in other website. Seems not important.

Just saying, but I dont think this is the cause,

@Norlandz
Copy link
Author

(I just revert to v2.4.5, seems old version is working fine.)

(Btw, the new version seems auto-format the Html;
Is there an option to disable that & only copy the original Html code?)

@BlackGlory
Copy link
Owner

I have no clue how to fix these issues.
I think these failures are caused by Chromium itself because the Chromium team hasn't figured out how to properly implement MV3.
Upgrading Copycat from MV2 to MV3 was a forced move because MV2 has been sentenced to death by the Chromium team.

@BlackGlory
Copy link
Owner

Or is there any hotkey to navigate through the context menu
--ie: only use the keyboard to navigate to the command; dont need to use mouse to click.

As far as I know, there is such a Menu key, but I don't think it's what you want.

@BlackGlory
Copy link
Owner

(Btw, the new version seems auto-format the Html;
Is there an option to disable that & only copy the original Html code?)

HTML does get formatted, because unformatted HTML is hard to read, and I can't find a reason to disable this behavior.

await pipeAsync(
html
, offscreen.sanitizeHTML
, html => offscreen.formatURLsInHTML(html, baseURL, config.url)
, formatHTML
)

@Norlandz
Copy link
Author

Or is there any hotkey to navigate through the context menu
--ie: only use the keyboard to navigate to the command; dont need to use mouse to click.

As far as I know, there is such a Menu key, but I don't think it's what you want.

---

in the context menu
for example,
1. copy can be selected by pressingc / ctrl+c
1. print can be selected by pressing p / ctrl+p
Is there a (context menu navigation) key for Copycat too?

So, I can press (say,) o to select Copycat,
then press another key / a sequence of keys to select to copy into Markdown/Html/...

---

image

@Norlandz
Copy link
Author

(Btw, the new version seems auto-format the Html;
Is there an option to disable that & only copy the original Html code?)

HTML does get formatted, because unformatted HTML is hard to read, and I can't find a reason to disable this behavior.

await pipeAsync(
html
, offscreen.sanitizeHTML
, html => offscreen.formatURLsInHTML(html, baseURL, config.url)
, formatHTML
)

---

The problem of auto-format (code prettify) is:

  1. Most of the time I need the original html
  2. Auto-format doesnt suit everyone's style
  3. Auto-format makes the html very long & harder to read

So, I rather there is an option.

---

for auto-format I mean code prettify (Not sure did I mis-refer to something else)

ie:

<em>A  AA
<em>

becomes

<em>
  AAA
<em>

---

(should I move this to another post)

@BlackGlory
Copy link
Owner

BlackGlory commented Mar 23, 2023

Or is there any hotkey to navigate through the context menu
--ie: only use the keyboard to navigate to the command; dont need to use mouse to click.

As far as I know, there is such a Menu key, but I don't think it's what you want.


in the context menu for example, 1. copy can be selected by pressingc / ctrl+c 1. print can be selected by pressing p / ctrl+p Is there a (context menu navigation) key for Copycat too?

So, I can press (say,) o to select Copycat, then press another key / a sequence of keys to select to copy into Markdown/Html/...


image

There are two things, access key and shortcut:

The access key is a Windows-specific feature that is better suited for standalone applications.
For extensions, the access key may be duplicated, making it unusable.
As far as I know, Chromium doesn't show access keys for extensions anymore, I'm not sure if this will be supported in the future.
For these reasons, I would not consider implementing it.

The shortcut, Chromium doesn't support it, so it's impossible to implement.

@BlackGlory
Copy link
Owner

(Btw, the new version seems auto-format the Html;
Is there an option to disable that & only copy the original Html code?)

HTML does get formatted, because unformatted HTML is hard to read, and I can't find a reason to disable this behavior.

await pipeAsync(
html
, offscreen.sanitizeHTML
, html => offscreen.formatURLsInHTML(html, baseURL, config.url)
, formatHTML
)


The problem of auto-format (code prettify) is:

  1. Most of the time I need the original html
  2. Auto-format doesnt suit everyone's style
  3. Auto-format makes the html very long & harder to read

So, I rather there is an option.


for auto-format I mean code prettify (Not sure did I mis-refer to something else)

ie:

<em>A  AA
<em>

becomes

<em>
  AAA
<em>

(should I move this to another post)

Done, now there is a new option called "Format HTML".

@BlackGlory
Copy link
Owner

BlackGlory commented Mar 23, 2023

For the fault mentioned in the OP, I noticed that in some cases the content script actually throws this error:

Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.

v2.4.5:

function getSelectionHTML(): string {
const userSelection = window.getSelection()
const range = userSelection!.getRangeAt(0)
const clonedSelection = range.cloneContents()
const div = document.createElement ('div')
div.appendChild(clonedSelection)
return div.innerHTML.toString()
}

v3.0.1:

function getSelectionHTML(): string {
const userSelection = window.getSelection()
if (userSelection) {
const range = userSelection?.getRangeAt(0)
const clonedSelection = range.cloneContents()
const div = document.createElement ('div')
div.appendChild(clonedSelection)
return div.innerHTML
} else {
return ''
}
}

To be honest, they are the same.

@BlackGlory
Copy link
Owner

SW sometimes fails to send messages to tabs, I don't know why:

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
    at wrappedSendMessageCallback (browser-polyfill.js:1183:1)

@BlackGlory
Copy link
Owner

Just released v3.0.2, not sure if it fixes the problem.

@Norlandz
Copy link
Author


#44 (comment)

The access key is a Windows-specific feature that is better suited for standalone applications.
For extensions, the access key may be duplicated, making it unusable.

If it wouldnt work, thats fine;
I wanted that just as a workaround when the hotkey was not working -- but now the hotkeys are fine (fixed).


#44 (comment)

Done, now there is a new option called "Format HTML".

Thanks, It works!


#44 (comment)

For the fault mentioned in the OP, I noticed that in some cases the content script actually throws this error:

Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.

#44 (comment)

SW sometimes fails to send messages to tabs, I don't know why:

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
   at wrappedSendMessageCallback (browser-polyfill.js:1183:1)

(Im not sure about these)


#44 (comment)

Just released v3.0.2, not sure if it fixes the problem.

Its working, the problem seems fixed.

@Norlandz
Copy link
Author

@BlackGlory

Actually, the problem is not solved completely.
v3.0.2 is has a higher probability of success, compare to v3.0.0?;
but it still fails sometimes. (2 days of using)

Especially when using the Copycat Extension hotkey in Chrome (to do a copy).
(so, same as before, but just slightly better.)

The Copycat right click context menu approach is much more reliable than before
(seems success every time).

---

(Btw, Maybe you can consider to put an option to output some debug info.
So the user can take a look at & help out to spot the problem? (not sure))

@BlackGlory
Copy link
Owner

Unfortunately, I can't find any more parts that can be fixed.
I think the only thing we can do is to keep the Chrome version up to date.

@BlackGlory BlackGlory reopened this Mar 30, 2023
@BlackGlory
Copy link
Owner

A bug was fixed in v3.0.4 that is likely related to this issue.

@Norlandz
Copy link
Author

A bug was fixed in v3.0.4 that is likely related to this issue.

No, it seems the problem is still there. -- Copycat hotkey only works sometimes.

(Some points to mention again)

  • seems its more of a hotkey issue between Copycat & Chrome (right click copy seems good)
  • v2.4.5 is still working fine (on my end)
  • could it be Network related?
  • is Copycat working fine on others? idk why seems no one was mentioning this?

@BlackGlory
Copy link
Owner

After some debugging, I think the problem is still due to #44 (comment)

When using shortcuts, userSelection.rangeCount may be 0 on some pages, I don't know why.

@Norlandz
Copy link
Author

Norlandz commented May 2, 2024

Update:

Still investigating, the statement

local dev extension works with no problem.

may not hold.

It works sometimes, but it needs to be refreshed some other time.
Feel like the old behavior I mentioned before.


the following content may no longer hold true

@BlackGlory
Update:

in short

Turned out, the local dev extension works with no problem.
-- it seems like there is a problem between the downloaded version vs local dev version.

details

Cuz the problem of the hotkey not working still exists.
(Though the context menus has no problem.)

I downloaded your source code, tried to look through & debug it.

>"
chrome.commands.onCommand.addListener(async (command, tab) => {
  const result = await commandHandlers[command](
    {}
  , tab ?? await getActiveTab()
  )
<>
G:\UsingTemp\copycat\src\background\index.ts


>"
export const commandSelectionAsMarkdown: CommandHandler = async (info, tab) => {
  if (tab.id) {
    const baseURL = info.frameUrl ?? info.pageUrl ?? tab.url

    if (baseURL) {
<>
G:\UsingTemp\copycat\src\background\handlers\selection-as-markdown.ts

So, I load unpacked the dist folder (v3.1.4 release) as local dev extension in chrome://extensions/.
Instead of downloading it from Google Chrome Web Store - Extensions.

Turned out, the local dev extension works with no problem.
-- it seems like there is a problem between the downloaded version vs local dev version.

@Norlandz
Copy link
Author

Norlandz commented May 3, 2024

@BlackGlory
The local dev version solved the hotkey problem.
But another problem on the hotkey & iframe arise.

in short

This can be fixed if the chrome.commands.onCommand.addListener( have access to the frameId from OnClickData.

details

Actually, with the local dev version, though its better than before, the hotkey still has problem for website like www.reddit.com / https://www.autohotkey.com/docs/v2/Variables.htm.
(it seems they put an extra frame on the html)

(the context menu is still working fine, regardless)

--

The problem is due to
when using chrome.commands.onCommand.addListener(,
the info is empty -> frameId: info.frameId is null in

    if (baseURL) {
      const config = await getConfig()
      const client = createTabClient<IFrameAPI>({
        tabId: tab.id
      , frameId: info.frameId
      })
      const html = await client.getSelectionHTML()

This can be fixed if the chrome.commands.onCommand.addListener( have access to the frameId from OnClickData.

@BlackGlory
Copy link
Owner

Turned out, the local dev extension works with no problem. -- it seems like there is a problem between the downloaded version vs local dev version.

Honestly, this is very unusual.
Have you tried using Copycat in another Chromium browser or on another device? A complete reinstall of Chrome may also fix the problem.

@Norlandz
Copy link
Author

Norlandz commented May 3, 2024

@BlackGlory


For #44 (comment)

Turned out, the local dev extension works with no problem. -- it seems like there is a problem between the downloaded version vs local dev version.

Honestly, this is very unusual. Have you tried using Copycat in another Chromium browser or on another device? A complete reinstall of Chrome may also fix the problem.

Still investigating, dont worry too much on this yet, I can be wrong.
(I updated the post.)


For #44 (comment)

But you may look into the frameId thing I mentioned above.

@BlackGlory
Copy link
Owner

I cannot reproduce the problem at https://www.autohotkey.com/docs/v2/Variables.htm (use the shortcut to copy the selected content as Markdown).

Reddit's problem may be related to #49, their new design uses Web Components.

@Norlandz
Copy link
Author

Norlandz commented May 3, 2024

@BlackGlory

I think I will give up on this.

--
There must be something inside this code.

>"
      const client = createTabClient<IFrameAPI>({
        tabId: tab.id
      , frameId: info.frameId
      })
      const html = await client.getSelectionHTML()
<>
G:\UsingTemp\copycat\src\background\handlers\selection-as-markdown.ts

If frameId is provided (-- which ContextMenu does, the Hotkey Command does not),
then getSelectionHTML() will have the html.

Otherwise, html is empty most of the time.

--
Im not sure what createTabClient does.

It seems like you used a complex Proxy for calling the method getSelectionHTML().
I cannot debug inside.

@BlackGlory
Copy link
Owner

BlackGlory commented May 4, 2024

createTabClient just creates an RPC client, see https://github.com/delight-rpc/webextension/blob/2443685304b40fd8f376c9ba5c7620444bb39a5b/src/client.ts#L27-L56.
This code requests the HTML of the selected content from the content script on the tab page:

function getSelectionHTML(): string {
const userSelection = window.getSelection()
if (userSelection && userSelection.rangeCount) {
const range = userSelection.getRangeAt(0)
const clonedSelection = range.cloneContents()
const div = document.createElement('div')
div.appendChild(clonedSelection)
return div.innerHTML
} else {
return ''
}
}

@BlackGlory
Copy link
Owner

BlackGlory commented May 4, 2024

If frameId is provided (-- which ContextMenu does, the Hotkey Command does not), then getSelectionHTML() will have the html.

Otherwise, html is empty most of the time.

Chrome's behavior is not very consistent, perhaps this can be fixed by keeping track of the currently active frameId.

image
image

@BlackGlory
Copy link
Owner

BlackGlory commented May 4, 2024

Just updated the code 607ae4a, give it a try.

@BlackGlory
Copy link
Owner

BlackGlory commented May 4, 2024

It's worth noting that the current solution (607ae4a) is flawed because it just sends a message to each frame on the active tab. The background script (or the service worker) just chooses the first result that responds correctly as the final result. Also, the solution requires webNavigation permission.

@BlackGlory
Copy link
Owner

BlackGlory commented May 4, 2024

Alternative solution (8a018cb)

This solution avoids the flaws of the existing solution, but it causes the service worker to be active all the time.

content-script.ts

window.addEventListener('focus', () => {
  chrome.runtime.sendMessage(null)
})

background/index.ts

let frameId = 0
chrome.runtime.onMessage.addListener((message, sender) => {
  if (sender.id === chrome.runtime.id && isNull(message)) {
    if (isntUndefined(sender.frameId)) {
      frameId = sender.frameId
    }
  }
})

@Norlandz
Copy link
Author

Norlandz commented May 4, 2024

@BlackGlory


createTabClient just creates an RPC client, see https://github.com/delight-rpc/webextension/blob/2443685304b40fd8f376c9ba5c7620444bb39a5b/src/client.ts#L27-L56.

ok (too complex for me for now)


If frameId is provided (-- which ContextMenu does, the Hotkey Command does not), then getSelectionHTML() will have the html.
Otherwise, html is empty most of the time.

Chrome's behavior is not very consistent, perhaps this can be fixed by keeping track of the currently active frameId.

I think that is the main problem.


It's worth noting that the current solution (607ae4a) is flawed because it just sends a message to each frame on the active tab. The background script (or the service worker) just chooses the first result that responds correctly as the final result. Also, the solution requires webNavigation permission.

I thought of this before.
Too bad the Api doesnt provide frameId in a better way.


Alternative solution (8a018cb)

This solution avoids the flaws of the existing solution, but it causes the service worker to be active all the time.

content-script.ts

window.addEventListener('focus', () => {
  chrome.runtime.sendMessage(null)
})

background/index.ts

let frameId = 0
chrome.runtime.onMessage.addListener((message, sender) => {
  if (sender.id === chrome.runtime.id && isNull(message)) {
    if (isntUndefined(sender.frameId)) {
      frameId = sender.frameId
    }
  }
})

frameId = sender.frameId

(I tried this before. But I made a mistake and got the wrong frameId.
I didnt know the sender has .frameId.)

causes the service worker to be active all the time

Does that slow down the PC a lot?


I built another extension https://github.com/Norlandz/ChromeCopy
which

  • borrows your concept of getSelectionHtml()
  • uses function get_seletion_insideIframe() { const elt_active = document.activeElement; to fix the iframe problem.
  • (uses chrome.runtime.onMessage.addListener( to communicate from background.ts to contentScript.ts.)
  • its simple & has limited functionalities

--

I may try your solution (it just building is slow on my computer, takes 7min).

@Norlandz
Copy link
Author

Norlandz commented May 4, 2024

For #44 (comment)

Alternative solution (8a018cb)

I build the ext, load it.
The hotkey works now!

I guess the frameId is one of the main thing to solve the problem.

(Thanks for your time & effort!)

@BlackGlory
Copy link
Owner

Does that slow down the PC a lot?

Not sure, all I know is that the designers of MV3 certainly didn't like it.
Anyway, I submitted v3.1.5 to Chrome Web Store and am waiting for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants