Skip to content

Commit

Permalink
#10 - create a property that host the search results' contexts (50 ch…
Browse files Browse the repository at this point in the history
…ars before and after the match)
  • Loading branch information
leojpod committed May 11, 2017
1 parent 59adc21 commit 8979cd0
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 23 deletions.
3 changes: 2 additions & 1 deletion .jscsrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"disallowSemicolons": true,
"requireSemicolons": false,
"disallowSpacesInFunction": false,
"disallowSpaceAfterObjectKeys": false
"disallowSpaceAfterObjectKeys": false,
"requireSpacesInsideObjectBrackets": false
}
115 changes: 93 additions & 22 deletions addon/components/pdf-js.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ const {
} = PDFJS

const {
A,
Component,
computed: { reads },
inject: { service: injectService },
computed,
computed: {reads},
inject: {service: injectService},
isEmpty,
observer,
run
} = Ember

function scrollToMatch (pdfViewer, match) {
let { pageIdx, matchIdx } = match
let {pageIdx, matchIdx} = match
let page = pdfViewer.getPageView(pageIdx)
let { textLayer } = page
let {textLayer} = page
if (!textLayer) {
// Ember.Logger.debug(`page ${pageIdx} not ready`)
page.div.scrollIntoView()
Expand All @@ -38,16 +41,37 @@ function scrollToMatch (pdfViewer, match) {
scrollToMatch(pdfViewer, match)
}, 50)
} else {
let [{ begin: { divIdx } }] = textLayer.convertMatches([matchIdx], [1])
let [{begin: {divIdx}}] = textLayer.convertMatches([matchIdx], [1])
textLayer.textDivs[divIdx].scrollIntoView()
// debugger
}
}
}

function getResultContextForPage (pdfViewer, pageIdx, currentMatchIdx, pageMatches, searchResultContextLength) {
let pageTextPromise = pdfViewer.getPageTextContent(pageIdx)
.then(({items}) => items.map((item) => item.str).join(' '))
/* this will cause some shifting:
- we are adding extra space compare to what the findController is doing
but it is required since some pdf don't add space at the end of their text divs
and we would end up with some text missing spaces and "lookingLikethat"
*/
return pageMatches.map((matchIdx, idx) => {
return {
context: pageTextPromise.then((text) => {
let startPosition = matchIdx - (searchResultContextLength * 0.5)
startPosition = (startPosition > 0) ? startPosition : 0
return text.substr(startPosition, searchResultContextLength)
}),
matchIdx: idx + currentMatchIdx,
pageIdx
}
})
}

