viewerjs-rails 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,356 +30,356 @@ var FIND_SCROLL_OFFSET_LEFT = -400;
30
30
  * text that is being searched for.
31
31
  */
32
32
  var TextLayerBuilder = function textLayerBuilder(options) {
33
- var textLayerFrag = document.createDocumentFragment();
34
-
35
- this.textLayerDiv = options.textLayerDiv;
36
- this.layoutDone = false;
37
- this.divContentDone = false;
38
- this.pageIdx = options.pageIndex;
39
- this.matches = [];
40
- this.lastScrollSource = options.lastScrollSource;
41
- this.viewport = options.viewport;
42
- this.isViewerInPresentationMode = options.isViewerInPresentationMode;
43
-
44
- if(typeof PDFFindController === 'undefined') {
45
- window.PDFFindController = null;
46
- }
47
-
48
- if(typeof this.lastScrollSource === 'undefined') {
49
- this.lastScrollSource = null;
50
- }
51
-
52
- this.beginLayout = function textLayerBuilderBeginLayout() {
53
- this.textDivs = [];
54
- this.renderingDone = false;
55
- };
56
-
57
- this.endLayout = function textLayerBuilderEndLayout() {
58
- this.layoutDone = true;
59
- this.insertDivContent();
60
- };
61
-
62
- this.renderLayer = function textLayerBuilderRenderLayer() {
63
- var self = this;
64
- var textDivs = this.textDivs;
65
- var bidiTexts = this.textContent;
66
- var textLayerDiv = this.textLayerDiv;
67
- var canvas = document.createElement('canvas');
68
- var ctx = canvas.getContext('2d');
69
-
70
- // No point in rendering so many divs as it'd make the browser unusable
71
- // even after the divs are rendered
72
- var MAX_TEXT_DIVS_TO_RENDER = 100000;
73
- if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER)
74
- return;
75
-
76
- for (var i = 0, ii = textDivs.length; i < ii; i++) {
77
- var textDiv = textDivs[i];
78
- if ('isWhitespace' in textDiv.dataset) {
79
- continue;
80
- }
81
-
82
- ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
83
- var width = ctx.measureText(textDiv.textContent).width;
84
-
85
- if (width > 0) {
86
- textLayerFrag.appendChild(textDiv);
87
- var textScale = textDiv.dataset.canvasWidth / width;
88
- var rotation = textDiv.dataset.angle;
89
- var transform = 'scale(' + textScale + ', 1)';
90
- transform = 'rotate(' + rotation + 'deg) ' + transform;
91
- CustomStyle.setProp('transform' , textDiv, transform);
92
- CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
93
- }
33
+ var textLayerFrag = document.createDocumentFragment();
34
+
35
+ this.textLayerDiv = options.textLayerDiv;
36
+ this.layoutDone = false;
37
+ this.divContentDone = false;
38
+ this.pageIdx = options.pageIndex;
39
+ this.matches = [];
40
+ this.lastScrollSource = options.lastScrollSource;
41
+ this.viewport = options.viewport;
42
+ this.isViewerInPresentationMode = options.isViewerInPresentationMode;
43
+
44
+ if (typeof PDFFindController === 'undefined') {
45
+ window.PDFFindController = null;
94
46
  }
95
47
 
96
- textLayerDiv.appendChild(textLayerFrag);
97
- this.renderingDone = true;
98
- this.updateMatches();
99
- };
100
-
101
- this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
102
- // Schedule renderLayout() if user has been scrolling, otherwise
103
- // run it right away
104
- var RENDER_DELAY = 200; // in ms
105
- var self = this;
106
- var lastScroll = this.lastScrollSource === null ?
107
- 0 : this.lastScrollSource.lastScroll;
108
-
109
- if (Date.now() - lastScroll > RENDER_DELAY) {
110
- // Render right away
111
- this.renderLayer();
112
- } else {
113
- // Schedule
114
- if (this.renderTimer)
115
- clearTimeout(this.renderTimer);
116
- this.renderTimer = setTimeout(function() {
117
- self.setupRenderLayoutTimer();
118
- }, RENDER_DELAY);
119
- }
120
- };
121
-
122
- this.appendText = function textLayerBuilderAppendText(geom) {
123
- var textDiv = document.createElement('div');
124
-
125
- // vScale and hScale already contain the scaling to pixel units
126
- var fontHeight = geom.fontSize * Math.abs(geom.vScale);
127
- textDiv.dataset.canvasWidth = geom.canvasWidth * Math.abs(geom.hScale);
128
- textDiv.dataset.fontName = geom.fontName;
129
- textDiv.dataset.angle = geom.angle * (180 / Math.PI);
130
-
131
- textDiv.style.fontSize = fontHeight + 'px';
132
- textDiv.style.fontFamily = geom.fontFamily;
133
- var fontAscent = geom.ascent ? geom.ascent * fontHeight :
134
- geom.descent ? (1 + geom.descent) * fontHeight : fontHeight;
135
- textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
136
- textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
137
-
138
- // The content of the div is set in the `setTextContent` function.
139
-
140
- this.textDivs.push(textDiv);
141
- };
142
-
143
- this.insertDivContent = function textLayerUpdateTextContent() {
144
- // Only set the content of the divs once layout has finished, the content
145
- // for the divs is available and content is not yet set on the divs.
146
- if (!this.layoutDone || this.divContentDone || !this.textContent)
147
- return;
148
-
149
- this.divContentDone = true;
150
-
151
- var textDivs = this.textDivs;
152
- var bidiTexts = this.textContent;
153
-
154
- for (var i = 0; i < bidiTexts.length; i++) {
155
- var bidiText = bidiTexts[i];
156
- var textDiv = textDivs[i];
157
- if (!/\S/.test(bidiText.str)) {
158
- textDiv.dataset.isWhitespace = true;
159
- continue;
160
- }
161
-
162
- textDiv.textContent = bidiText.str;
163
- // TODO refactor text layer to use text content position
164
- /**
165
- * var arr = this.viewport.convertToViewportPoint(bidiText.x, bidiText.y);
166
- * textDiv.style.left = arr[0] + 'px';
167
- * textDiv.style.top = arr[1] + 'px';
168
- */
169
- // bidiText.dir may be 'ttb' for vertical texts.
170
- textDiv.dir = bidiText.dir;
48
+ if (typeof this.lastScrollSource === 'undefined') {
49
+ this.lastScrollSource = null;
171
50
  }
172
51
 
173
- this.setupRenderLayoutTimer();
174
- };
175
-
176
- this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
177
- this.textContent = textContent;
178
- this.insertDivContent();
179
- };
180
-
181
- this.convertMatches = function textLayerBuilderConvertMatches(matches) {
182
- var i = 0;
183
- var iIndex = 0;
184
- var bidiTexts = this.textContent;
185
- var end = bidiTexts.length - 1;
186
- var queryLen = PDFFindController === null ?
187
- 0 : PDFFindController.state.query.length;
188
-
189
- var lastDivIdx = -1;
190
- var pos;
191
-
192
- var ret = [];
193
-
194
- // Loop over all the matches.
195
- for (var m = 0; m < matches.length; m++) {
196
- var matchIdx = matches[m];
197
- // # Calculate the begin position.
198
-
199
- // Loop over the divIdxs.
200
- while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) {
201
- iIndex += bidiTexts[i].str.length;
202
- i++;
203
- }
204
-
205
- // TODO: Do proper handling here if something goes wrong.
206
- if (i == bidiTexts.length) {
207
- console.error('Could not find matching mapping');
208
- }
209
-
210
- var match = {
211
- begin: {
212
- divIdx: i,
213
- offset: matchIdx - iIndex
52
+ this.beginLayout = function textLayerBuilderBeginLayout() {
53
+ this.textDivs = [];
54
+ this.renderingDone = false;
55
+ };
56
+
57
+ this.endLayout = function textLayerBuilderEndLayout() {
58
+ this.layoutDone = true;
59
+ this.insertDivContent();
60
+ };
61
+
62
+ this.renderLayer = function textLayerBuilderRenderLayer() {
63
+ var self = this;
64
+ var textDivs = this.textDivs;
65
+ var bidiTexts = this.textContent;
66
+ var textLayerDiv = this.textLayerDiv;
67
+ var canvas = document.createElement('canvas');
68
+ var ctx = canvas.getContext('2d');
69
+
70
+ // No point in rendering so many divs as it'd make the browser unusable
71
+ // even after the divs are rendered
72
+ var MAX_TEXT_DIVS_TO_RENDER = 100000;
73
+ if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER)
74
+ return;
75
+
76
+ for (var i = 0, ii = textDivs.length; i < ii; i++) {
77
+ var textDiv = textDivs[i];
78
+ if ('isWhitespace' in textDiv.dataset) {
79
+ continue;
80
+ }
81
+
82
+ ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
83
+ var width = ctx.measureText(textDiv.textContent).width;
84
+
85
+ if (width > 0) {
86
+ textLayerFrag.appendChild(textDiv);
87
+ var textScale = textDiv.dataset.canvasWidth / width;
88
+ var rotation = textDiv.dataset.angle;
89
+ var transform = 'scale(' + textScale + ', 1)';
90
+ transform = 'rotate(' + rotation + 'deg) ' + transform;
91
+ CustomStyle.setProp('transform', textDiv, transform);
92
+ CustomStyle.setProp('transformOrigin', textDiv, '0% 0%');
93
+ }
214
94
  }
215
- };
216
-
217
- // # Calculate the end position.
218
- matchIdx += queryLen;
219
-
220
- // Somewhat same array as above, but use a > instead of >= to get the end
221
- // position right.
222
- while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) {
223
- iIndex += bidiTexts[i].str.length;
224
- i++;
225
- }
226
-
227
- match.end = {
228
- divIdx: i,
229
- offset: matchIdx - iIndex
230
- };
231
- ret.push(match);
232
- }
233
95
 
