BlackGlory / copycat

🌳 Copy content from web powerful than ever before.
https://chrome.google.com/webstore/detail/jdjbiojkklnaeoanimopafmnmhldejbg
MIT License
266 stars 35 forks source link

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

Closed Norlandz closed 4 months ago

Norlandz commented 1 year ago

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

Norlandz commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

(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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

(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. https://github.com/BlackGlory/copycat/blob/4b8a8206af6c55af8637023fff40cf9a294c813d/src/background/handlers/selection-as-html.ts#L23-L28

Norlandz commented 1 year ago

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
  2. 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 commented 1 year ago

(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.

https://github.com/BlackGlory/copycat/blob/4b8a8206af6c55af8637023fff40cf9a294c813d/src/background/handlers/selection-as-html.ts#L23-L28

---

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 commented 1 year ago

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 commented 1 year ago

(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. https://github.com/BlackGlory/copycat/blob/4b8a8206af6c55af8637023fff40cf9a294c813d/src/background/handlers/selection-as-html.ts#L23-L28


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 commented 1 year ago

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: https://github.com/BlackGlory/copycat/blob/7c7a865ad7b7125c25ef653a4ff95ce204bb95ca/src/content-script/index.ts#L1-L8

v3.0.1: https://github.com/BlackGlory/copycat/blob/4b8a8206af6c55af8637023fff40cf9a294c813d/src/content-script.ts#L16-L27

To be honest, they are the same.

BlackGlory commented 1 year ago

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 commented 1 year ago

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

Norlandz commented 1 year ago

https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481306635

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).


https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481401367

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

Thanks, It works!


https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481413884

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.

https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481440509

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)


https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481613780

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

Its working, the problem seems fixed.

Norlandz commented 1 year ago

@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 commented 1 year ago

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 commented 1 year ago

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

Norlandz commented 1 year ago

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)

BlackGlory commented 1 year ago

After some debugging, I think the problem is still due to https://github.com/BlackGlory/copycat/issues/44#issuecomment-1481413884

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

Norlandz commented 4 months ago

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 commented 4 months ago

@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 commented 4 months ago

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 commented 4 months ago

@BlackGlory


For https://github.com/BlackGlory/copycat/issues/44#issuecomment-2091917017

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 https://github.com/BlackGlory/copycat/issues/44#issuecomment-2091952209

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

BlackGlory commented 4 months ago

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 commented 4 months ago

@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 commented 4 months ago

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: https://github.com/BlackGlory/copycat/blob/6f6522767fafe0f8d96de271681d3489a79617e0/src/content-script.ts#L15-L26

BlackGlory commented 4 months ago

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 commented 4 months ago

Just updated the code https://github.com/BlackGlory/copycat/commit/607ae4af940c9bb70eebf64d94ee4974f884a791, give it a try.

BlackGlory commented 4 months ago

It's worth noting that the current solution (https://github.com/BlackGlory/copycat/commit/607ae4af940c9bb70eebf64d94ee4974f884a791) 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 commented 4 months ago

Alternative solution (https://github.com/BlackGlory/copycat/commit/8a018cb7636ddb00d580d0a7d1c116bdd6f9d0c2)

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 commented 4 months ago

@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

--

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

Norlandz commented 4 months ago

For https://github.com/BlackGlory/copycat/issues/44#issuecomment-2094021500

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 commented 4 months ago

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.