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

Refactor annotation display layer code to use classes #6770

Merged

Conversation

timvandermeij
Copy link
Contributor

This patch refactors the annotation display layer code to use classes. This work makes it easier to add new annotation types and improves readability and testability of the code. Feedback is appreciated.

Most of this patch is moving existing code. The following structural additions have been made:

  • Introduction of AnnotationElementFactory, which is based on the code in src/core/annotation.js, to handle returning the correct annotation element type object.
  • Introduction of AnnotationElement, a base class for other annotation element types that is responsible for creating a generic empty container.
  • Introduction of LinkAnnotationElement, responsible for rendering a link annotation element. Contains existing code, but _bindLink and _bindNamedAction have been moved to separate methods where they were previously inlined.
  • Introduction of TextAnnotationElement, responsible for rendering a text annotation element. Contains existing code, but _toggle, _show and _hide have been moved to separate methods where they were previously inlined.
  • Introduction of WidgetAnnotationElement, responsible for rendering a widget annotation element. Contains existing code with _setTextStyle as a method here instead of an overall function before.

Aside from the above, JSDoc comments have been added.

I have tested this with a set of 23 PDF files containing different annotation types, where Link, Text and Widget are covered. I found no difference in behavior, rendering or printing before and after the patch.

* @private
* @memberof AnnotationElement
*/
_makeContainer: function AnnotationElement_makeContainer() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think that calling this _createContainer instead feels like better English :)

(Please note: I've only looked through the diff quickly so far, and I still want to go through the code more thoroughly before signing off on it. I'll try to do that during the weekend.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the new commit.

@Snuffleupagus
Copy link
Collaborator

I have tested this with a set of 23 PDF files containing different annotation types, where Link, Text and Widget are covered. I found no difference in behavior, rendering or printing before and after the patch.

@timvandermeij Would you be able to look into #6673 next, since having more complete test-coverage for annotations would mean that testing e.g. refactoring PRs like this one would be so much easier?

style.fontFamily = fontFamily + fallbackName;
}
/**
* @typedef {Object} AnnotationElementOptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AnnotationElementParameters ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the new commit.

@timvandermeij
Copy link
Contributor Author

Thank you both. I will address the comments soon. @Snuffleupagus, there is now #6780 for the regression testing, which should address your test coverage concern.

}, false);
image.addEventListener('mouseout', function image_mouseOutHandler() {
self._hide();
}, false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you can actually make all of the above event listeners one-liners, e.g. like this:

image.addEventListener('click', this._toggle.bind(this));
...

Edit: You might not agree with this (for e.g. readability reasons), in that case I'm fine with keeping it as is, but I figured I'd mention it anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the new commit. Note that I needed to add the isBool check and import because with this oneliner the event object is now passed to the listener, where we first expected only to get a boolean value.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really sorry that I didn't think this through properly before!
I believe that you should be able to get rid of the boolean check, and be able to simplify all the event listeners by doing:

image.addEventListener('click', this._toggle.bind(this));
image.addEventListener('mouseover', this._show.bind(this, false));
image.addEventListener('mouseout', this._hide.bind(this, false));

content.addEventListener('click', this._hide.bind(this, true));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know that that was possible, but it works like a charm. The boolean checks and import have been removed and the event listener lines have been updated. I verified with a PDF file with text annotations that the behavior is still the same.

@timvandermeij timvandermeij force-pushed the annotation-display-classes branch 2 times, most recently from 716c92f to f48c6a6 Compare December 19, 2015 16:00
@timvandermeij
Copy link
Contributor Author

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_preview from @timvandermeij received. Current queue size: 0

Live output at: http://107.21.233.14:8877/025192a848975ce/output.txt

@timvandermeij
Copy link
Contributor Author

/botio test

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_test from @timvandermeij received. Current queue size: 0

Live output at: http://107.21.233.14:8877/c4b1be218642960/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

Command cmd_test from @timvandermeij received. Current queue size: 0

Live output at: http://107.22.172.223:8877/0adf36a9e4cf829/output.txt

@pdfjsbot
Copy link

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/0adf36a9e4cf829/output.txt

Total script time: 20.16 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@pdfjsbot
Copy link

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/c4b1be218642960/output.txt

Total script time: 20.63 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

Snuffleupagus added a commit that referenced this pull request Dec 20, 2015
Refactor annotation display layer code to use classes
@Snuffleupagus Snuffleupagus merged commit cfc0cc8 into mozilla:master Dec 20, 2015
@Snuffleupagus
Copy link
Collaborator

Looks good, thank you for the patch!

Also, thanks for your continued efforts in improving both the annotation code and the related tests!

warn('Unimplemented border style: beveled');
break;
default:
throw new Error('Unimplemented annotation type "' + subtype + '"');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason to throw error instead of warn it and just don't render anything? I don't think there are any code that catches this error so this error is a fatal error that will propagate to top level and stop the annotation rendering process. I think this is also the reason why #6818 failed (but I still prefer #6786 why of doing it)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has just been refactoring, so it was like this already before the PR. I think the main reason is that we should just not render any HTML elements for unsupported annotation types. Note that this is not the main reason the hasHtml removal patch failed: that was because we tried to call render on a non-object because there is no annotation element class for unsupported annotation types. Of course, if you think improvements are possible, please open a separate issue or a PR.

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

Successfully merging this pull request may close these issues.

5 participants