234
- return ret;
235
- };
96
+ textLayerDiv.appendChild(textLayerFrag);
97
+ this.renderingDone = true;
98
+ this.updateMatches();
99
+ };
236
100
 
237
- this.renderMatches = function textLayerBuilder_renderMatches(matches) {
238
- // Early exit if there is nothing to render.
239
- if (matches.length === 0) {
240
- return;
241
- }
101
+ this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
102
+ // Schedule renderLayout() if user has been scrolling, otherwise
103
+ // run it right away
104
+ var RENDER_DELAY = 200; // in ms
105
+ var self = this;
106
+ var lastScroll = this.lastScrollSource === null ?
107
+ 0 : this.lastScrollSource.lastScroll;
108
+
109
+ if (Date.now() - lastScroll > RENDER_DELAY) {
110
+ // Render right away
111
+ this.renderLayer();
112
+ } else {
113
+ // Schedule
114
+ if (this.renderTimer)
115
+ clearTimeout(this.renderTimer);
116
+ this.renderTimer = setTimeout(function () {
117
+ self.setupRenderLayoutTimer();
118
+ }, RENDER_DELAY);
119
+ }
120
+ };
242
121
 
243
- var bidiTexts = this.textContent;
244
- var textDivs = this.textDivs;
245
- var prevEnd = null;
246
- var isSelectedPage = PDFFindController === null ?
247
- false : (this.pageIdx === PDFFindController.selected.pageIdx);
122
+ this.appendText = function textLayerBuilderAppendText(geom) {
123
+ var textDiv = document.createElement('div');
248
124
 
249
- var selectedMatchIdx = PDFFindController === null ?
250
- -1 : PDFFindController.selected.matchIdx;
125
+ // vScale and hScale already contain the scaling to pixel units
126
+ var fontHeight = geom.fontSize * Math.abs(geom.vScale);
127
+ textDiv.dataset.canvasWidth = geom.canvasWidth * Math.abs(geom.hScale);
128
+ textDiv.dataset.fontName = geom.fontName;
129
+ textDiv.dataset.angle = geom.angle * (180 / Math.PI);
251
130
 
252
- var highlightAll = PDFFindController === null ?
253
- false : PDFFindController.state.highlightAll;
131
+ textDiv.style.fontSize = fontHeight + 'px';
132
+ textDiv.style.fontFamily = geom.fontFamily;
133
+ var fontAscent = geom.ascent ? geom.ascent * fontHeight :
134
+ geom.descent ? (1 + geom.descent) * fontHeight : fontHeight;
135
+ textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
136
+ textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
254
137
 
255
- var infty = {
256
- divIdx: -1,
257
- offset: undefined
138
+ // The content of the div is set in the `setTextContent` function.
139
+
140
+ this.textDivs.push(textDiv);
258
141
  };
259
142
 
260
- function beginText(begin, className) {
261
- var divIdx = begin.divIdx;
262
- var div = textDivs[divIdx];
263
- div.textContent = '';
264
-
265
- var content = bidiTexts[divIdx].str.substring(0, begin.offset);
266
- var node = document.createTextNode(content);
267
- if (className) {
268
- var isSelected = isSelectedPage &&
269
- divIdx === selectedMatchIdx;
270
- var span = document.createElement('span');
271
- span.className = className + (isSelected ? ' selected' : '');
272
- span.appendChild(node);
273
- div.appendChild(span);
274
- return;
275
- }
276
- div.appendChild(node);
277
- }
143
+ this.insertDivContent = function textLayerUpdateTextContent() {
144
+ // Only set the content of the divs once layout has finished, the content
145
+ // for the divs is available and content is not yet set on the divs.
146
+ if (!this.layoutDone || this.divContentDone || !this.textContent)
147
+ return;
148
+
149
+ this.divContentDone = true;
150
+
151
+ var textDivs = this.textDivs;
152
+ var bidiTexts = this.textContent;
153
+
154
+ for (var i = 0; i < bidiTexts.length; i++) {
155
+ var bidiText = bidiTexts[i];
156
+ var textDiv = textDivs[i];
157
+ if (!/\S/.test(bidiText.str)) {
158
+ textDiv.dataset.isWhitespace = true;
159
+ continue;
160
+ }
161
+
162
+ textDiv.textContent = bidiText.str;
163
+ // TODO refactor text layer to use text content position
164
+ /**
165
+ * var arr = this.viewport.convertToViewportPoint(bidiText.x, bidiText.y);
166
+ * textDiv.style.left = arr[0] + 'px';
167
+ * textDiv.style.top = arr[1] + 'px';
168
+ */
169
+ // bidiText.dir may be 'ttb' for vertical texts.
170
+ textDiv.dir = bidiText.dir;
171
+ }
278
172
 
279
- function appendText(from, to, className) {
280
- var divIdx = from.divIdx;
281
- var div = textDivs[divIdx];
282
-
283
- var content = bidiTexts[divIdx].str.substring(from.offset, to.offset);
284
- var node = document.createTextNode(content);
285
- if (className) {
286
- var span = document.createElement('span');
287
- span.className = className;
288
- span.appendChild(node);
289
- div.appendChild(span);
290
- return;
291
- }
292
- div.appendChild(node);
293
- }
173
+ this.setupRenderLayoutTimer();
174
+ };
294
175
 
295
- function highlightDiv(divIdx, className) {
296
- textDivs[divIdx].className = className;
297
- }
176
+ this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
177
+ this.textContent = textContent;
178
+ this.insertDivContent();
179
+ };
298
180
 
