| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- import _ from 'lodash'
- /* eslint-disable
- handle-callback-err,
- max-len,
- new-cap,
- no-return-assign,
- no-sequences,
- no-unused-vars,
- */
- // TODO: This file was created by bulk-decaffeinate.
- // Fix any style issues and re-enable lint.
- /*
- * decaffeinate suggestions:
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS103: Rewrite code to no longer use __guard__
- * DS104: Avoid inline assignments
- * DS207: Consider shorter variations of null checks
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- import App from '../../../base'
- import pdfTextLayer from './pdfTextLayer'
- import pdfAnnotations from './pdfAnnotations'
- import pdfHighlights from './pdfHighlights'
- import pdfRenderer from './pdfRenderer'
- import pdfPage from './pdfPage'
- import pdfSpinner from './pdfSpinner'
- App.controller('pdfViewerController', function(
- $scope,
- $q,
- $timeout,
- PDFRenderer,
- $element,
- pdfHighlights,
- pdfSpinner
- ) {
- this.load = function() {
- // $scope.pages = []
- // Ensure previous document is torn down before loading the next one (to
- // prevent race conditions)
- const documentTearDown =
- $scope.document != null ? $scope.document.destroy() : Promise.resolve()
- return documentTearDown.then(() => {
- $scope.loadCount = $scope.loadCount != null ? $scope.loadCount + 1 : 1
- // TODO need a proper url manipulation library to add to query string
- let url = $scope.pdfSrc
- // add 'pdfng=true' to show that we are using the angular pdfjs viewer
- const queryStringExists = /\?/.test(url)
- url = url + (!queryStringExists ? '?' : '&') + 'pdfng=true'
- // for isolated compiles, load the pdf on-demand because nobody will overwrite it
- const onDemandLoading = true
- $scope.document = new PDFRenderer(url, {
- scale: 1,
- disableAutoFetch: onDemandLoading ? true : undefined,
- navigateFn(ref) {
- // this function captures clicks on the annotation links
- $scope.navigateTo = ref
- return $scope.$apply()
- },
- progressCallback(progress) {
- return $scope.$emit('progress', progress)
- },
- loadedCallback() {
- return $scope.$emit('loaded')
- },
- errorCallback(error) {
- if (window.Raven) {
- // MissingPDFException is "expected" as the pdf file can be on a
- // CLSI server that has been cycled out.
- // Currently, there is NO error handling to handle this situation,
- // but we plan to add this in the future
- // (https://github.com/overleaf/issues/issues/2985) and this error
- // is causing noise in Sentry so ignore it
- if (!error.name === 'MissingPDFException') {
- window.Raven.captureMessage(`pdfng error ${error}`)
- }
- }
- return $scope.$emit('pdf:error', error)
- },
- pageSizeChangeCallback(pageNum, deltaH) {
- return $scope.$broadcast('pdf:page:size-change', pageNum, deltaH)
- }
- })
- // we will have all the main information needed to start display
- // after the following promise is resolved
- $scope.loaded = $q
- .all({
- numPages: $scope.document.getNumPages(),
- // get size of first page as default @ scale 1
- pdfViewport: $scope.document.getPdfViewport(1, 1)
- })
- .then(function(result) {
- $scope.pdfViewport = result.pdfViewport
- $scope.pdfPageSize = [
- result.pdfViewport.height,
- result.pdfViewport.width
- ]
- // console.log 'resolved q.all, page size is', result
- $scope.$emit('loaded')
- return ($scope.numPages = result.numPages)
- })
- .catch(function(error) {
- $scope.$emit('pdf:error', error)
- return $q.reject(error)
- })
- return $scope.loaded
- })
- }
- this.setScale = (scale, containerHeight, containerWidth) =>
- $scope.loaded
- .then(function() {
- let numScale
- if (scale == null) {
- scale = {}
- }
- if (containerHeight === 0 || containerWidth === 0) {
- numScale = 1
- } else if (scale.scaleMode === 'scale_mode_fit_width') {
- // TODO make this dynamic
- numScale = (containerWidth - 40) / $scope.pdfPageSize[1]
- } else if (scale.scaleMode === 'scale_mode_fit_height') {
- // TODO magic numbers for jquery ui layout
- numScale = (containerHeight - 20) / $scope.pdfPageSize[0]
- } else if (scale.scaleMode === 'scale_mode_value') {
- numScale = scale.scale
- } else if (scale.scaleMode === 'scale_mode_auto') {
- // TODO
- } else {
- scale.scaleMode = 'scale_mode_fit_width'
- numScale = (containerWidth - 40) / $scope.pdfPageSize[1]
- }
- // TODO
- $scope.scale.scale = numScale
- $scope.document.setScale(numScale)
- return ($scope.defaultPageSize = [
- numScale * $scope.pdfPageSize[0],
- numScale * $scope.pdfPageSize[1]
- ])
- })
- // console.log 'in setScale result', $scope.scale.scale, $scope.defaultPageSize
- .catch(function(error) {
- $scope.$emit('pdf:error', error)
- return $q.reject(error)
- })
- this.redraw = function(position) {
- // console.log 'in redraw'
- // console.log 'reseting pages array for', $scope.numPages
- $scope.pages = __range__(0, $scope.numPages - 1, true).map(i => ({
- pageNum: i + 1
- }))
- if (position != null && position.page != null) {
- // console.log 'position is', position.page, position.offset
- // console.log 'setting current page', position.page
- let pagenum = position.page
- if (pagenum > $scope.numPages - 1) {
- pagenum = $scope.numPages - 1
- }
- $scope.pages[pagenum].current = true
- return ($scope.pages[pagenum].position = position)
- }
- }
- this.zoomIn = function() {
- // console.log 'zoom in'
- const newScale = $scope.scale.scale * 1.2
- return ($scope.forceScale = {
- scaleMode: 'scale_mode_value',
- scale: newScale
- })
- }
- this.zoomOut = function() {
- // console.log 'zoom out'
- const newScale = $scope.scale.scale / 1.2
- return ($scope.forceScale = {
- scaleMode: 'scale_mode_value',
- scale: newScale
- })
- }
- this.fitWidth = () =>
- // console.log 'fit width'
- ($scope.forceScale = { scaleMode: 'scale_mode_fit_width' })
- this.fitHeight = () =>
- // console.log 'fit height'
- ($scope.forceScale = { scaleMode: 'scale_mode_fit_height' })
- this.checkPosition = () =>
- // console.log 'check position'
- ($scope.forceCheck = ($scope.forceCheck || 0) + 1)
- this.showRandomHighlights = () =>
- // console.log 'show highlights'
- ($scope.highlights = [
- {
- page: 3,
- h: 100,
- v: 100,
- height: 30,
- width: 200
- }
- ])
- // we work with (pagenumber, % of height down page from top)
- // pdfListView works with (pagenumber, vertical position up page from
- // bottom measured in pts)
- this.getPdfPosition = function() {
- // console.log 'in getPdfPosition'
- let canvasOffset, pdfOffset, viewport
- let topPageIdx = 0
- let topPage = $scope.pages[0]
- // find first visible page
- const visible = $scope.pages.some(function(page, i) {
- if (page.visible) {
- let ref
- return ([topPageIdx, topPage] = Array.from((ref = [i, page]))), ref
- }
- })
- if (visible && topPage.element != null) {
- // console.log 'found it', topPageIdx
- } else {
- // console.log 'CANNOT FIND TOP PAGE'
- return
- }
- // console.log 'top page is', topPage.pageNum, topPage.elemTop, topPage.elemBottom, topPage
- const { top } = topPage.element.offset()
- const bottom = top + topPage.element.innerHeight()
- const viewportTop = $element.offset().top
- const viewportBottom = viewportTop + $element.height()
- const topVisible = top >= viewportTop && top < viewportBottom
- const someContentVisible = top < viewportTop && bottom > viewportTop
- // console.log 'in PdfListView', top, topVisible, someContentVisible, viewportTop
- if (topVisible) {
- canvasOffset = 0
- } else if (someContentVisible) {
- canvasOffset = viewportTop - top
- } else {
- canvasOffset = null
- }
- // console.log 'pdfListview position = ', canvasOffset
- // instead of using promise, check if size is known and revert to
- // default otherwise
- // console.log 'looking up viewport', topPage.viewport, $scope.pdfViewport
- if (topPage.viewport) {
- ;({ viewport } = topPage)
- pdfOffset = viewport.convertToPdfPoint(0, canvasOffset)
- } else {
- // console.log 'WARNING: had to default to global page size'
- viewport = $scope.pdfViewport
- const scaledOffset = canvasOffset / $scope.scale.scale
- pdfOffset = viewport.convertToPdfPoint(0, scaledOffset)
- }
- // console.log 'converted to offset = ', pdfOffset
- const newPosition = {
- page: topPageIdx,
- offset: { top: pdfOffset[1], left: 0 },
- pageSize: { height: viewport.viewBox[3], width: viewport.viewBox[2] }
- }
- return newPosition
- }
- this.computeOffset = function(page, position) {
- // console.log 'computing offset for', page, position
- const { element } = page
- // console.log 'element =', $(element), 'parent =', $(element).parent()
- const t1 = __guard__($(element).offset(), x => x.top)
- const t2 = __guard__(
- $(element)
- .parent()
- .offset(),
- x1 => x1.top
- )
- if (!(t1 != null && t2 != null)) {
- return $q((resolve, reject) => reject('elements destroyed'))
- }
- const pageTop =
- $(element).offset().top -
- $(element)
- .parent()
- .offset().top
- // console.log('top of page scroll is', pageTop, 'vs', page.elemTop)
- // console.log('inner height is', $(element).innerHeight())
- const currentScroll = $(element)
- .parent()
- .scrollTop()
- const { offset } = position
- // convert offset to pixels
- return $scope.document
- .getPdfViewport(page.pageNum)
- .then(function(viewport) {
- page.viewport = viewport
- const pageOffset = viewport.convertToViewportPoint(
- offset.left,
- offset.top
- )
- // if the passed-in position doesn't have the page height/width add them now
- if (position.pageSize == null) {
- position.pageSize = {
- height: viewport.viewBox[3],
- width: viewport.viewBox[2]
- }
- }
- // console.log 'addition offset =', pageOffset
- // console.log 'total', pageTop + pageOffset[1]
- return Math.round(pageTop + pageOffset[1] + currentScroll)
- }) // # 10 is margin
- }
- this.setPdfPosition = function(page, position) {
- // console.log 'required pdf Position is', position
- return this.computeOffset(page, position).then(function(offset) {
- return $scope.$apply(() => {
- $scope.pleaseScrollTo = offset
- $scope.position = position
- })
- })
- }
- return this
- })
- export default App.directive('pdfViewer', ($q, $timeout, pdfSpinner) => ({
- controller: 'pdfViewerController',
- controllerAs: 'ctrl',
- scope: {
- pdfSrc: '=',
- highlights: '=',
- position: '=',
- scale: '=',
- pleaseJumpTo: '='
- },
- template: `\
- <div data-pdf-page class='pdf-page-container page-container' ng-repeat='page in pages'></div>\
- `,
- link(scope, element, attrs, ctrl) {
- // console.log 'in pdfViewer element is', element
- // console.log 'attrs', attrs
- const spinner = new pdfSpinner()
- let layoutReady = $q.defer()
- layoutReady.notify('waiting for layout')
- layoutReady.promise.then(function() {})
- // console.log 'layoutReady was resolved'
- const renderVisiblePages = function() {
- const visiblePages = getVisiblePages()
- const pages = getExtraPages(visiblePages)
- return scope.document.renderPages(pages)
- }
- var getVisiblePages = function() {
- const top = element[0].scrollTop
- const bottom = top + element[0].clientHeight
- const visiblePages = _.filter(scope.pages, function(page) {
- if (page.element == null) {
- return false
- }
- const pageElement = page.element[0]
- const pageTop = pageElement.offsetTop
- const pageBottom = pageTop + pageElement.clientHeight
- page.visible = pageTop < bottom && pageBottom > top
- return page.visible
- })
- return visiblePages
- }
- var getExtraPages = function(visiblePages) {
- const extra = []
- if (visiblePages.length > 0) {
- const firstVisiblePage = visiblePages[0].pageNum
- const firstVisiblePageIdx = firstVisiblePage - 1
- const len = visiblePages.length
- const lastVisiblePage = visiblePages[len - 1].pageNum
- const lastVisiblePageIdx = lastVisiblePage - 1
- // first page after
- if (lastVisiblePageIdx + 1 < scope.pages.length) {
- extra.push(scope.pages[lastVisiblePageIdx + 1])
- }
- // page before
- if (firstVisiblePageIdx > 0) {
- extra.push(scope.pages[firstVisiblePageIdx - 1])
- }
- // second page after
- if (lastVisiblePageIdx + 2 < scope.pages.length) {
- extra.push(scope.pages[lastVisiblePageIdx + 2])
- }
- }
- return visiblePages.concat(extra)
- }
- let rescaleTimer = null
- const queueRescale = function(scale) {
- // console.log 'call to queueRescale'
- if (rescaleTimer != null || layoutTimer != null || elementTimer != null) {
- return
- }
- // console.log 'adding to rescale queue'
- return (rescaleTimer = setTimeout(function() {
- doRescale(scale)
- return (rescaleTimer = null)
- }, 0))
- }
- let spinnerTimer = null
- var doRescale = function(scale) {
- // console.log 'doRescale', scale
- if (scale == null) {
- return
- }
- const origposition = angular.copy(scope.position)
- // console.log 'origposition', origposition
- if (spinnerTimer == null) {
- spinnerTimer = setTimeout(function() {
- spinner.add(element)
- return (spinnerTimer = null)
- }, 100)
- }
- return layoutReady.promise.then(function(parentSize) {
- const [h, w] = Array.from(parentSize)
- // console.log 'in promise', h, w
- return ctrl
- .setScale(scale, h, w)
- .then(() =>
- // console.log 'in setscale then', scale, h, w
- scope.$evalAsync(function() {
- if (spinnerTimer) {
- clearTimeout(spinnerTimer)
- } else {
- spinner.remove(element)
- }
- // stop displaying the text layer
- element.removeClass('pdfjs-viewer-show-text')
- ctrl.redraw(origposition)
- $timeout(renderVisiblePages)
- return (scope.loadSuccess = true)
- })
- )
- .catch(error => scope.$emit('pdf:error', error))
- })
- }
- var elementTimer = null
- var updateLayout = function() {
- // if element is zero-sized keep checking until it is ready
- // console.log 'checking element ready', element.height(), element.width()
- if (element.height() === 0 || element.width() === 0) {
- if (elementTimer != null) {
- return
- }
- return (elementTimer = setTimeout(function() {
- elementTimer = null
- return updateLayout()
- }, 1000))
- } else {
- scope.parentSize = [element.innerHeight(), element.innerWidth()]
- // console.log 'resolving layoutReady with', scope.parentSize
- return $timeout(function() {
- layoutReady.resolve(scope.parentSize)
- return scope.$emit('flash-controls')
- })
- }
- }
- var layoutTimer = null
- const queueLayout = function() {
- // console.log 'call to queue layout'
- if (layoutTimer != null) {
- return
- }
- // console.log 'added to queue layoyt'
- layoutReady = $q.defer()
- return (layoutTimer = setTimeout(function() {
- // console.log 'calling update layout'
- updateLayout()
- // console.log 'setting layout timer to null'
- return (layoutTimer = null)
- }, 0))
- }
- queueLayout()
- // scope.$on 'layout:pdf:view', (e, args) ->
- // console.log 'pdf view change', element, e, args
- // queueLayout()
- scope.$on('layout:main:resize', () =>
- // console.log 'GOT LAYOUT-MAIN-RESIZE EVENT'
- queueLayout()
- )
- scope.$on('layout:pdf:resize', () =>
- // FIXME we get this event twice
- // also we need to start a new layout when we get it
- // console.log 'GOT LAYOUT-PDF-RESIZE EVENT'
- queueLayout()
- )
- scope.$on('pdf:error', function(event, error) {
- if (error.name === 'RenderingCancelledException') {
- return
- }
- // check if too many retries or file is missing
- const message = (error != null ? error.message : undefined) || error
- if (
- scope.loadCount > 3 ||
- /^Missing PDF/i.test(message) ||
- /^loading/i.test(message)
- ) {
- scope.$emit('pdf:error:display')
- return
- }
- if (scope.loadSuccess) {
- return ctrl
- .load()
- .then(
- () =>
- // trigger a redraw
- (scope.scale = angular.copy(scope.scale))
- )
- .catch(error => scope.$emit('pdf:error:display'))
- } else {
- scope.$emit('pdf:error:display')
- }
- })
- scope.$on('pdf:page:size-change', function(event, pageNum, delta) {
- // console.log 'page size change event', pageNum, delta
- const origposition = angular.copy(scope.position)
- // console.log 'orig position', JSON.stringify(origposition)
- if (
- origposition != null &&
- pageNum - 1 < origposition.page &&
- delta !== 0
- ) {
- const currentScrollTop = element.scrollTop()
- // console.log 'adjusting scroll from', currentScrollTop, 'by', delta
- scope.adjustingScroll = true
- return element.scrollTop(currentScrollTop + delta)
- }
- })
- element.on('mousedown', function(e) {
- // We're checking that the event target isn't the directive root element
- // to make sure that the click was within a PDF page - no point in showing
- // the text layer when the click is outside.
- // If the user clicks a PDF page, the mousedown target will be the canvas
- // element (or the text layer one). Alternatively, if the event target is
- // the root element, we can assume that the user has clicked either the
- // grey background area or the scrollbars.
- if (e.target !== element[0] && !_hasSelection()) {
- element.addClass('pdfjs-viewer-show-text')
- return _setMouseUpHandler()
- }
- })
- let mouseUpHandler = null // keep track of the handler to avoid adding multiple times
- var _setMouseUpHandler = function() {
- if (mouseUpHandler == null) {
- return (mouseUpHandler = $(document.body).one(
- 'mouseup',
- _handleSelectionMouseUp
- ))
- }
- }
- var _handleSelectionMouseUp = function() {
- mouseUpHandler = null // reset handler, has now fired
- window.setTimeout(function() {
- const removedClass = _removeClassIfNoSelection()
- // if we still have a selection we need to keep the handler going
- if (!removedClass) {
- return _setMouseUpHandler()
- }
- }, 10)
- return true
- }
- var _removeClassIfNoSelection = function() {
- if (_hasSelection()) {
- return false // didn't remove the text layer
- } else {
- element.removeClass('pdfjs-viewer-show-text')
- return true
- }
- }
- var _hasSelection = function() {
- const selection =
- typeof window.getSelection === 'function'
- ? window.getSelection()
- : undefined
- // check the selection collapsed state in preference to
- // using selection.toString() as the latter is "" when
- // the selection is hidden (e.g. while viewing logs)
- return (
- selection != null &&
- _isSelectionWithinPDF(selection) &&
- !selection.isCollapsed
- )
- }
- var _isSelectionWithinPDF = function(selection) {
- if (selection.rangeCount === 0) {
- return false
- }
- const selectionAncestorNode = selection.getRangeAt(0)
- .commonAncestorContainer
- return (
- element.find(selectionAncestorNode).length > 0 ||
- element.is(selectionAncestorNode)
- )
- }
- element.on('scroll', function() {
- // console.log 'scroll event', element.scrollTop(), 'adjusting?', scope.adjustingScroll
- // scope.scrollPosition = element.scrollTop()
- if (scope.adjustingScroll) {
- renderVisiblePages()
- scope.adjustingScroll = false
- return
- }
- if (scope.scrollHandlerTimeout) {
- clearTimeout(scope.scrollHandlerTimeout)
- }
- return (scope.scrollHandlerTimeout = setTimeout(scrollHandler, 25))
- })
- var scrollHandler = function() {
- renderVisiblePages()
- const newPosition = ctrl.getPdfPosition()
- if (newPosition != null) {
- scope.position = newPosition
- }
- return (scope.scrollHandlerTimeout = null)
- }
- scope.$watch('pdfSrc', function(newVal, oldVal) {
- // console.log 'loading pdf', newVal, oldVal
- if (newVal == null) {
- return
- }
- scope.loadCount = 0 // new pdf, so reset load count
- scope.loadSuccess = false
- return ctrl
- .load()
- .then(
- () =>
- // trigger a redraw
- (scope.scale = angular.copy(scope.scale))
- )
- .catch(error => scope.$emit('pdf:error', error))
- })
- scope.$watch('scale', function(newVal, oldVal) {
- // no need to set scale when initialising, done in pdfSrc
- if (newVal === oldVal) {
- return
- }
- // console.log 'XXX calling Setscale in scale watch'
- return queueRescale(newVal)
- })
- scope.$watch('forceScale', function(newVal, oldVal) {
- // console.log 'got change in numscale watcher', newVal, oldVal
- if (newVal == null) {
- return
- }
- return queueRescale(newVal)
- })
- // scope.$watch 'position', (newVal, oldVal) ->
- // console.log 'got change in position watcher', newVal, oldVal
- scope.$watch('forceCheck', function(newVal, oldVal) {
- // console.log 'forceCheck', newVal, oldVal
- if (newVal == null) {
- return
- }
- scope.adjustingScroll = true // temporarily disable scroll
- return queueRescale(scope.scale)
- })
- scope.$watch(
- 'parentSize',
- function(newVal, oldVal) {
- // console.log 'XXX in parentSize watch', newVal, oldVal
- // if newVal == oldVal
- // console.log 'returning because old and new are the same'
- // return
- // return unless oldVal?
- // console.log 'XXX calling setScale in parentSize watcher'
- if (newVal == null) {
- return
- }
- return queueRescale(scope.scale)
- },
- true
- )
- // scope.$watch 'elementWidth', (newVal, oldVal) ->
- // console.log '*** watch INTERVAL element width is', newVal, oldVal
- scope.$watch('pleaseScrollTo', function(newVal, oldVal) {
- // console.log 'got request to ScrollTo', newVal, 'oldVal', oldVal
- if (newVal == null) {
- return
- }
- scope.adjustingScroll = true // temporarily disable scroll
- // handler while we reposition
- $(element).scrollTop(newVal)
- return (scope.pleaseScrollTo = undefined)
- })
- scope.$watch('pleaseJumpTo', function(newPosition, oldPosition) {
- // console.log 'in pleaseJumpTo', newPosition, oldPosition
- if (newPosition == null) {
- return
- }
- return ctrl.setPdfPosition(scope.pages[newPosition.page - 1], newPosition)
- })
- scope.$watch('navigateTo', function(newVal, oldVal) {
- if (newVal == null) {
- return
- }
- // console.log 'got request to navigate to', newVal, 'oldVal', oldVal
- scope.navigateTo = undefined
- // console.log 'navigate to', newVal
- // console.log 'look up page num'
- return scope.document.getDestination(newVal.dest).then(r =>
- // console.log 'need to go to', r
- // console.log 'page ref is', r[0]
- scope.document.getPageIndex(r[0]).then(function(pidx) {
- // console.log 'page num is', pidx
- const page = scope.pages[pidx]
- return scope.document
- .getPdfViewport(page.pageNum)
- .then(function(viewport) {
- // console.log 'got viewport', viewport
- const coords = viewport.convertToViewportPoint(r[2], r[3])
- // console.log 'viewport position', coords
- // console.log 'r is', r, 'r[1]', r[1], 'r[1].name', r[1].name
- if (r[1].name === 'XYZ') {
- // console.log 'XYZ:', r[2], r[3]
- const newPosition = {
- page: pidx,
- offset: { top: r[3], left: r[2] }
- }
- return ctrl.setPdfPosition(scope.pages[pidx], newPosition)
- }
- })
- })
- )
- }) // XXX?
- scope.$watch('highlights', function(areas) {
- // console.log 'got HIGHLIGHTS in pdfViewer', areas
- if (areas == null) {
- return
- }
- // console.log 'areas are', areas
- const highlights = Array.from(areas || []).map(area => ({
- page: area.page - 1,
- highlight: {
- left: area.h,
- top: area.v,
- height: area.height,
- width: area.width
- }
- }))
- // console.log 'highlights', highlights
- if (!highlights.length) {
- return
- }
- scope.$broadcast('pdf:highlights', areas)
- const first = highlights[0]
- // switching between split and full pdf views can cause
- // highlights to appear before rendering
- if (!scope.pages) {
- return // ignore highlight scroll if still rendering
- }
- const pageNum =
- scope.pages[first.page] != null
- ? scope.pages[first.page].pageNum
- : undefined
- if (pageNum == null) {
- return // ignore highlight scroll if page not found
- }
- // use a visual offset of 72pt to match the offset in PdfController syncToCode
- return scope.document.getPdfViewport(pageNum).then(function(viewport) {
- const position = {
- page: first.page,
- offset: {
- left: first.highlight.left,
- top:
- viewport.viewBox[3] -
- first.highlight.top +
- first.highlight.height +
- 72
- }
- }
- return ctrl.setPdfPosition(scope.pages[first.page], position)
- })
- })
- return scope.$on('$destroy', function() {
- // console.log 'handle pdfng directive destroy'
- if (elementTimer != null) {
- clearTimeout(elementTimer)
- }
- if (layoutTimer != null) {
- clearTimeout(layoutTimer)
- }
- if (rescaleTimer != null) {
- clearTimeout(rescaleTimer)
- }
- if (spinnerTimer != null) {
- return clearTimeout(spinnerTimer)
- }
- })
- }
- }))
- function __range__(left, right, inclusive) {
- let range = []
- let ascending = left < right
- let end = !inclusive ? right : ascending ? right + 1 : right - 1
- for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
- range.push(i)
- }
- return range
- }
- function __guard__(value, transform) {
- return typeof value !== 'undefined' && value !== null
- ? transform(value)
- : undefined
- }
|