export default Component.extend({
layout,
classNames: [ 'pdf-js' ],
classNames: ['pdf-js'],
// Service
pdfJs: injectService('pdf-js'),
pdfLib: reads('pdfJs.PDFJS'),
Expand All @@ -71,14 +95,15 @@ export default Component.extend({

// privates
_topMargin: 10,
_searchResultContextLength: 100,
_container: undefined,

// components
toolbarComponent: 'pdf-js-toolbar',

// initialization
didInsertElement () {
let container = this.element.getElementsByClassName('pdfViewerContainer')[0]
let container = this.element.getElementsByClassName('pdfViewerContainer')[0]
this.set('_container', container)
let pdfLinkService = new PDFLinkService()
this.set('pdfLinkService', pdfLinkService)
Expand All @@ -103,34 +128,38 @@ export default Component.extend({
pdfViewer.currentScaleValue = 'page-fit'

// setup the event listening to synchronise with pdf.js' modifications
let self = this
pdfViewer.eventBus.on('pagechange', function (evt) {
pdfViewer.eventBus.on('pagechange', (evt) => {
let page = evt.pageNumber
run(function () {
self.set('pdfPage', page)
run(() => {
this.set('pdfPage', page)
})
})

pdfFindController.onUpdateResultsCount = function (total) {
run(function () {
self.set('matchTotal', total)
pdfFindController.onUpdateResultsCount = (total) => {
run(() => {
this.set('matchTotal', total)
})
}
pdfFindController.onUpdateState = function (state/*, previous, total*/) {
run(function () {
pdfFindController.onUpdateState = (state/*, previous, total*/) => {
run(() => {
if (state === 3) {
this.set('isSearchPending', true)
return
}
if (state !== 0 && state !== 2) { // 0 <=> search found something ; 2 <=> wrapped
return
}
let { pageIdx, matchIdx } = pdfFindController.selected
this.set('isSearchPending', false)
let {pageIdx, matchIdx} = pdfFindController.selected
if (matchIdx !== -1 || pageIdx !== -1) {
let { pageMatches } = pdfFindController
let {pageMatches} = pdfFindController
let idx = matchIdx + 1
for (let i = 0; i < pageIdx; i++) {
idx += pageMatches[i].length
}
let match = pdfFindController.pageMatches[pageIdx][matchIdx]
self.set('currentMatch', match)
self.set('currentMatchIdx', idx)
this.set('currentMatch', match)
this.set('currentMatchIdx', idx)
}
})
}
Expand All @@ -144,6 +173,49 @@ export default Component.extend({
pdfObserver: observer('pdf', function () {
this.send('load')
}),
// we use an observer to setup this property to provide some sort of caching...
searchResultsObserver: observer('isSearchPending', 'matchTotal', function () {
let pdfFindController = this.get('pdfFindController')
let pdfViewer = this.get('pdfViewer')
let {pageMatches} = pdfFindController
if (this.get('isSearchPending')) {
this.set('searchResultContextsPerPage', A())
return
}
// else
let searchResultContextsPerPage = this.get('searchResultContextsPerPage')
let length = searchResultContextsPerPage.get('length')
if (length >= pageMatches.length) {
// no new matches yet let's wait
return
}
let searchResultContextLength = this.get('_searchResultContextLength')
let currentMatchIdx = pageMatches.slice(0, length).reduce((totalMatches, formattedContext) => totalMatches + formattedContext.length, 0)
console.log('currentLength -> ', length)
for (let i = length; i < pageMatches.length; i++) {
if (isEmpty(pageMatches[i])) {
searchResultContextsPerPage.pushObject([])
} else {
searchResultContextsPerPage.pushObject(getResultContextForPage(pdfViewer, i, currentMatchIdx, pageMatches[i], searchResultContextLength))
}
currentMatchIdx += pageMatches[i].length
}
console.log('searchResultContextsPerPage -> ', searchResultContextsPerPage.length)
// this.set('searchResultContextsPerPage', searchResultContextsPerPage)
}),

// computed
searchResultContexts: computed('searchResultContextsPerPage.[]', function () {
let searchResultContextsPerPage = this.get('searchResultContextsPerPage')
if (isEmpty(searchResultContextsPerPage)) {
return []
} // else
console.log('searchResultContextsPerPage -> ', searchResultContextsPerPage)
return searchResultContextsPerPage.reduce(
(joinedContexts, contextsOfPage) => joinedContexts.concat(contextsOfPage),
[]
)
}),

// actions:
actions: {
Expand Down Expand Up @@ -215,8 +287,7 @@ export default Component.extend({
pdfViewer.getPageView(pdfLinkService.page - 1).div.scrollIntoView()
},
zoom () {
throw 'not implemented yet'
throw new Error('not implemented yet')
}
}

})
7 changes: 7 additions & 0 deletions addon/templates/components/pdf-js.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@
currentMatch=currentMatch
currentMatchIdx=currentMatchIdx
matchTotal=matchTotal
searchResultContexts=searchResultContexts
}}
<div class="pdfViewerContainer">
<div class="pdfViewer">
</div>
</div>
{{!--
{{log 'searchResults -> ' searchResultContexts}}
{{#each searchResultContexts as |context|}}
{{log 'context -> ' context}}
{{/each}}
--}}

0 comments on commit 8979cd0

Please sign in to comment.