299
- var i0 = selectedMatchIdx, i1 = i0 + 1, i;
181
+ this.convertMatches = function textLayerBuilderConvertMatches(matches) {
182
+ var i = 0;
183
+ var iIndex = 0;
184
+ var bidiTexts = this.textContent;
185
+ var end = bidiTexts.length - 1;
186
+ var queryLen = PDFFindController === null ?
187
+ 0 : PDFFindController.state.query.length;
188
+
189
+ var lastDivIdx = -1;
190
+ var pos;
191
+
192
+ var ret = [];
193
+
194
+ // Loop over all the matches.
195
+ for (var m = 0; m < matches.length; m++) {
196
+ var matchIdx = matches[m];
197
+ // # Calculate the begin position.
198
+
199
+ // Loop over the divIdxs.
200
+ while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) {
201
+ iIndex += bidiTexts[i].str.length;
202
+ i++;
203
+ }
204
+
205
+ // TODO: Do proper handling here if something goes wrong.
206
+ if (i == bidiTexts.length) {
207
+ console.error('Could not find matching mapping');
208
+ }
209
+
210
+ var match = {
211
+ begin: {
212
+ divIdx: i,
213
+ offset: matchIdx - iIndex
214
+ }
215
+ };
216
+
217
+ // # Calculate the end position.
218
+ matchIdx += queryLen;
219
+
220
+ // Somewhat same array as above, but use a > instead of >= to get the end
221
+ // position right.
222
+ while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) {
223
+ iIndex += bidiTexts[i].str.length;
224
+ i++;
225
+ }
226
+
227
+ match.end = {
228
+ divIdx: i,
229
+ offset: matchIdx - iIndex
230
+ };
231
+ ret.push(match);
232
+ }
300
233
 
