-
Notifications
You must be signed in to change notification settings - Fork 182
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
Custom Find Controller? #2339
Comments
I assume you want to benefit from improvements of pdf.js, so anything involving a fork sounds painful. I only manage because I merge the new changes every week. I wonder if you can implement a system to add plugins to the findbar. That's similar to option 4, but instead of overwriting methods you define user hooks to add custom code. If you're ready to send me such a PR, I'll happily merge it. I guess it's a sensible compromise between risking merge hell and adding flexibility to the library. BTW, you regex search might be interesting to other users, too. What about adding it to a demo page of the showcase? |
Come to think of it, the plugins might bring back fuzzy search and searching multiple terms. I had to abandon these improvements some time ago because I ran into the merge hell. It would be nice to get them back! |
That's basically what I want... regex search and multiple terms. I basically only need to add one line in
Not very clean or maintainable. If we were to write a plugin system I'm guessing it would be almost the same thing. Something to override the built in Edit: And this to overide the instance in the pdfjs application:
|
I'm thinking of this approach. Both would be changes to
Not quite a plugins... but close. You could resonably do this to other objects as well. Here is what I would guss my "plugin" would look like:
Registered something like:
|
Yes, that's an option. You're definitely on the right track. It's just that I'd like to find a minimally invasive approach. And it seems I'm less shy about manipulating prototypes. :) customQueryConversion(query) {
return query; // idempotent default implementation
}
#calculateMatch(pageIndex) {
let query = this.#query;
if (query.length === 0) {
return; // Do nothing: the matches should be wiped out already.
}
const { caseSensitive, entireWord } = this.#state;
const pageContent = this._pageContents[pageIndex];
const hasDiacritics = this._hasDiacritics[pageIndex];
let isUnicode = false;
// allow users to add their plugins <<<<<<<<<
query = customQueryConversion(query);
// end of the modification <<<<<<<<<<<<<<<
if (typeof query === "string") {
[isUnicode, query] = this.#convertToRegExpString(query, hasDiacritics);
} else {
... and (PDFViewerApplication as any).pdfViewer.findController.customQueryConversion = () => { /* put your magic here */ }; How do you like the idea? |
That might work in some cases... but in my case I need to conditionally skip |
If we wanted that it would have to be something like:
then
|
That shouldn't be a problem - customQueryConversion(query) {
return {
skipDefaultBehavior: false;
query; // idempotent default implementation
}
}
#calculateMatch(pageIndex) {
...
// allow users to add their plugins <<<<<<<<<
{ query, skipDefaultBehavior} = customQueryConversion(query);
if (skipDefaultBehavior) {
// do nothing;
}
else if (typeof query === "string") { // end of the modification <<<<<<<<<<<<<<< |
We've sent our messages simultaneously - and we're thinking along similar lines! |
I suppose my approach isn't perfect yet. But I hope we can polish it until it's useful to support most (or every?) use-case. Things we still need to consider (or at least I should consider it, I'm not familiar with your application):
|
I also might have some modifications to const originalCalculateMatch = findController._calculateMatch; // only works if _calculateMatch is public
findController._calculateMatch = function (query) {
const { matchRegex } = this.state;
if (!matchRegex) return originalCalculateMatch(query);
/* put your magic here */
};
const originalCalculateRegExpMatch = findController._calculateRegExpMatch;
findController._calculateRegExpMatch = function (query) {
const { matchRegex } = this.state;
if (!matchRegex) return originalCalculateRegExpMatch(query);
/* put your magic here */
}; Then the only change would be the search and replace Might need a few |
My override of Edit: This is what I need: const originalConvertToRegExpString = findController._convertToRegExpString.bind(findController); // only works if _convertToRegExpString is public
findController._convertToRegExpString = function (query: any) {
const { matchRegex } = this.state;
if (matchRegex) return [false, query];
return originalConvertToRegExpString(query);
}; |
@stephanrauh Let me know if the PR to pdfjs works for now. I tested locally and allowed me to override the |
Yes, everything seems to work fine. Thanks! |
Do we also need to apply these changes to the non-bleeding edge version? |
I already did. I just didn't push my changes yet. Currently, I'm merging the latest changes of pdf.js to the bleeding edge, and like so often, that's a bit painful. :) |
Your improvement has landed with version 20.1.0. Now I'm looking forward to your demo. Enjoy! |
Regarding the find by regex feature; Is there a way to prevent the viewer from doing an auto jump to the page where the search result is? |
Currently not - but I think it should be easy to implement this feature. |
Hi Stephan, thanks again for all you're doing. Just checking in to see if there's an update regarding this feature request. |
Not really, but I've finally managed to publish the huge refactoring called version 21. This, in turn, means I can now afford time to your ticket. |
You might be interested in the changes I've added in version 21.2.0. It's not precisely what you're looking for, but it already gives you new options. |
@stephanrauh That's very cool. Is the |
It's a separate instance. Basically, I simply duplicated the line |
@Hypercubed @rmdorsey I believe I've found a nice solution. Would you like to define your own custom find controller, without being restricted by the pdf.js implementation? As it turns out that's possible. The API of So it's easy to write your own find controller. I assume most people prefer to extend or modify the original find controller, and this is also possible. My prototype stephanrauh/extended-pdf-viewer-showcase@aebdf6b shows the idea. How do you like it? |
Mostly just curious. I'm still doing the overide of the methods we exposed and using the existing UI. |
Well, that's still possible, and there's nothing wrong with that. What I like about my idea is that it opens the way to a find controller that's written in TypeScript and integrates seamlessly into Angular. |
…df-viewer#2507 allow for custom find controllers
…df-viewer#2507 improved the demo - now it delays the second search until the primary find controller has found a result
…df-viewer#2507 allow for custom find controllers
Version 21.3.0 has landed, offering you the option to define your own custom controller. I'm pretty sure the document needs a lot of improvement. The current version is here: https://pdfviewer.net/extended-pdf-viewer/custom-find. Enjoy! |
Hi Stephan, thanks for this! I'm trying to use it now by creating a new angular app and bringing in the newest version of the player. I've set things up like you have here in your showcase repo: https://github.com/stephanrauh/extended-pdf-viewer-showcase/tree/main/src/app/extended-pdf-viewer/custom-find Your Angular skills are very advanced... I'm wondering if you can give me any pointers regarding these errors I'm seeing... |
I doubt my Angular skills are advanced - for example, I've never used NgRX store till now :) I suspect the difference between our projects is this setting in the "esModuleInterop": true, |
…f-viewer#2524 the PDF viewer didn't scroll find matches reliably into view
…f-viewer#2524 the PDF viewer didn't scroll find matches reliably into view
…f-viewer#2524 update the local version of the PdfFindController
I have a need to add regex search to the find toolbar. I think I have a clear understanding of ngx-extended-pdf-viewer custom components; etc. I can create custom components that I need but the search functionality itself is buried deep in pdfjs; specifically private methods in PDFFindController.
Options:
ngx-extended-pdf-viewer
andstephanrauh/pdf.js
as PRs to both projects.stephanrauh/pdf.js
and create custom component on my end to expose it.ngx-extended-pdf-viewer
to allow overriding PDFFindController so that I can maintain my own "fork" of just that class.stephanrauh/pdf.js
to make all private methods public; allowing me to override methods inpdfViewer.findController
on my end.stephanrauh/pdf.js
.I feel that # 4 would be the least impactful to your projects; but obviously will add some complexity merging upstream pdfjs changes. I'm willing an able to do the code changes myself... but would like to know if you have any thoughts on the best way to proceed.
Thank you.
The text was updated successfully, but these errors were encountered: