windingwind / zotero-plugin-toolkit

Toolkit for Zotero Plugin Developers.
https://www.npmjs.com/package/zotero-plugin-toolkit
MIT License
115 stars 13 forks source link

Is it possible to obtain the precise coordinates of the selected text in a PDF document through the plugin? #23

Closed MoGuGuai-hzr closed 1 year ago

MoGuGuai-hzr commented 1 year ago

I am learning how to develop a zotero plugin.

Specifically, the purpose is to retrieve the coordinates of the selected text in relation to the PDF page, and subsequently display relevant hints proximal to the text. However, such an outcome has yet to be achieved.

I have attempted to obtain the 'selection', then get the range by selection.getRangeAt(0). Unfortunately, this approach has been hindered by the persistent outcome whereby Selection.isCollapsed is always set to true.

Consequently, coordinates for the selected text are consistently registering as 0.

Several methods have been employed in an attempt to obtain the 'selection', including:

These efforts have proved futile. As such, I am seeking further guidance or recommendations to resolve this issue.

Thank you in advance for your enthusiasm~

windingwind commented 1 year ago

Hi,

The pdf reader does not use a standard DOM selection. A canvas-based renderer and a group of div elements composes a pdf page.

You can compute the relative position of the selection from the highlight element and the page canvas. Or, you may find a solution using pdfjs API. The private variables of the pdf reader can be found in readerinstance._iframeWindow.wrappedJSObject.

MoGuGuai-hzr commented 1 year ago

Thanks to your help, I have made some progress, but still close to success.

I just used the following code, and successfully got the text message

let reader = Zotero.Reader._readers[0];
let selection = reader._iframeWindow.getSelection();
reader._iframeWindow.wrappedJSObject
.selectionBox.addEventListener('select', (e) => {
    Zotero.log("text: "+e.target.value)
    rect = e.target.getBoundingClientRect()
    Zotero.log("target, getBoundingClientRect:"+rect.left+", "+ rect.top+", "+ rect.right+", "+ rect.bottom);
})

Unfortunately, the output of the coordinates is constant

[JavaScript Warning: "target, getBoundingClientRect:-10, -10, -6, -6"]

Do you have any ideas about what I did wrong?

MoGuGuai-hzr commented 1 year ago

I tried using the following code, which does get the coordinates.

let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
let menu = reader._iframeWindow.document.querySelector('#selection-menu');
menu.getBoundingClientRect()

But it gets the coordinates relative to the upper left corner of the screen, not the current document.

If you have any good notes, please help me