301
- if (highlightAll) {
302
- i0 = 0;
303
- i1 = matches.length;
304
- } else if (!isSelectedPage) {
305
- // Not highlighting all and this isn't the selected page, so do nothing.
306
- return;
307
- }
234
+ return ret;
235
+ };
308
236
 
309
- for (i = i0; i < i1; i++) {
310
- var match = matches[i];
311
- var begin = match.begin;
312
- var end = match.end;
313
-
314
- var isSelected = isSelectedPage && i === selectedMatchIdx;
315
- var highlightSuffix = (isSelected ? ' selected' : '');
316
- if (isSelected && !this.isViewerInPresentationMode) {
317
- scrollIntoView(textDivs[begin.divIdx], { top: FIND_SCROLL_OFFSET_TOP,
318
- left: FIND_SCROLL_OFFSET_LEFT });
319
- }
320
-
321
- // Match inside new div.
322
- if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
323
- // If there was a previous div, then add the text at the end
324
- if (prevEnd !== null) {
325
- appendText(prevEnd, infty);
237
+ this.renderMatches = function textLayerBuilder_renderMatches(matches) {
238
+ // Early exit if there is nothing to render.
239
+ if (matches.length === 0) {
240
+ return;
326
241
  }
327
- // clears the divs and set the content until the begin point.
328
- beginText(begin);
329
- } else {
330
- appendText(prevEnd, begin);
331
- }
332
-
333
- if (begin.divIdx === end.divIdx) {
334
- appendText(begin, end, 'highlight' + highlightSuffix);
335
- } else {
336
- appendText(begin, infty, 'highlight begin' + highlightSuffix);
337
- for (var n = begin.divIdx + 1; n < end.divIdx; n++) {
338
- highlightDiv(n, 'highlight middle' + highlightSuffix);
242
+
243
+ var bidiTexts = this.textContent;
244
+ var textDivs = this.textDivs;
245
+ var prevEnd = null;
246
+ var isSelectedPage = PDFFindController === null ?
247
+ false : (this.pageIdx === PDFFindController.selected.pageIdx);
248
+
249
+ var selectedMatchIdx = PDFFindController === null ?
250
+ -1 : PDFFindController.selected.matchIdx;
251
+
252
+ var highlightAll = PDFFindController === null ?
253
+ false : PDFFindController.state.highlightAll;
254
+
255
+ var infty = {
256
+ divIdx: -1,
257
+ offset: undefined
258
+ };
259
+
260
+ function beginText(begin, className) {
261
+ var divIdx = begin.divIdx;
262
+ var div = textDivs[divIdx];
263
+ div.textContent = '';
264
+
265
+ var content = bidiTexts[divIdx].str.substring(0, begin.offset);
266
+ var node = document.createTextNode(content);
267
+ if (className) {
268
+ var isSelected = isSelectedPage &&
269
+ divIdx === selectedMatchIdx;
270
+ var span = document.createElement('span');
271
+ span.className = className + (isSelected ? ' selected' : '');
272
+ span.appendChild(node);
273
+ div.appendChild(span);
274
+ return;
275
+ }
276
+ div.appendChild(node);
339
277
  }
340
- beginText(end, 'highlight end' + highlightSuffix);
341
- }
342
- prevEnd = end;
343
- }
344
278
 
345
- if (prevEnd) {
346
- appendText(prevEnd, infty);
347
- }
348
- };
349
-
350
- this.updateMatches = function textLayerUpdateMatches() {
351
- // Only show matches, once all rendering is done.
352
- if (!this.renderingDone)
353
- return;
354
-
355
- // Clear out all matches.
356
- var matches = this.matches;
357
- var textDivs = this.textDivs;
358
- var bidiTexts = this.textContent;
359
- var clearedUntilDivIdx = -1;
360
-
361
- // Clear out all current matches.
362
- for (var i = 0; i < matches.length; i++) {
363
- var match = matches[i];
364
- var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
365
- for (var n = begin; n <= match.end.divIdx; n++) {
366
- var div = textDivs[n];
367
- div.textContent = bidiTexts[n].str;
368
- div.className = '';
369
- }
370
- clearedUntilDivIdx = match.end.divIdx + 1;
371
- }
279
+ function appendText(from, to, className) {
280
+ var divIdx = from.divIdx;
281
+ var div = textDivs[divIdx];
282
+
283
+ var content = bidiTexts[divIdx].str.substring(from.offset, to.offset);
284
+ var node = document.createTextNode(content);
285
+ if (className) {
286
+ var span = document.createElement('span');
287
+ span.className = className;
288
+ span.appendChild(node);
289
+ div.appendChild(span);
290
+ return;
291
+ }
292
+ div.appendChild(node);
293
+ }
372
294
 
373
- if (PDFFindController === null || !PDFFindController.active)
374
- return;
295
+ function highlightDiv(divIdx, className) {
296
+ textDivs[divIdx].className = className;
297
+ }
375
298
 
376
- // Convert the matches on the page controller into the match format used
377
- // for the textLayer.
378
- this.matches = matches =
379
- this.convertMatches(PDFFindController === null ?
380
- [] : (PDFFindController.pageMatches[this.pageIdx] || []));
299
+ var i0 = selectedMatchIdx, i1 = i0 + 1, i;
381
300
 
382
- this.renderMatches(this.matches);
383
- };
301
+ if (highlightAll) {
302
+ i0 = 0;
303
+ i1 = matches.length;
304
+ } else if (!isSelectedPage) {
305
+ // Not highlighting all and this isn't the selected page, so do nothing.
306
+ return;
307
+ }
308
+
309
+ for (i = i0; i < i1; i++) {
310
+ var match = matches[i];
311
+ var begin = match.begin;
312
+ var end = match.end;
313
+
314
+ var isSelected = isSelectedPage && i === selectedMatchIdx;
315
+ var highlightSuffix = (isSelected ? ' selected' : '');
316
+ if (isSelected && !this.isViewerInPresentationMode) {
317
+ scrollIntoView(textDivs[begin.divIdx], { top: FIND_SCROLL_OFFSET_TOP,
318
+ left: FIND_SCROLL_OFFSET_LEFT });
319
+ }
320
+
321
+ // Match inside new div.
322
+ if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
323
+ // If there was a previous div, then add the text at the end
324
+ if (prevEnd !== null) {
325
+ appendText(prevEnd, infty);
326
+ }
327
+ // clears the divs and set the content until the begin point.
328
+ beginText(begin);
329
+ } else {
330
+ appendText(prevEnd, begin);
331
+ }
332
+
333
+ if (begin.divIdx === end.divIdx) {
334
+ appendText(begin, end, 'highlight' + highlightSuffix);
335
+ } else {
336
+ appendText(begin, infty, 'highlight begin' + highlightSuffix);
337
+ for (var n = begin.divIdx + 1; n < end.divIdx; n++) {
338
+ highlightDiv(n, 'highlight middle' + highlightSuffix);
339
+ }
340
+ beginText(end, 'highlight end' + highlightSuffix);
341
+ }
342
+ prevEnd = end;
343
+ }
344
+
345
+ if (prevEnd) {
346
+ appendText(prevEnd, infty);
347
+ }
348
+ };
349
+
350
+ this.updateMatches = function textLayerUpdateMatches() {
351
+ // Only show matches, once all rendering is done.
352
+ if (!this.renderingDone)
353
+ return;
354
+
355
+ // Clear out all matches.
356
+ var matches = this.matches;
357
+ var textDivs = this.textDivs;
358
+ var bidiTexts = this.textContent;
359
+ var clearedUntilDivIdx = -1;
360
+
361
+ // Clear out all current matches.
362
+ for (var i = 0; i < matches.length; i++) {
363
+ var match = matches[i];
364
+ var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
365
+ for (var n = begin; n <= match.end.divIdx; n++) {
366
+ var div = textDivs[n];
367
+ div.textContent = bidiTexts[n].str;
368
+ div.className = '';
369
+ }
370
+ clearedUntilDivIdx = match.end.divIdx + 1;
371
+ }
372
+
373
+ if (PDFFindController === null || !PDFFindController.active)
374
+ return;
375
+
376
+ // Convert the matches on the page controller into the match format used
377
+ // for the textLayer.
378
+ this.matches = matches =
379
+ this.convertMatches(PDFFindController === null ?
380
+ [] : (PDFFindController.pageMatches[this.pageIdx] || []));
381
+
382
+ this.renderMatches(this.matches);
383
+ };
384
384
  };
385
385