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

[api-minor] Expanding divs to improve selection #7539

Merged
merged 2 commits into from
Sep 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
400 changes: 381 additions & 19 deletions src/display/text_layer.js

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions test/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
return textLayerStylePromise;
}

function rasterizeTextLayer(ctx, viewport, textContent) {
function rasterizeTextLayer(ctx, viewport, textContent,
enhanceTextSelection) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: please change this to:

  function rasterizeTextLayer(ctx, viewport, textContent,
                              enhanceTextSelection) {

return new Promise(function (resolve) {
// Building SVG with size of the viewport.
var svg = document.createElementNS(SVG_NS, 'svg:svg');
Expand All @@ -90,9 +91,11 @@ var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
var task = PDFJS.renderTextLayer({
textContent: textContent,
container: div,
viewport: viewport
viewport: viewport,
enhanceTextSelection: enhanceTextSelection,
});
Promise.all([stylePromise, task.promise]).then(function (results) {
task.expandTextDivs(true);
style.textContent = results[0];
svg.appendChild(foreignObject);

Expand Down Expand Up @@ -468,12 +471,13 @@ var Driver = (function DriverClosure() {
var textLayerContext = textLayerCanvas.getContext('2d');
textLayerContext.clearRect(0, 0,
textLayerCanvas.width, textLayerCanvas.height);
var enhanceText = !!task.enhance;
// The text builder will draw its content on the test canvas
initPromise = page.getTextContent({
normalizeWhitespace: true,
}).then(function(textContent) {
return rasterizeTextLayer(textLayerContext, viewport,
textContent);
textContent, enhanceText);
});
} else {
textLayerCanvas = null;
Expand Down
23 changes: 23 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
"rounds": 1,
"type": "text"
},
{ "id": "tracemonkey-text-enhance",
"file": "pdfs/tracemonkey.pdf",
"md5": "9a192d8b1a7dc652a19835f6f08098bd",
"rounds": 1,
"enhance": true,
"type": "text"
},
{ "id": "issue3925",
"file": "pdfs/issue3925.pdf",
"md5": "c5c895deecf7a7565393587e0d61be2b",
Expand Down Expand Up @@ -331,12 +338,28 @@
"lastPage": 4,
"type": "text"
},
{ "id": "taro-text-enhance",
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add a testcase that uses enhance for the tracemonkey file too. Then way we should have horizontal, vertical and rotated text covered, as well as our default testing file, the Tracemonkey paper.

"file": "pdfs/TaroUTR50SortedList112.pdf",
"md5": "ce63eab622ff473a43f8a8de85ef8a46",
"link":true,
"rounds": 1,
"lastPage": 4,
"enhance": true,
"type": "text"
},
{ "id": "rotated-text",
"file": "pdfs/rotated.pdf",
"md5": "aed187f53e969ccdcbab0bb4c59f9e46",
"rounds": 1,
"type": "text"
},
{ "id": "rotated-text-enhance",
"file": "pdfs/rotated.pdf",
"md5": "aed187f53e969ccdcbab0bb4c59f9e46",
"rounds": 1,
"enhance": true,
"type": "text"
},
{
"id": "issue3115",
"file": "pdfs/issue3115r.pdf",
Expand Down
4 changes: 3 additions & 1 deletion web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ var SCALE_SELECT_CONTAINER_PADDING = 8;
var SCALE_SELECT_PADDING = 22;
var PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading';
var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
var ENHANCE_TEXT_SELECTION = false;

function configure(PDFJS) {
PDFJS.imageResourcesPath = './images/';
Expand Down Expand Up @@ -209,7 +210,8 @@ var PDFViewerApplication = {
eventBus: eventBus,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
downloadManager: downloadManager
downloadManager: downloadManager,
enhanceTextSelection: ENHANCE_TEXT_SELECTION,
});
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
Expand Down
2 changes: 1 addition & 1 deletion web/default_preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
"disableTextLayer": false,
"useOnlyCssZoom": false,
"externalLinkTarget": 0
}
}
4 changes: 3 additions & 1 deletion web/interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ IPDFTextLayerFactory.prototype = {
* @param {HTMLDivElement} textLayerDiv
* @param {number} pageIndex
* @param {PageViewport} viewport
* @param {Boolean} enhanceTextSelection
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport) {}
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport,
enhanceTextSelection) {}
};

/**
Expand Down
10 changes: 7 additions & 3 deletions web/pdf_page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ var TEXT_LAYER_RENDER_DELAY = 200; // ms
* @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
* @property {IPDFTextLayerFactory} textLayerFactory
* @property {IPDFAnnotationLayerFactory} annotationLayerFactory
* @property {boolean} enhanceTextSelection - Turns on the text selection
* enhancement. The default is `false`.
*/

/**
Expand All @@ -69,6 +71,7 @@ var PDFPageView = (function PDFPageViewClosure() {
var renderingQueue = options.renderingQueue;
var textLayerFactory = options.textLayerFactory;
var annotationLayerFactory = options.annotationLayerFactory;
var enhanceTextSelection = options.enhanceTextSelection || false;
Copy link
Contributor

Choose a reason for hiding this comment

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

The intention is to enable this by default (see previous comments), so let's change this to true (and in the comment above).

Copy link
Collaborator

@Snuffleupagus Snuffleupagus Aug 31, 2016

Choose a reason for hiding this comment

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

Given the performance/correctness issues currently present, refer to #7539 (comment), I don't think that we want to enable this by default at this point. Hence var ENHANCE_TEXT_SELECTION = false; should be set in app.js.

More to the point though, please note that we agreed to #7539 (comment), to avoid changing the defaults for the viewer components. Hence this comment is not applicable.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. We can also land this disabled and file a follow-up issue for the optimizations.


this.id = id;
this.renderingId = 'page' + id;
Expand All @@ -78,6 +81,7 @@ var PDFPageView = (function PDFPageViewClosure() {
this.viewport = defaultViewport;
this.pdfPageRotate = defaultViewport.rotation;
this.hasRestrictedScaling = false;
this.enhanceTextSelection = enhanceTextSelection;

this.eventBus = options.eventBus || domEvents.getGlobalEventBus();
this.renderingQueue = renderingQueue;
Expand Down Expand Up @@ -395,9 +399,9 @@ var PDFPageView = (function PDFPageViewClosure() {
div.appendChild(textLayerDiv);
}

textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv,
this.id - 1,
this.viewport);
textLayer = this.textLayerFactory.
createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport,
this.enhanceTextSelection);
}
this.textLayer = textLayer;

Expand Down
13 changes: 10 additions & 3 deletions web/pdf_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ var DEFAULT_CACHE_SIZE = 10;
* queue object.
* @property {boolean} removePageBorders - (optional) Removes the border shadow
* around the pages. The default is false.
* @property {boolean} enhanceTextSelection - (optional) Enables the improved
* text selection behaviour. The default is `false`.
*/

/**
Expand Down Expand Up @@ -127,6 +129,7 @@ var PDFViewer = (function pdfViewer() {
this.linkService = options.linkService || new SimpleLinkService();
this.downloadManager = options.downloadManager || null;
this.removePageBorders = options.removePageBorders || false;
this.enhanceTextSelection = options.enhanceTextSelection || false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, let's make this true (and in the comment above).

Copy link
Collaborator

@Snuffleupagus Snuffleupagus Aug 31, 2016

Choose a reason for hiding this comment

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

Please note that #7539 (comment) applies here too, hence this shouldn't change.


Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this newline.

this.defaultRenderingQueue = !options.renderingQueue;
if (this.defaultRenderingQueue) {
Expand Down Expand Up @@ -352,7 +355,8 @@ var PDFViewer = (function pdfViewer() {
defaultViewport: viewport.clone(),
renderingQueue: this.renderingQueue,
textLayerFactory: textLayerFactory,
annotationLayerFactory: this
annotationLayerFactory: this,
enhanceTextSelection: this.enhanceTextSelection,
});
bindOnAfterAndBeforeDraw(pageView);
this._pages.push(pageView);
Expand Down Expand Up @@ -798,13 +802,16 @@ var PDFViewer = (function pdfViewer() {
* @param {PageViewport} viewport
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport) {
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport,
enhanceTextSelection) {
return new TextLayerBuilder({
textLayerDiv: textLayerDiv,
eventBus: this.eventBus,
pageIndex: pageIndex,
viewport: viewport,
findController: this.isInPresentationMode ? null : this.findController
findController: this.isInPresentationMode ? null : this.findController,
enhanceTextSelection: this.isInPresentationMode ? false :
enhanceTextSelection,
});
},

Expand Down
30 changes: 24 additions & 6 deletions web/text_layer_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
* @property {number} pageIndex - The page index.
* @property {PageViewport} viewport - The viewport of the text layer.
* @property {PDFFindController} findController
* @property {boolean} enhanceTextSelection - Option to turn on improved
* text selection.
*/

/**
Expand All @@ -57,16 +59,19 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
this.textDivs = [];
this.findController = options.findController || null;
this.textLayerRenderTask = null;
this.enhanceTextSelection = options.enhanceTextSelection;
this._bindMouse();
}

TextLayerBuilder.prototype = {
_finishRendering: function TextLayerBuilder_finishRendering() {
this.renderingDone = true;

var endOfContent = document.createElement('div');
endOfContent.className = 'endOfContent';
this.textLayerDiv.appendChild(endOfContent);
if (!this.enhanceTextSelection) {
var endOfContent = document.createElement('div');
endOfContent.className = 'endOfContent';
this.textLayerDiv.appendChild(endOfContent);
}

this.eventBus.dispatch('textlayerrendered', {
source: this,
Expand Down Expand Up @@ -96,7 +101,8 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
container: textLayerFrag,
viewport: this.viewport,
textDivs: this.textDivs,
timeout: timeout
timeout: timeout,
enhanceTextSelection: this.enhanceTextSelection,
});
this.textLayerRenderTask.promise.then(function () {
this.textLayerDiv.appendChild(textLayerFrag);
Expand Down Expand Up @@ -314,7 +320,12 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
*/
_bindMouse: function TextLayerBuilder_bindMouse() {
var div = this.textLayerDiv;
var self = this;
div.addEventListener('mousedown', function (e) {
if (self.enhanceTextSelection && self.textLayerRenderTask) {
self.textLayerRenderTask.expandTextDivs(true);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

here and in mouseup, return from the function to avoid div-workaround logic.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then I'd assume that we also want to change https://github.com/mozilla/pdf.js/blob/master/web/text_layer_builder.js#L67-L69 to something like:

if (!this.enhanceTextSelection) {
  var endOfContent = document.createElement('div');
  endOfContent.className = 'endOfContent';
  this.textLayerDiv.appendChild(endOfContent);
}

var end = div.querySelector('.endOfContent');
if (!end) {
return;
Expand All @@ -338,6 +349,10 @@ var TextLayerBuilder = (function TextLayerBuilderClosure() {
end.classList.add('active');
});
div.addEventListener('mouseup', function (e) {
if (self.enhanceTextSelection && self.textLayerRenderTask) {
self.textLayerRenderTask.expandTextDivs(false);
return;
}
var end = div.querySelector('.endOfContent');
if (!end) {
return;
Expand All @@ -362,13 +377,16 @@ DefaultTextLayerFactory.prototype = {
* @param {HTMLDivElement} textLayerDiv
* @param {number} pageIndex
* @param {PageViewport} viewport
* @param {boolean} enhanceTextSelection
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport) {
createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport,
enhanceTextSelection) {
return new TextLayerBuilder({
textLayerDiv: textLayerDiv,
pageIndex: pageIndex,
viewport: viewport
viewport: viewport,
enhanceTextSelection: enhanceTextSelection
});
}
};
Expand Down