mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
moved new pdf viewer under base App module
This commit is contained in:
parent
175de30967
commit
ff04e1662a
8 changed files with 841 additions and 829 deletions
|
@ -2,13 +2,6 @@ define [
|
|||
"libs"
|
||||
"modules/recursionHelper"
|
||||
"utils/underscore"
|
||||
# TODo move these into a separate definition
|
||||
"ide/pdfng/directives/pdfViewer"
|
||||
"ide/pdfng/directives/pdfPage"
|
||||
"ide/pdfng/directives/pdfRenderer"
|
||||
"ide/pdfng/directives/pdfTextLayer"
|
||||
"ide/pdfng/directives/pdfAnnotations"
|
||||
"ide/pdfng/directives/pdfHighlights"
|
||||
], () ->
|
||||
App = angular.module("SharelatexApp", [
|
||||
"ui.bootstrap"
|
||||
|
@ -18,7 +11,6 @@ define [
|
|||
"underscore"
|
||||
"ngSanitize"
|
||||
"ipCookie"
|
||||
"pdfViewerApp"
|
||||
])
|
||||
|
||||
return App
|
||||
|
|
|
@ -1,42 +1,44 @@
|
|||
app = angular.module 'pdfAnnotations', []
|
||||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
# App = angular.module 'pdfAnnotations', []
|
||||
App.factory 'pdfAnnotations', [ () ->
|
||||
class pdfAnnotations
|
||||
|
||||
app.factory 'pdfAnnotations', [ () ->
|
||||
class pdfAnnotations
|
||||
@EXTERNAL_LINK_TARGET = "_blank";
|
||||
|
||||
@EXTERNAL_LINK_TARGET = "_blank";
|
||||
constructor: (options) ->
|
||||
@annotationsLayerDiv = options.annotations;
|
||||
@viewport = options.viewport
|
||||
@navigateFn = options.navigateFn
|
||||
|
||||
constructor: (options) ->
|
||||
@annotationsLayerDiv = options.annotations;
|
||||
@viewport = options.viewport
|
||||
@navigateFn = options.navigateFn
|
||||
setAnnotations: (annotations) ->
|
||||
for annotation in annotations
|
||||
switch annotation.subtype
|
||||
when 'Link' then @addLink(annotation);
|
||||
when 'Text' then continue
|
||||
|
||||
setAnnotations: (annotations) ->
|
||||
for annotation in annotations
|
||||
switch annotation.subtype
|
||||
when 'Link' then @addLink(annotation);
|
||||
when 'Text' then continue
|
||||
addLink: (link) ->
|
||||
element = @buildLinkElementFromRect(link.rect);
|
||||
@setLinkTarget(element, link);
|
||||
@annotationsLayerDiv.appendChild(element);
|
||||
|
||||
addLink: (link) ->
|
||||
element = @buildLinkElementFromRect(link.rect);
|
||||
@setLinkTarget(element, link);
|
||||
@annotationsLayerDiv.appendChild(element);
|
||||
buildLinkElementFromRect: (rect) ->
|
||||
rect = @viewport.convertToViewportRectangle(rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
element = document.createElement("a");
|
||||
element.style.left = Math.floor(rect[0]) + 'px';
|
||||
element.style.top = Math.floor(rect[1]) + 'px';
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
element
|
||||
|
||||
buildLinkElementFromRect: (rect) ->
|
||||
rect = @viewport.convertToViewportRectangle(rect);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
element = document.createElement("a");
|
||||
element.style.left = Math.floor(rect[0]) + 'px';
|
||||
element.style.top = Math.floor(rect[1]) + 'px';
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
element
|
||||
|
||||
setLinkTarget: (element, link) ->
|
||||
if link.url
|
||||
element.href = link.url;
|
||||
element.target = @EXTERNAL_LINK_TARGET;
|
||||
else if (link.dest)
|
||||
element.href = "#" + link.dest;
|
||||
element.onclick = (e) =>
|
||||
@navigateFn link
|
||||
]
|
||||
setLinkTarget: (element, link) ->
|
||||
if link.url
|
||||
element.href = link.url;
|
||||
element.target = @EXTERNAL_LINK_TARGET;
|
||||
else if (link.dest)
|
||||
element.href = "#" + link.dest;
|
||||
element.onclick = (e) =>
|
||||
@navigateFn link
|
||||
]
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
app = angular.module 'pdfHighlights', []
|
||||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
#app = angular.module 'pdfHighlights', []
|
||||
|
||||
app.factory 'pdfHighlights', [ () ->
|
||||
class pdfHighlights
|
||||
App.factory 'pdfHighlights', [ () ->
|
||||
class pdfHighlights
|
||||
|
||||
constructor: (options) ->
|
||||
@highlightsLayerDiv = options.highlights[0]
|
||||
@highlightElements = []
|
||||
constructor: (options) ->
|
||||
@highlightsLayerDiv = options.highlights[0]
|
||||
@highlightElements = []
|
||||
|
||||
addHighlight: (viewport, left, top, width, height) ->
|
||||
rect = viewport.convertToViewportRectangle([left, top, left + width, top + height])
|
||||
rect = PDFJS.Util.normalizeRect(rect)
|
||||
element = document.createElement("div")
|
||||
element.style.left = Math.floor(rect[0]) + 'px'
|
||||
element.style.top = Math.floor(rect[1]) + 'px'
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px'
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px'
|
||||
@highlightElements.push(element)
|
||||
@highlightsLayerDiv.appendChild(element)
|
||||
element
|
||||
addHighlight: (viewport, left, top, width, height) ->
|
||||
rect = viewport.convertToViewportRectangle([left, top, left + width, top + height])
|
||||
rect = PDFJS.Util.normalizeRect(rect)
|
||||
element = document.createElement("div")
|
||||
element.style.left = Math.floor(rect[0]) + 'px'
|
||||
element.style.top = Math.floor(rect[1]) + 'px'
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px'
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px'
|
||||
@highlightElements.push(element)
|
||||
@highlightsLayerDiv.appendChild(element)
|
||||
element
|
||||
|
||||
clearHighlights: () ->
|
||||
for h in @highlightElements
|
||||
h.remove()
|
||||
@highlightElements = []
|
||||
]
|
||||
clearHighlights: () ->
|
||||
for h in @highlightElements
|
||||
h.remove()
|
||||
@highlightElements = []
|
||||
]
|
||||
|
|
|
@ -1,24 +1,12 @@
|
|||
define [
|
||||
"base"
|
||||
"ide/pdfng/directives/pdfTextLayer"
|
||||
"ide/pdfng/directives/pdfAnnotations"
|
||||
"ide/pdfng/directives/pdfHighlights"
|
||||
"ide/pdfng/directives/pdfRenderer"
|
||||
"ide/pdfng/directives/pdfPage"
|
||||
"ide/pdfng/directives/pdfViewer"
|
||||
"libs/pdfjs-1.0.712/pdf"
|
||||
"text!libs/pdfListView/TextLayer.css"
|
||||
"text!libs/pdfListView/AnnotationsLayer.css"
|
||||
"text!libs/pdfListView/HighlightsLayer.css"
|
||||
], (
|
||||
App
|
||||
pdfViewer
|
||||
pdfPage
|
||||
pdfRenderer
|
||||
pdfTextLayer
|
||||
pdfAnnotations
|
||||
pdfHighlights
|
||||
pdf
|
||||
textLayerCss
|
||||
annotationsLayerCss
|
||||
highlightsLayerCss
|
||||
|
|
|
@ -1,104 +1,107 @@
|
|||
app = angular.module 'pdfPage', ['pdfHighlights']
|
||||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
# App = angular.module 'pdfPage', ['pdfHighlights']
|
||||
|
||||
app.directive 'pdfPage', ['$timeout', 'pdfHighlights', ($timeout, pdfHighlights) ->
|
||||
{
|
||||
require: '^pdfViewer',
|
||||
template: '''
|
||||
<div class="plv-page-view page-view">
|
||||
<div class="pdf-canvas"></div>
|
||||
<div class="plv-text-layer text-layer"></div>
|
||||
<div class="plv-annotations-layer annotations-layer"></div>
|
||||
<div class="plv-highlights-layer highlights-layer"></div>
|
||||
</div>
|
||||
'''
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
canvasElement = $(element).find('.pdf-canvas')
|
||||
textElement = $(element).find('.text-layer')
|
||||
annotationsElement = $(element).find('.annotations-layer')
|
||||
highlightsElement = $(element).find('.highlights-layer')
|
||||
App.directive 'pdfPage', ['$timeout', 'pdfHighlights', ($timeout, pdfHighlights) ->
|
||||
{
|
||||
require: '^pdfViewer',
|
||||
template: '''
|
||||
<div class="plv-page-view page-view">
|
||||
<div class="pdf-canvas"></div>
|
||||
<div class="plv-text-layer text-layer"></div>
|
||||
<div class="plv-annotations-layer annotations-layer"></div>
|
||||
<div class="plv-highlights-layer highlights-layer"></div>
|
||||
</div>
|
||||
'''
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
canvasElement = $(element).find('.pdf-canvas')
|
||||
textElement = $(element).find('.text-layer')
|
||||
annotationsElement = $(element).find('.annotations-layer')
|
||||
highlightsElement = $(element).find('.highlights-layer')
|
||||
|
||||
updatePageSize = (size) ->
|
||||
element.height(Math.floor(size[0]))
|
||||
element.width(Math.floor(size[1]))
|
||||
scope.page.sized = true
|
||||
updatePageSize = (size) ->
|
||||
element.height(Math.floor(size[0]))
|
||||
element.width(Math.floor(size[1]))
|
||||
scope.page.sized = true
|
||||
|
||||
isVisible = (containerSize) ->
|
||||
elemTop = element.offset().top - containerSize[2]
|
||||
elemBottom = elemTop + element.innerHeight()
|
||||
visible = (elemTop < containerSize[1] and elemBottom > 0)
|
||||
scope.page.visible = visible
|
||||
scope.page.elemTop = elemTop
|
||||
scope.page.elemBottom = elemBottom
|
||||
return visible
|
||||
isVisible = (containerSize) ->
|
||||
elemTop = element.offset().top - containerSize[2]
|
||||
elemBottom = elemTop + element.innerHeight()
|
||||
visible = (elemTop < containerSize[1] and elemBottom > 0)
|
||||
scope.page.visible = visible
|
||||
scope.page.elemTop = elemTop
|
||||
scope.page.elemBottom = elemBottom
|
||||
return visible
|
||||
|
||||
renderPage = () ->
|
||||
scope.document.renderPage {
|
||||
canvas: canvasElement,
|
||||
text: textElement
|
||||
annotations: annotationsElement
|
||||
renderPage = () ->
|
||||
scope.document.renderPage {
|
||||
canvas: canvasElement,
|
||||
text: textElement
|
||||
annotations: annotationsElement
|
||||
highlights: highlightsElement
|
||||
}, scope.page.pageNum
|
||||
|
||||
pausePage = () ->
|
||||
scope.document.pause {
|
||||
canvas: canvasElement,
|
||||
text: textElement
|
||||
}, scope.page.pageNum
|
||||
|
||||
# keep track of our page element, so we can access it in the
|
||||
# parent with scope.pages[i].element
|
||||
scope.page.element = element
|
||||
|
||||
if (!scope.page.sized && scope.defaultPageSize)
|
||||
updatePageSize scope.defaultPageSize
|
||||
|
||||
if scope.page.current
|
||||
console.log 'we must scroll to this page', scope.page.pageNum,
|
||||
'at position', scope.page.position
|
||||
renderPage()
|
||||
# this is the current page, we want to scroll it into view
|
||||
scope.document.getPdfViewport(scope.page.pageNum).then (viewport) ->
|
||||
scope.page.viewport = viewport
|
||||
ctrl.setPdfPosition(scope.page, scope.page.position)
|
||||
|
||||
scope.$watch 'defaultPageSize', (defaultPageSize) ->
|
||||
return unless defaultPageSize?
|
||||
updatePageSize defaultPageSize
|
||||
|
||||
watchHandle = scope.$watch 'containerSize', (containerSize, oldVal) ->
|
||||
return unless containerSize?
|
||||
return unless scope.page.sized
|
||||
oldVisible = scope.page.visible
|
||||
newVisible = isVisible containerSize
|
||||
scope.page.visible = newVisible
|
||||
if newVisible && !oldVisible
|
||||
renderPage()
|
||||
# TODO deregister this listener after the page is rendered
|
||||
#watchHandle()
|
||||
else if !newVisible && oldVisible
|
||||
pausePage()
|
||||
|
||||
highlightsLayer = new pdfHighlights({
|
||||
highlights: highlightsElement
|
||||
}, scope.page.pageNum
|
||||
})
|
||||
|
||||
pausePage = () ->
|
||||
scope.document.pause {
|
||||
canvas: canvasElement,
|
||||
text: textElement
|
||||
}, scope.page.pageNum
|
||||
|
||||
# keep track of our page element, so we can access it in the
|
||||
# parent with scope.pages[i].element
|
||||
scope.page.element = element
|
||||
|
||||
if (!scope.page.sized && scope.defaultPageSize)
|
||||
updatePageSize scope.defaultPageSize
|
||||
|
||||
if scope.page.current
|
||||
console.log 'we must scroll to this page', scope.page.pageNum,
|
||||
'at position', scope.page.position
|
||||
renderPage()
|
||||
# this is the current page, we want to scroll it into view
|
||||
scope.$watch 'highlights', (highlights, oldVal) ->
|
||||
return unless highlights?
|
||||
return unless highlights.length > 0
|
||||
console.log 'got highlight watch in pdfPage', scope.page
|
||||
pageHighlights = (h for h in highlights when h.page == scope.page.pageNum)
|
||||
return unless pageHighlights.length
|
||||
scope.document.getPdfViewport(scope.page.pageNum).then (viewport) ->
|
||||
scope.page.viewport = viewport
|
||||
ctrl.setPdfPosition(scope.page, scope.page.position)
|
||||
for hl in pageHighlights
|
||||
console.log 'adding highlight', h, viewport
|
||||
top = viewport.viewBox[3] - hl.v
|
||||
highlightsLayer.addHighlight viewport, hl.h, top, hl.width, hl.height
|
||||
$timeout () ->
|
||||
highlightsLayer.clearHighlights()
|
||||
, 1000
|
||||
|
||||
scope.$watch 'defaultPageSize', (defaultPageSize) ->
|
||||
return unless defaultPageSize?
|
||||
updatePageSize defaultPageSize
|
||||
scope.$on "$destroy", () ->
|
||||
console.log 'in destroy handler, TODO need to clean up timeout/highlights'
|
||||
|
||||
watchHandle = scope.$watch 'containerSize', (containerSize, oldVal) ->
|
||||
return unless containerSize?
|
||||
return unless scope.page.sized
|
||||
oldVisible = scope.page.visible
|
||||
newVisible = isVisible containerSize
|
||||
scope.page.visible = newVisible
|
||||
if newVisible && !oldVisible
|
||||
renderPage()
|
||||
# TODO deregister this listener after the page is rendered
|
||||
#watchHandle()
|
||||
else if !newVisible && oldVisible
|
||||
pausePage()
|
||||
|
||||
highlightsLayer = new pdfHighlights({
|
||||
highlights: highlightsElement
|
||||
})
|
||||
|
||||
scope.$watch 'highlights', (highlights, oldVal) ->
|
||||
return unless highlights?
|
||||
return unless highlights.length > 0
|
||||
console.log 'got highlight watch in pdfPage', scope.page
|
||||
pageHighlights = (h for h in highlights when h.page == scope.page.pageNum)
|
||||
return unless pageHighlights.length
|
||||
scope.document.getPdfViewport(scope.page.pageNum).then (viewport) ->
|
||||
for hl in pageHighlights
|
||||
console.log 'adding highlight', h, viewport
|
||||
top = viewport.viewBox[3] - hl.v
|
||||
highlightsLayer.addHighlight viewport, hl.h, top, hl.width, hl.height
|
||||
$timeout () ->
|
||||
highlightsLayer.clearHighlights()
|
||||
, 1000
|
||||
|
||||
scope.$on "$destroy", () ->
|
||||
console.log 'in destroy handler, TODO need to clean up timeout/highlights'
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,185 +1,188 @@
|
|||
app = angular.module 'PDFRenderer', ['pdfAnnotations', 'pdfTextLayer']
|
||||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
# App = angular.module 'PDFRenderer', ['pdfAnnotations', 'pdfTextLayer']
|
||||
|
||||
console.log 'hello from Renderer'
|
||||
console.log 'hello from Renderer'
|
||||
|
||||
app.factory 'PDFRenderer', ['$q', '$timeout', 'pdfAnnotations', 'pdfTextLayer', ($q, $timeout, pdfAnnotations, pdfTextLayer) ->
|
||||
App.factory 'PDFRenderer', ['$q', '$timeout', 'pdfAnnotations', 'pdfTextLayer', ($q, $timeout, pdfAnnotations, pdfTextLayer) ->
|
||||
|
||||
class PDFRenderer
|
||||
@JOB_QUEUE_INTERVAL: 100
|
||||
class PDFRenderer
|
||||
@JOB_QUEUE_INTERVAL: 100
|
||||
|
||||
constructor: (@url, @options) ->
|
||||
@scale = @options.scale || 1
|
||||
@document = $q.when(PDFJS.getDocument @url)
|
||||
@navigateFn = @options.navigateFn
|
||||
@resetState()
|
||||
constructor: (@url, @options) ->
|
||||
@scale = @options.scale || 1
|
||||
@document = $q.when(PDFJS.getDocument @url)
|
||||
@navigateFn = @options.navigateFn
|
||||
@resetState()
|
||||
|
||||
resetState: () ->
|
||||
console.log 'reseting renderer state'
|
||||
@page = []
|
||||
@complete = []
|
||||
@timeout = []
|
||||
@renderTask = []
|
||||
@renderQueue = []
|
||||
@jobs = 0
|
||||
resetState: () ->
|
||||
console.log 'reseting renderer state'
|
||||
@page = []
|
||||
@complete = []
|
||||
@timeout = []
|
||||
@renderTask = []
|
||||
@renderQueue = []
|
||||
@jobs = 0
|
||||
|
||||
getNumPages: () ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.numPages
|
||||
getNumPages: () ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.numPages
|
||||
|
||||
getPage: (pageNum) ->
|
||||
# with promise caching
|
||||
return @page[pageNum] if @page[pageNum]?
|
||||
@page[pageNum] = @document.then (pdfDocument) ->
|
||||
pdfDocument.getPage(pageNum)
|
||||
getPage: (pageNum) ->
|
||||
# with promise caching
|
||||
return @page[pageNum] if @page[pageNum]?
|
||||
@page[pageNum] = @document.then (pdfDocument) ->
|
||||
pdfDocument.getPage(pageNum)
|
||||
|
||||
getPdfViewport: (pageNum, scale) ->
|
||||
scale ?= @scale
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getPage(pageNum).then (page) ->
|
||||
viewport = page.getViewport scale
|
||||
getPdfViewport: (pageNum, scale) ->
|
||||
scale ?= @scale
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getPage(pageNum).then (page) ->
|
||||
viewport = page.getViewport scale
|
||||
|
||||
getDestinations: () ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getDestinations()
|
||||
getDestinations: () ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getDestinations()
|
||||
|
||||
getPageIndex: (ref) ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getPageIndex(ref).then (idx) ->
|
||||
idx
|
||||
getPageIndex: (ref) ->
|
||||
@document.then (pdfDocument) ->
|
||||
pdfDocument.getPageIndex(ref).then (idx) ->
|
||||
idx
|
||||
|
||||
getScale: () ->
|
||||
@scale
|
||||
getScale: () ->
|
||||
@scale
|
||||
|
||||
setScale: (@scale) ->
|
||||
@resetState()
|
||||
setScale: (@scale) ->
|
||||
@resetState()
|
||||
|
||||
pause: (element, pagenum) ->
|
||||
return if @complete[pagenum]
|
||||
@renderQueue = @renderQueue.filter (q) ->
|
||||
q.pagenum != pagenum
|
||||
@stopSpinner (element.canvas)
|
||||
pause: (element, pagenum) ->
|
||||
return if @complete[pagenum]
|
||||
@renderQueue = @renderQueue.filter (q) ->
|
||||
q.pagenum != pagenum
|
||||
@stopSpinner (element.canvas)
|
||||
|
||||
triggerRenderQueue: () ->
|
||||
$timeout () =>
|
||||
@processRenderQueue()
|
||||
, @JOB_QUEUE_INTERVAL
|
||||
triggerRenderQueue: () ->
|
||||
$timeout () =>
|
||||
@processRenderQueue()
|
||||
, @JOB_QUEUE_INTERVAL
|
||||
|
||||
removeCompletedJob: (pagenum) ->
|
||||
# may need to clean up deferred object here
|
||||
delete @renderTask[pagenum]
|
||||
@jobs = @jobs - 1
|
||||
@triggerRenderQueue()
|
||||
removeCompletedJob: (pagenum) ->
|
||||
# may need to clean up deferred object here
|
||||
delete @renderTask[pagenum]
|
||||
@jobs = @jobs - 1
|
||||
@triggerRenderQueue()
|
||||
|
||||
renderPage: (element, pagenum) ->
|
||||
viewport = $q.defer()
|
||||
current = {
|
||||
'element': element
|
||||
'pagenum': pagenum
|
||||
}
|
||||
@renderQueue.push(current)
|
||||
@triggerRenderQueue()
|
||||
renderPage: (element, pagenum) ->
|
||||
viewport = $q.defer()
|
||||
current = {
|
||||
'element': element
|
||||
'pagenum': pagenum
|
||||
}
|
||||
@renderQueue.push(current)
|
||||
@triggerRenderQueue()
|
||||
|
||||
processRenderQueue: () ->
|
||||
return if @jobs > 0
|
||||
current = @renderQueue.pop()
|
||||
return unless current?
|
||||
[element, pagenum] = [current.element, current.pagenum]
|
||||
return if @complete[pagenum]
|
||||
return if @renderTask[pagenum]
|
||||
@jobs = @jobs + 1
|
||||
processRenderQueue: () ->
|
||||
return if @jobs > 0
|
||||
current = @renderQueue.pop()
|
||||
return unless current?
|
||||
[element, pagenum] = [current.element, current.pagenum]
|
||||
return if @complete[pagenum]
|
||||
return if @renderTask[pagenum]
|
||||
@jobs = @jobs + 1
|
||||
|
||||
@addSpinner(element.canvas)
|
||||
@addSpinner(element.canvas)
|
||||
|
||||
pageLoad = @getPage(pagenum)
|
||||
pageLoad = @getPage(pagenum)
|
||||
|
||||
@renderTask[pagenum] = pageLoad.then (pageObject) =>
|
||||
@doRender element, pagenum, pageObject
|
||||
@renderTask[pagenum] = pageLoad.then (pageObject) =>
|
||||
@doRender element, pagenum, pageObject
|
||||
|
||||
@renderTask[pagenum].then () =>
|
||||
# complete
|
||||
@complete[pagenum] = true
|
||||
@removeCompletedJob pagenum
|
||||
, () =>
|
||||
# rejected
|
||||
@removeCompletedJob pagenum
|
||||
@renderTask[pagenum].then () =>
|
||||
# complete
|
||||
@complete[pagenum] = true
|
||||
@removeCompletedJob pagenum
|
||||
, () =>
|
||||
# rejected
|
||||
@removeCompletedJob pagenum
|
||||
|
||||
doRender: (element, pagenum, page) ->
|
||||
self = this
|
||||
scale = @scale
|
||||
doRender: (element, pagenum, page) ->
|
||||
self = this
|
||||
scale = @scale
|
||||
|
||||
if (not scale?)
|
||||
console.log 'scale is undefined, returning'
|
||||
return
|
||||
if (not scale?)
|
||||
console.log 'scale is undefined, returning'
|
||||
return
|
||||
|
||||
canvas = $('<canvas class="pdf-canvas-new"></canvas>')
|
||||
canvas = $('<canvas class="pdf-canvas-new"></canvas>')
|
||||
|
||||
viewport = page.getViewport (scale)
|
||||
viewport = page.getViewport (scale)
|
||||
|
||||
devicePixelRatio = window.devicePixelRatio || 1
|
||||
devicePixelRatio = window.devicePixelRatio || 1
|
||||
|
||||
ctx = canvas[0].getContext '2d'
|
||||
backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
|
||||
ctx.mozBackingStorePixelRatio ||
|
||||
ctx.msBackingStorePixelRatio ||
|
||||
ctx.oBackingStorePixelRatio ||
|
||||
ctx.backingStorePixelRatio || 1
|
||||
pixelRatio = devicePixelRatio / backingStoreRatio
|
||||
ctx = canvas[0].getContext '2d'
|
||||
backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
|
||||
ctx.mozBackingStorePixelRatio ||
|
||||
ctx.msBackingStorePixelRatio ||
|
||||
ctx.oBackingStorePixelRatio ||
|
||||
ctx.backingStorePixelRatio || 1
|
||||
pixelRatio = devicePixelRatio / backingStoreRatio
|
||||
|
||||
scaledWidth = (Math.floor(viewport.width) * pixelRatio) | 0
|
||||
scaledHeight = (Math.floor(viewport.height) * pixelRatio) | 0
|
||||
scaledWidth = (Math.floor(viewport.width) * pixelRatio) | 0
|
||||
scaledHeight = (Math.floor(viewport.height) * pixelRatio) | 0
|
||||
|
||||
newWidth = Math.floor(viewport.width)
|
||||
newHeight = Math.floor(viewport.height)
|
||||
newWidth = Math.floor(viewport.width)
|
||||
newHeight = Math.floor(viewport.height)
|
||||
|
||||
canvas[0].height = scaledHeight
|
||||
canvas[0].width = scaledWidth
|
||||
canvas[0].height = scaledHeight
|
||||
canvas[0].width = scaledWidth
|
||||
|
||||
canvas.height(newHeight + 'px')
|
||||
canvas.width(newWidth + 'px')
|
||||
canvas.height(newHeight + 'px')
|
||||
canvas.width(newWidth + 'px')
|
||||
|
||||
element.canvas[0].height = newHeight
|
||||
element.canvas[0].width = newWidth
|
||||
element.canvas[0].height = newHeight
|
||||
element.canvas[0].width = newWidth
|
||||
|
||||
if pixelRatio != 1
|
||||
ctx.scale(pixelRatio, pixelRatio)
|
||||
if pixelRatio != 1
|
||||
ctx.scale(pixelRatio, pixelRatio)
|
||||
|
||||
textLayer = new pdfTextLayer({
|
||||
textLayerDiv: element.text[0]
|
||||
viewport: viewport
|
||||
})
|
||||
page.getTextContent().then (textContent) ->
|
||||
console.log 'text content is', textContent
|
||||
window.RENDER_DELAY = 0
|
||||
textLayer.setTextContent textContent
|
||||
textLayer = new pdfTextLayer({
|
||||
textLayerDiv: element.text[0]
|
||||
viewport: viewport
|
||||
})
|
||||
page.getTextContent().then (textContent) ->
|
||||
console.log 'text content is', textContent
|
||||
window.RENDER_DELAY = 0
|
||||
textLayer.setTextContent textContent
|
||||
|
||||
annotationsLayer = new pdfAnnotations({
|
||||
annotations: element.annotations[0]
|
||||
viewport: viewport
|
||||
navigateFn: @navigateFn
|
||||
})
|
||||
page.getAnnotations().then (annotations) ->
|
||||
console.log 'annotations are', annotations
|
||||
window.RENDER_DELAY = 0
|
||||
annotationsLayer.setAnnotations annotations
|
||||
annotationsLayer = new pdfAnnotations({
|
||||
annotations: element.annotations[0]
|
||||
viewport: viewport
|
||||
navigateFn: @navigateFn
|
||||
})
|
||||
page.getAnnotations().then (annotations) ->
|
||||
console.log 'annotations are', annotations
|
||||
window.RENDER_DELAY = 0
|
||||
annotationsLayer.setAnnotations annotations
|
||||
|
||||
return @renderTask = page.render {
|
||||
canvasContext: ctx
|
||||
viewport: viewport
|
||||
}
|
||||
.then () ->
|
||||
element.canvas.replaceWith(canvas)
|
||||
canvas.removeClass('pdf-canvas-new')
|
||||
return @renderTask = page.render {
|
||||
canvasContext: ctx
|
||||
viewport: viewport
|
||||
}
|
||||
.then () ->
|
||||
element.canvas.replaceWith(canvas)
|
||||
canvas.removeClass('pdf-canvas-new')
|
||||
|
||||
addSpinner: (element) ->
|
||||
element.css({position: 'relative'})
|
||||
h = element.parent().height()
|
||||
w = element.parent().width()
|
||||
size = Math.floor(0.5 * Math.min(h, w))
|
||||
spinner = $('<div style="position: absolute; top: 50%; left:50%; transform: translateX(-50%) translateY(50%);"><i class="fa fa-spinner fa-spin" style="color: #999"></i></div>')
|
||||
spinner.css({'font-size' : size + 'px'})
|
||||
element.append(spinner)
|
||||
addSpinner: (element) ->
|
||||
element.css({position: 'relative'})
|
||||
h = element.parent().height()
|
||||
w = element.parent().width()
|
||||
size = Math.floor(0.5 * Math.min(h, w))
|
||||
spinner = $('<div style="position: absolute; top: 50%; left:50%; transform: translateX(-50%) translateY(50%);"><i class="fa fa-spinner fa-spin" style="color: #999"></i></div>')
|
||||
spinner.css({'font-size' : size + 'px'})
|
||||
element.append(spinner)
|
||||
|
||||
stopSpinner: (element) ->
|
||||
element.find('.fa-spin').removeClass('fa-spin')
|
||||
stopSpinner: (element) ->
|
||||
element.find('.fa-spin').removeClass('fa-spin')
|
||||
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1,207 +1,210 @@
|
|||
app = angular.module 'pdfTextLayer', []
|
||||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
# App = angular.module 'pdfTextLayer', []
|
||||
|
||||
app.factory 'pdfTextLayer', [ () ->
|
||||
App.factory 'pdfTextLayer', [ () ->
|
||||
|
||||
# TRANSLATED FROM pdf.js-1.0.712
|
||||
# pdf.js-1.0.712/web/ui_utils.js
|
||||
# pdf.js-1.0.712/web/text_layer_builder.js
|
||||
# TRANSLATED FROM pdf.js-1.0.712
|
||||
# pdf.js-1.0.712/web/ui_utils.js
|
||||
# pdf.js-1.0.712/web/text_layer_builder.js
|
||||
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
|
||||
# Copyright 2012 Mozilla Foundation
|
||||
# *
|
||||
# * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# * you may not use this file except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.apache.org/licenses/LICENSE-2.0
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
#
|
||||
# Copyright 2012 Mozilla Foundation
|
||||
# *
|
||||
# * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# * you may not use this file except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.apache.org/licenses/LICENSE-2.0
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
#
|
||||
|
||||
# globals CustomStyle, scrollIntoView, PDFJS
|
||||
# ms
|
||||
# globals CustomStyle, scrollIntoView, PDFJS
|
||||
# ms
|
||||
|
||||
# optimised CSS custom property getter/setter
|
||||
# optimised CSS custom property getter/setter
|
||||
|
||||
CustomStyle = (CustomStyleClosure = ->
|
||||
CustomStyle = (CustomStyleClosure = ->
|
||||
|
||||
# As noted on: http://www.zachstronaut.com/posts/2009/02/17/
|
||||
# animate-css-transforms-firefox-webkit.html
|
||||
# in some versions of IE9 it is critical that ms appear in this list
|
||||
# before Moz
|
||||
CustomStyle = ->
|
||||
prefixes = [
|
||||
'ms'
|
||||
'Moz'
|
||||
'Webkit'
|
||||
'O'
|
||||
]
|
||||
_cache = {}
|
||||
CustomStyle.getProp = get = (propName, element) ->
|
||||
# As noted on: http://www.zachstronaut.com/posts/2009/02/17/
|
||||
# animate-css-transforms-firefox-webkit.html
|
||||
# in some versions of IE9 it is critical that ms appear in this list
|
||||
# before Moz
|
||||
CustomStyle = ->
|
||||
prefixes = [
|
||||
'ms'
|
||||
'Moz'
|
||||
'Webkit'
|
||||
'O'
|
||||
]
|
||||
_cache = {}
|
||||
CustomStyle.getProp = get = (propName, element) ->
|
||||
|
||||
# check cache only when no element is given
|
||||
return _cache[propName] if arguments.length is 1 and typeof _cache[propName] is 'string'
|
||||
element = element or document.documentElement
|
||||
style = element.style
|
||||
prefixed = undefined
|
||||
uPropName = undefined
|
||||
# check cache only when no element is given
|
||||
return _cache[propName] if arguments.length is 1 and typeof _cache[propName] is 'string'
|
||||
element = element or document.documentElement
|
||||
style = element.style
|
||||
prefixed = undefined
|
||||
uPropName = undefined
|
||||
|
||||
# test standard property first
|
||||
return (_cache[propName] = propName) if typeof style[propName] is 'string'
|
||||
# test standard property first
|
||||
return (_cache[propName] = propName) if typeof style[propName] is 'string'
|
||||
|
||||
# capitalize
|
||||
uPropName = propName.charAt(0).toUpperCase() + propName.slice(1)
|
||||
# capitalize
|
||||
uPropName = propName.charAt(0).toUpperCase() + propName.slice(1)
|
||||
|
||||
# test vendor specific properties
|
||||
i = 0
|
||||
l = prefixes.length
|
||||
# test vendor specific properties
|
||||
i = 0
|
||||
l = prefixes.length
|
||||
|
||||
while i < l
|
||||
prefixed = prefixes[i] + uPropName
|
||||
return (_cache[propName] = prefixed) if typeof style[prefixed] is 'string'
|
||||
i++
|
||||
while i < l
|
||||
prefixed = prefixes[i] + uPropName
|
||||
return (_cache[propName] = prefixed) if typeof style[prefixed] is 'string'
|
||||
i++
|
||||
|
||||
#if all fails then set to undefined
|
||||
_cache[propName] = 'undefined'
|
||||
#if all fails then set to undefined
|
||||
_cache[propName] = 'undefined'
|
||||
|
||||
CustomStyle.setProp = set = (propName, element, str) ->
|
||||
prop = @getProp(propName)
|
||||
element.style[prop] = str if prop isnt 'undefined'
|
||||
return
|
||||
|
||||
CustomStyle
|
||||
)()
|
||||
|
||||
#################################
|
||||
|
||||
isAllWhitespace = (str) ->
|
||||
not NonWhitespaceRegexp.test(str)
|
||||
'use strict'
|
||||
FIND_SCROLL_OFFSET_TOP = -50
|
||||
FIND_SCROLL_OFFSET_LEFT = -400
|
||||
MAX_TEXT_DIVS_TO_RENDER = 100000
|
||||
RENDER_DELAY = 200
|
||||
NonWhitespaceRegexp = /\S/
|
||||
|
||||
###*
|
||||
TextLayerBuilder provides text-selection functionality for the PDF.
|
||||
It does this by creating overlay divs over the PDF text. These divs
|
||||
contain text that matches the PDF text they are overlaying. This object
|
||||
also provides a way to highlight text that is being searched for.
|
||||
###
|
||||
|
||||
class pdfTextLayer
|
||||
|
||||
constructor: (options) ->
|
||||
@textLayerDiv = options.textLayerDiv
|
||||
@layoutDone = false
|
||||
@divContentDone = false
|
||||
@pageIdx = options.pageIndex
|
||||
@matches = []
|
||||
@lastScrollSource = options.lastScrollSource or null
|
||||
@viewport = options.viewport
|
||||
@isViewerInPresentationMode = options.isViewerInPresentationMode
|
||||
@textDivs = []
|
||||
@findController = options.findController or null
|
||||
|
||||
renderLayer: () ->
|
||||
textLayerFrag = document.createDocumentFragment()
|
||||
textDivs = @textDivs
|
||||
textDivsLength = textDivs.length
|
||||
canvas = document.createElement('canvas')
|
||||
ctx = canvas.getContext('2d')
|
||||
|
||||
# No point in rendering many divs as it would make the browser
|
||||
# unusable even after the divs are rendered.
|
||||
return if textDivsLength > MAX_TEXT_DIVS_TO_RENDER
|
||||
lastFontSize = undefined
|
||||
lastFontFamily = undefined
|
||||
i = 0
|
||||
|
||||
while i < textDivsLength
|
||||
textDiv = textDivs[i]
|
||||
continue if textDiv.dataset.isWhitespace
|
||||
fontSize = textDiv.style.fontSize
|
||||
fontFamily = textDiv.style.fontFamily
|
||||
|
||||
# Only build font string and set to context if different from last.
|
||||
if fontSize isnt lastFontSize or fontFamily isnt lastFontFamily
|
||||
ctx.font = fontSize + ' ' + fontFamily
|
||||
lastFontSize = fontSize
|
||||
lastFontFamily = fontFamily
|
||||
width = ctx.measureText(textDiv.textContent).width
|
||||
if width > 0
|
||||
textLayerFrag.appendChild textDiv
|
||||
|
||||
# Dataset values come of type string.
|
||||
textScale = textDiv.dataset.canvasWidth / width
|
||||
rotation = textDiv.dataset.angle
|
||||
transform = 'scale(' + textScale + ', 1)'
|
||||
transform = 'rotate(' + rotation + 'deg) ' + transform if rotation
|
||||
CustomStyle.setProp 'transform', textDiv, transform
|
||||
CustomStyle.setProp 'transformOrigin', textDiv, '0% 0%'
|
||||
i++
|
||||
@textLayerDiv.appendChild textLayerFrag
|
||||
return
|
||||
|
||||
appendText: (geom, styles) ->
|
||||
style = styles[geom.fontName]
|
||||
textDiv = document.createElement('div')
|
||||
@textDivs.push textDiv
|
||||
if isAllWhitespace(geom.str)
|
||||
textDiv.dataset.isWhitespace = true
|
||||
CustomStyle.setProp = set = (propName, element, str) ->
|
||||
prop = @getProp(propName)
|
||||
element.style[prop] = str if prop isnt 'undefined'
|
||||
return
|
||||
tx = PDFJS.Util.transform(@viewport.transform, geom.transform)
|
||||
angle = Math.atan2(tx[1], tx[0])
|
||||
angle += Math.PI / 2 if style.vertical
|
||||
fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]))
|
||||
fontAscent = fontHeight
|
||||
if style.ascent
|
||||
fontAscent = style.ascent * fontAscent
|
||||
else fontAscent = (1 + style.descent) * fontAscent if style.descent
|
||||
left = undefined
|
||||
top = undefined
|
||||
if angle is 0
|
||||
left = tx[4]
|
||||
top = tx[5] - fontAscent
|
||||
else
|
||||
left = tx[4] + (fontAscent * Math.sin(angle))
|
||||
top = tx[5] - (fontAscent * Math.cos(angle))
|
||||
textDiv.style.left = left + 'px'
|
||||
textDiv.style.top = top + 'px'
|
||||
textDiv.style.fontSize = fontHeight + 'px'
|
||||
textDiv.style.fontFamily = style.fontFamily
|
||||
textDiv.textContent = geom.str
|
||||
|
||||
# |fontName| is only used by the Font Inspector. This test will succeed
|
||||
# when e.g. the Font Inspector is off but the Stepper is on, but it's
|
||||
# not worth the effort to do a more accurate test.
|
||||
textDiv.dataset.fontName = geom.fontName if PDFJS.pdfBug
|
||||
CustomStyle
|
||||
)()
|
||||
|
||||
# Storing into dataset will convert number into string.
|
||||
textDiv.dataset.angle = angle * (180 / Math.PI) if angle isnt 0
|
||||
if style.vertical
|
||||
textDiv.dataset.canvasWidth = geom.height * @viewport.scale
|
||||
else
|
||||
textDiv.dataset.canvasWidth = geom.width * @viewport.scale
|
||||
return
|
||||
#################################
|
||||
|
||||
setTextContent: (textContent) ->
|
||||
@textContent = textContent
|
||||
textItems = textContent.items
|
||||
i = 0
|
||||
len = textItems.length
|
||||
isAllWhitespace = (str) ->
|
||||
not NonWhitespaceRegexp.test(str)
|
||||
'use strict'
|
||||
FIND_SCROLL_OFFSET_TOP = -50
|
||||
FIND_SCROLL_OFFSET_LEFT = -400
|
||||
MAX_TEXT_DIVS_TO_RENDER = 100000
|
||||
RENDER_DELAY = 200
|
||||
NonWhitespaceRegexp = /\S/
|
||||
|
||||
while i < len
|
||||
@appendText textItems[i], textContent.styles
|
||||
i++
|
||||
@divContentDone = true
|
||||
@renderLayer()
|
||||
return
|
||||
###*
|
||||
TextLayerBuilder provides text-selection functionality for the PDF.
|
||||
It does this by creating overlay divs over the PDF text. These divs
|
||||
contain text that matches the PDF text they are overlaying. This object
|
||||
also provides a way to highlight text that is being searched for.
|
||||
###
|
||||
|
||||
]
|
||||
class pdfTextLayer
|
||||
|
||||
constructor: (options) ->
|
||||
@textLayerDiv = options.textLayerDiv
|
||||
@layoutDone = false
|
||||
@divContentDone = false
|
||||
@pageIdx = options.pageIndex
|
||||
@matches = []
|
||||
@lastScrollSource = options.lastScrollSource or null
|
||||
@viewport = options.viewport
|
||||
@isViewerInPresentationMode = options.isViewerInPresentationMode
|
||||
@textDivs = []
|
||||
@findController = options.findController or null
|
||||
|
||||
renderLayer: () ->
|
||||
textLayerFrag = document.createDocumentFragment()
|
||||
textDivs = @textDivs
|
||||
textDivsLength = textDivs.length
|
||||
canvas = document.createElement('canvas')
|
||||
ctx = canvas.getContext('2d')
|
||||
|
||||
# No point in rendering many divs as it would make the browser
|
||||
# unusable even after the divs are rendered.
|
||||
return if textDivsLength > MAX_TEXT_DIVS_TO_RENDER
|
||||
lastFontSize = undefined
|
||||
lastFontFamily = undefined
|
||||
i = 0
|
||||
|
||||
while i < textDivsLength
|
||||
textDiv = textDivs[i]
|
||||
continue if textDiv.dataset.isWhitespace
|
||||
fontSize = textDiv.style.fontSize
|
||||
fontFamily = textDiv.style.fontFamily
|
||||
|
||||
# Only build font string and set to context if different from last.
|
||||
if fontSize isnt lastFontSize or fontFamily isnt lastFontFamily
|
||||
ctx.font = fontSize + ' ' + fontFamily
|
||||
lastFontSize = fontSize
|
||||
lastFontFamily = fontFamily
|
||||
width = ctx.measureText(textDiv.textContent).width
|
||||
if width > 0
|
||||
textLayerFrag.appendChild textDiv
|
||||
|
||||
# Dataset values come of type string.
|
||||
textScale = textDiv.dataset.canvasWidth / width
|
||||
rotation = textDiv.dataset.angle
|
||||
transform = 'scale(' + textScale + ', 1)'
|
||||
transform = 'rotate(' + rotation + 'deg) ' + transform if rotation
|
||||
CustomStyle.setProp 'transform', textDiv, transform
|
||||
CustomStyle.setProp 'transformOrigin', textDiv, '0% 0%'
|
||||
i++
|
||||
@textLayerDiv.appendChild textLayerFrag
|
||||
return
|
||||
|
||||
appendText: (geom, styles) ->
|
||||
style = styles[geom.fontName]
|
||||
textDiv = document.createElement('div')
|
||||
@textDivs.push textDiv
|
||||
if isAllWhitespace(geom.str)
|
||||
textDiv.dataset.isWhitespace = true
|
||||
return
|
||||
tx = PDFJS.Util.transform(@viewport.transform, geom.transform)
|
||||
angle = Math.atan2(tx[1], tx[0])
|
||||
angle += Math.PI / 2 if style.vertical
|
||||
fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]))
|
||||
fontAscent = fontHeight
|
||||
if style.ascent
|
||||
fontAscent = style.ascent * fontAscent
|
||||
else fontAscent = (1 + style.descent) * fontAscent if style.descent
|
||||
left = undefined
|
||||
top = undefined
|
||||
if angle is 0
|
||||
left = tx[4]
|
||||
top = tx[5] - fontAscent
|
||||
else
|
||||
left = tx[4] + (fontAscent * Math.sin(angle))
|
||||
top = tx[5] - (fontAscent * Math.cos(angle))
|
||||
textDiv.style.left = left + 'px'
|
||||
textDiv.style.top = top + 'px'
|
||||
textDiv.style.fontSize = fontHeight + 'px'
|
||||
textDiv.style.fontFamily = style.fontFamily
|
||||
textDiv.textContent = geom.str
|
||||
|
||||
# |fontName| is only used by the Font Inspector. This test will succeed
|
||||
# when e.g. the Font Inspector is off but the Stepper is on, but it's
|
||||
# not worth the effort to do a more accurate test.
|
||||
textDiv.dataset.fontName = geom.fontName if PDFJS.pdfBug
|
||||
|
||||
# Storing into dataset will convert number into string.
|
||||
textDiv.dataset.angle = angle * (180 / Math.PI) if angle isnt 0
|
||||
if style.vertical
|
||||
textDiv.dataset.canvasWidth = geom.height * @viewport.scale
|
||||
else
|
||||
textDiv.dataset.canvasWidth = geom.width * @viewport.scale
|
||||
return
|
||||
|
||||
setTextContent: (textContent) ->
|
||||
@textContent = textContent
|
||||
textItems = textContent.items
|
||||
i = 0
|
||||
len = textItems.length
|
||||
|
||||
while i < len
|
||||
@appendText textItems[i], textContent.styles
|
||||
i++
|
||||
@divContentDone = true
|
||||
@renderLayer()
|
||||
return
|
||||
|
||||
]
|
||||
|
|
|
@ -1,359 +1,377 @@
|
|||
app = angular.module 'pdfViewerApp', ['pdfPage', 'PDFRenderer', 'pdfHighlights']
|
||||
define [
|
||||
"base"
|
||||
"ide/pdfng/directives/pdfTextLayer"
|
||||
"ide/pdfng/directives/pdfAnnotations"
|
||||
"ide/pdfng/directives/pdfHighlights"
|
||||
"ide/pdfng/directives/pdfRenderer"
|
||||
"ide/pdfng/directives/pdfPage"
|
||||
"libs/pdfjs-1.0.712/pdf"
|
||||
], (
|
||||
App
|
||||
pdfTextLayer
|
||||
pdfAnnotations
|
||||
pdfHighlights
|
||||
pdfRenderer
|
||||
pdfPage
|
||||
pdf
|
||||
) ->
|
||||
|
||||
app.controller 'pdfViewerController', ['$scope', '$q', 'PDFRenderer', '$element', 'pdfHighlights', ($scope, $q, PDFRenderer, $element, pdfHighlights) ->
|
||||
@load = () ->
|
||||
$scope.document = new PDFRenderer($scope.pdfSrc, {
|
||||
scale: 1,
|
||||
navigateFn: (ref) ->
|
||||
# this function captures clicks on the annotation links
|
||||
$scope.navigateTo = ref
|
||||
$scope.$apply()
|
||||
})
|
||||
# App = angular.module 'pdfViewerApp', ['pdfPage', 'PDFRenderer', 'pdfHighlights']
|
||||
|
||||
# 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()
|
||||
destinations: $scope.document.getDestinations()
|
||||
# get size of first page as default @ scale 1
|
||||
pdfViewport: $scope.document.getPdfViewport 1, 1
|
||||
}).then (result) ->
|
||||
$scope.pdfViewport = result.pdfViewport
|
||||
$scope.pdfPageSize = [
|
||||
result.pdfViewport.height,
|
||||
result.pdfViewport.width
|
||||
App.controller 'pdfViewerController', ['$scope', '$q', 'PDFRenderer', '$element', 'pdfHighlights', ($scope, $q, PDFRenderer, $element, pdfHighlights) ->
|
||||
@load = () ->
|
||||
$scope.document = new PDFRenderer($scope.pdfSrc, {
|
||||
scale: 1,
|
||||
navigateFn: (ref) ->
|
||||
# this function captures clicks on the annotation links
|
||||
$scope.navigateTo = ref
|
||||
$scope.$apply()
|
||||
})
|
||||
|
||||
# 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()
|
||||
destinations: $scope.document.getDestinations()
|
||||
# get size of first page as default @ scale 1
|
||||
pdfViewport: $scope.document.getPdfViewport 1, 1
|
||||
}).then (result) ->
|
||||
$scope.pdfViewport = result.pdfViewport
|
||||
$scope.pdfPageSize = [
|
||||
result.pdfViewport.height,
|
||||
result.pdfViewport.width
|
||||
]
|
||||
$scope.destinations = result.destinations
|
||||
console.log 'resolved q.all, page size is', result
|
||||
$scope.numPages = result.numPages
|
||||
|
||||
@setScale = (scale, containerHeight, containerWidth) ->
|
||||
$scope.loaded.then () ->
|
||||
scale = {} if not scale?
|
||||
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)
|
||||
$scope.defaultPageSize = [
|
||||
numScale * $scope.pdfPageSize[0],
|
||||
numScale * $scope.pdfPageSize[1]
|
||||
]
|
||||
$scope.destinations = result.destinations
|
||||
console.log 'resolved q.all, page size is', result
|
||||
$scope.numPages = result.numPages
|
||||
console.log 'in setScale result', $scope.scale.scale, $scope.defaultPageSize
|
||||
|
||||
@setScale = (scale, containerHeight, containerWidth) ->
|
||||
$scope.loaded.then () ->
|
||||
scale = {} if not scale?
|
||||
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)
|
||||
$scope.defaultPageSize = [
|
||||
numScale * $scope.pdfPageSize[0],
|
||||
numScale * $scope.pdfPageSize[1]
|
||||
@redraw = (position) ->
|
||||
console.log 'in redraw'
|
||||
console.log 'reseting pages array for', $scope.numPages
|
||||
console.log 'position is', position.page, position.offset
|
||||
$scope.pages = ({
|
||||
pageNum: i + 1
|
||||
} for i in [0 .. $scope.numPages-1])
|
||||
if position? && position.page?
|
||||
console.log 'setting current page', position.page
|
||||
pagenum = position.page
|
||||
$scope.pages[pagenum].current = true
|
||||
$scope.pages[pagenum].position = position
|
||||
|
||||
@zoomIn = () ->
|
||||
console.log 'zoom in'
|
||||
newScale = $scope.scale.scale * 1.2
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }
|
||||
|
||||
@zoomOut = () ->
|
||||
console.log 'zoom out'
|
||||
newScale = $scope.scale.scale / 1.2
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }
|
||||
|
||||
@fitWidth = () ->
|
||||
console.log 'fit width'
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_fit_width' }
|
||||
|
||||
@fitHeight = () ->
|
||||
console.log 'fit height'
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_fit_height' }
|
||||
|
||||
@checkPosition = () ->
|
||||
console.log 'check position'
|
||||
$scope.forceCheck = ($scope.forceCheck || 0) + 1
|
||||
|
||||
@showRandomHighlights = () ->
|
||||
console.log 'show highlights'
|
||||
$scope.highlights = [
|
||||
{
|
||||
page: 3
|
||||
h: 100
|
||||
v: 100
|
||||
height: 30
|
||||
width: 200
|
||||
}
|
||||
]
|
||||
console.log 'in setScale result', $scope.scale.scale, $scope.defaultPageSize
|
||||
|
||||
@redraw = (position) ->
|
||||
console.log 'in redraw'
|
||||
console.log 'reseting pages array for', $scope.numPages
|
||||
console.log 'position is', position.page, position.offset
|
||||
$scope.pages = ({
|
||||
pageNum: i + 1
|
||||
} for i in [0 .. $scope.numPages-1])
|
||||
if position? && position.page?
|
||||
console.log 'setting current page', position.page
|
||||
pagenum = position.page
|
||||
$scope.pages[pagenum].current = true
|
||||
$scope.pages[pagenum].position = position
|
||||
# we work with (pagenumber, % of height down page from top)
|
||||
# pdfListView works with (pagenumber, vertical position up page from
|
||||
# bottom measured in pts)
|
||||
|
||||
@zoomIn = () ->
|
||||
console.log 'zoom in'
|
||||
newScale = $scope.scale.scale * 1.2
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }
|
||||
@getPdfPosition = () ->
|
||||
console.log 'in getPdfPosition'
|
||||
topPageIdx = 0
|
||||
topPage = $scope.pages[0]
|
||||
# find first visible page
|
||||
visible = $scope.pages.some (page, i) ->
|
||||
[topPageIdx, topPage] = [i, page] if page.visible
|
||||
if visible
|
||||
console.log 'found it', topPageIdx
|
||||
else
|
||||
console.log 'CANNOT FIND TOP PAGE'
|
||||
|
||||
@zoomOut = () ->
|
||||
console.log 'zoom out'
|
||||
newScale = $scope.scale.scale / 1.2
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }
|
||||
|
||||
@fitWidth = () ->
|
||||
console.log 'fit width'
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_fit_width' }
|
||||
|
||||
@fitHeight = () ->
|
||||
console.log 'fit height'
|
||||
$scope.forceScale = { scaleMode: 'scale_mode_fit_height' }
|
||||
|
||||
@checkPosition = () ->
|
||||
console.log 'check position'
|
||||
$scope.forceCheck = ($scope.forceCheck || 0) + 1
|
||||
|
||||
@showRandomHighlights = () ->
|
||||
console.log 'show highlights'
|
||||
$scope.highlights = [
|
||||
{
|
||||
page: 3
|
||||
h: 100
|
||||
v: 100
|
||||
height: 30
|
||||
width: 200
|
||||
console.log 'top page is', topPage.pageNum, topPage.elemTop, topPage.elemBottom, topPage
|
||||
top = topPage.elemTop
|
||||
bottom = topPage.elemBottom
|
||||
viewportTop = 0
|
||||
viewportHeight = $element.height()
|
||||
topVisible = (top >= viewportTop && top < viewportTop + viewportHeight)
|
||||
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.viewport
|
||||
pdfOffset = viewport.convertToPdfPoint(0, canvasOffset);
|
||||
else
|
||||
console.log 'WARNING: had to default to global page size'
|
||||
viewport = $scope.pdfViewport
|
||||
scaledOffset = canvasOffset / $scope.scale.scale
|
||||
pdfOffset = viewport.convertToPdfPoint(0, scaledOffset);
|
||||
console.log 'converted to offset = ', pdfOffset
|
||||
newPosition = {
|
||||
"page": topPageIdx,
|
||||
"offset" : { "top" : pdfOffset[1], "left": 0 }
|
||||
}
|
||||
]
|
||||
return newPosition
|
||||
|
||||
# we work with (pagenumber, % of height down page from top)
|
||||
# pdfListView works with (pagenumber, vertical position up page from
|
||||
# bottom measured in pts)
|
||||
@computeOffset = (page, position) ->
|
||||
console.log 'computing offset for', page, position
|
||||
element = page.element
|
||||
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())
|
||||
currentScroll = $(element).parent().scrollTop()
|
||||
offset = position.offset
|
||||
# convert offset to pixels
|
||||
return $scope.document.getPdfViewport(page.pageNum).then (viewport) ->
|
||||
page.viewport = viewport
|
||||
pageOffset = viewport.convertToViewportPoint(offset.left, offset.top)
|
||||
console.log 'addition offset =', pageOffset
|
||||
console.log 'total', pageTop + pageOffset[1]
|
||||
Math.round(pageTop + pageOffset[1] + currentScroll) ## 10 is margin
|
||||
|
||||
@getPdfPosition = () ->
|
||||
console.log 'in getPdfPosition'
|
||||
topPageIdx = 0
|
||||
topPage = $scope.pages[0]
|
||||
# find first visible page
|
||||
visible = $scope.pages.some (page, i) ->
|
||||
[topPageIdx, topPage] = [i, page] if page.visible
|
||||
if visible
|
||||
console.log 'found it', topPageIdx
|
||||
else
|
||||
console.log 'CANNOT FIND TOP PAGE'
|
||||
@setPdfPosition = (page, position) ->
|
||||
console.log 'required pdf Position is', position
|
||||
@computeOffset(page, position).then (offset) ->
|
||||
$scope.pleaseScrollTo = offset
|
||||
$scope.position = position
|
||||
|
||||
console.log 'top page is', topPage.pageNum, topPage.elemTop, topPage.elemBottom, topPage
|
||||
top = topPage.elemTop
|
||||
bottom = topPage.elemBottom
|
||||
viewportTop = 0
|
||||
viewportHeight = $element.height()
|
||||
topVisible = (top >= viewportTop && top < viewportTop + viewportHeight)
|
||||
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.viewport
|
||||
pdfOffset = viewport.convertToPdfPoint(0, canvasOffset);
|
||||
else
|
||||
console.log 'WARNING: had to default to global page size'
|
||||
viewport = $scope.pdfViewport
|
||||
scaledOffset = canvasOffset / $scope.scale.scale
|
||||
pdfOffset = viewport.convertToPdfPoint(0, scaledOffset);
|
||||
console.log 'converted to offset = ', pdfOffset
|
||||
newPosition = {
|
||||
"page": topPageIdx,
|
||||
"offset" : { "top" : pdfOffset[1], "left": 0 }
|
||||
}
|
||||
return newPosition
|
||||
return this
|
||||
|
||||
@computeOffset = (page, position) ->
|
||||
console.log 'computing offset for', page, position
|
||||
element = page.element
|
||||
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())
|
||||
currentScroll = $(element).parent().scrollTop()
|
||||
offset = position.offset
|
||||
# convert offset to pixels
|
||||
return $scope.document.getPdfViewport(page.pageNum).then (viewport) ->
|
||||
page.viewport = viewport
|
||||
pageOffset = viewport.convertToViewportPoint(offset.left, offset.top)
|
||||
console.log 'addition offset =', pageOffset
|
||||
console.log 'total', pageTop + pageOffset[1]
|
||||
Math.round(pageTop + pageOffset[1] + currentScroll) ## 10 is margin
|
||||
]
|
||||
|
||||
@setPdfPosition = (page, position) ->
|
||||
console.log 'required pdf Position is', position
|
||||
@computeOffset(page, position).then (offset) ->
|
||||
$scope.pleaseScrollTo = offset
|
||||
$scope.position = position
|
||||
|
||||
return this
|
||||
|
||||
]
|
||||
|
||||
app.directive 'pdfViewer', ['$q', '$timeout', ($q, $timeout) ->
|
||||
{
|
||||
controller: 'pdfViewerController'
|
||||
controllerAs: 'ctrl'
|
||||
scope: {
|
||||
"pdfSrc": "="
|
||||
"highlights": "="
|
||||
"position": "="
|
||||
"scale": "="
|
||||
"dblClickCallback": "="
|
||||
"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
|
||||
layoutReady = $q.defer()
|
||||
layoutReady.notify 'waiting for layout'
|
||||
layoutReady.promise.then () ->
|
||||
console.log 'layoutReady was resolved'
|
||||
|
||||
# TODO can we combine this with scope.parentSize, need to finalize boxes
|
||||
updateContainer = () ->
|
||||
scope.containerSize = [
|
||||
element.innerWidth()
|
||||
element.innerHeight()
|
||||
element.offset().top
|
||||
]
|
||||
|
||||
doRescale = (scale) ->
|
||||
console.log 'doRescale', scale
|
||||
origposition = angular.copy scope.position
|
||||
console.log 'origposition', origposition
|
||||
App.directive 'pdfViewer', ['$q', '$timeout', ($q, $timeout) ->
|
||||
{
|
||||
controller: 'pdfViewerController'
|
||||
controllerAs: 'ctrl'
|
||||
scope: {
|
||||
"pdfSrc": "="
|
||||
"highlights": "="
|
||||
"position": "="
|
||||
"scale": "="
|
||||
"dblClickCallback": "="
|
||||
"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
|
||||
layoutReady = $q.defer()
|
||||
layoutReady.notify 'waiting for layout'
|
||||
layoutReady.promise.then () ->
|
||||
[h, w] = [element.innerHeight(), element.width()]
|
||||
console.log 'in promise', h, w
|
||||
ctrl.setScale(scale, h, w).then () ->
|
||||
ctrl.redraw(origposition)
|
||||
console.log 'layoutReady was resolved'
|
||||
|
||||
scope.$on 'layout-ready', () ->
|
||||
console.log 'GOT LAYOUT READY EVENT'
|
||||
console.log 'calling refresh'
|
||||
updateContainer()
|
||||
layoutReady.resolve 'layout is ready'
|
||||
scope.parentSize = [
|
||||
element.innerHeight(),
|
||||
element.innerWidth()
|
||||
]
|
||||
#scope.$apply()
|
||||
# TODO can we combine this with scope.parentSize, need to finalize boxes
|
||||
updateContainer = () ->
|
||||
scope.containerSize = [
|
||||
element.innerWidth()
|
||||
element.innerHeight()
|
||||
element.offset().top
|
||||
]
|
||||
|
||||
scope.$on 'layout:pdf:resize', () ->
|
||||
console.log 'GOT LAYOUT-RESIZE EVENT'
|
||||
scope.parentSize = [
|
||||
element.innerHeight(),
|
||||
element.innerWidth()
|
||||
]
|
||||
#scope.$apply()
|
||||
doRescale = (scale) ->
|
||||
console.log 'doRescale', scale
|
||||
origposition = angular.copy scope.position
|
||||
console.log 'origposition', origposition
|
||||
layoutReady.promise.then () ->
|
||||
[h, w] = [element.innerHeight(), element.width()]
|
||||
console.log 'in promise', h, w
|
||||
ctrl.setScale(scale, h, w).then () ->
|
||||
ctrl.redraw(origposition)
|
||||
|
||||
element.on 'scroll', () ->
|
||||
console.log 'scroll detected', scope.adjustingScroll
|
||||
updateContainer()
|
||||
scope.$apply()
|
||||
#console.log 'pdfposition', element.parent().scrollTop()
|
||||
if scope.adjustingScroll
|
||||
scope.adjustingScroll = false
|
||||
return
|
||||
#console.log 'not from auto scroll'
|
||||
scope.position = ctrl.getPdfPosition()
|
||||
console.log 'position is', scope.position.page, scope.position.offset
|
||||
scope.$apply()
|
||||
scope.$on 'layout-ready', () ->
|
||||
console.log 'GOT LAYOUT READY EVENT'
|
||||
console.log 'calling refresh'
|
||||
updateContainer()
|
||||
layoutReady.resolve 'layout is ready'
|
||||
scope.parentSize = [
|
||||
element.innerHeight(),
|
||||
element.innerWidth()
|
||||
]
|
||||
#scope.$apply()
|
||||
|
||||
scope.$watch 'pdfSrc', (newVal, oldVal) ->
|
||||
console.log 'loading pdf', newVal, oldVal
|
||||
return unless newVal?
|
||||
ctrl.load()
|
||||
# trigger a redraw
|
||||
scope.scale = angular.copy (scope.scale)
|
||||
scope.$on 'layout:pdf:resize', () ->
|
||||
console.log 'GOT LAYOUT-RESIZE EVENT'
|
||||
scope.parentSize = [
|
||||
element.innerHeight(),
|
||||
element.innerWidth()
|
||||
]
|
||||
#scope.$apply()
|
||||
|
||||
scope.$watch 'scale', (newVal, oldVal) ->
|
||||
# no need to set scale when initialising, done in pdfSrc
|
||||
return if newVal == oldVal
|
||||
console.log 'XXX calling Setscale in scale watch'
|
||||
doRescale newVal
|
||||
element.on 'scroll', () ->
|
||||
console.log 'scroll detected', scope.adjustingScroll
|
||||
updateContainer()
|
||||
scope.$apply()
|
||||
#console.log 'pdfposition', element.parent().scrollTop()
|
||||
if scope.adjustingScroll
|
||||
scope.adjustingScroll = false
|
||||
return
|
||||
#console.log 'not from auto scroll'
|
||||
scope.position = ctrl.getPdfPosition()
|
||||
console.log 'position is', scope.position.page, scope.position.offset
|
||||
scope.$apply()
|
||||
|
||||
scope.$watch 'forceScale', (newVal, oldVal) ->
|
||||
console.log 'got change in numscale watcher', newVal, oldVal
|
||||
return unless newVal?
|
||||
doRescale newVal
|
||||
scope.$watch 'pdfSrc', (newVal, oldVal) ->
|
||||
console.log 'loading pdf', newVal, oldVal
|
||||
return unless newVal?
|
||||
ctrl.load()
|
||||
# trigger a redraw
|
||||
scope.scale = angular.copy (scope.scale)
|
||||
|
||||
scope.$watch 'position', (newVal, oldVal) ->
|
||||
console.log 'got change in position watcher', newVal, oldVal
|
||||
scope.$watch 'scale', (newVal, oldVal) ->
|
||||
# no need to set scale when initialising, done in pdfSrc
|
||||
return if newVal == oldVal
|
||||
console.log 'XXX calling Setscale in scale watch'
|
||||
doRescale newVal
|
||||
|
||||
scope.$watch 'forceCheck', (newVal, oldVal) ->
|
||||
console.log 'forceCheck', newVal, oldVal
|
||||
return unless newVal?
|
||||
scope.adjustingScroll = true # temporarily disable scroll
|
||||
doRescale scope.scale
|
||||
scope.$watch 'forceScale', (newVal, oldVal) ->
|
||||
console.log 'got change in numscale watcher', newVal, oldVal
|
||||
return unless newVal?
|
||||
doRescale newVal
|
||||
|
||||
scope.$watch('parentSize', (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'
|
||||
doRescale scope.scale
|
||||
, true)
|
||||
scope.$watch 'position', (newVal, oldVal) ->
|
||||
console.log 'got change in position watcher', newVal, oldVal
|
||||
|
||||
scope.$watch 'elementWidth', (newVal, oldVal) ->
|
||||
console.log '*** watch INTERVAL element width is', newVal, oldVal
|
||||
scope.$watch 'forceCheck', (newVal, oldVal) ->
|
||||
console.log 'forceCheck', newVal, oldVal
|
||||
return unless newVal?
|
||||
scope.adjustingScroll = true # temporarily disable scroll
|
||||
doRescale scope.scale
|
||||
|
||||
scope.$watch 'pleaseScrollTo', (newVal, oldVal) ->
|
||||
console.log 'got request to ScrollTo', newVal, 'oldVal', oldVal
|
||||
return unless newVal?
|
||||
scope.adjustingScroll = true # temporarily disable scroll
|
||||
# handler while we reposition
|
||||
$(element).scrollTop(newVal)
|
||||
scope.pleaseScrollTo = undefined
|
||||
scope.$watch('parentSize', (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'
|
||||
doRescale scope.scale
|
||||
, true)
|
||||
|
||||
scope.$watch 'pleaseJumpTo', (newPosition, oldPosition) ->
|
||||
console.log 'in pleaseJumpTo', newPosition, oldPosition
|
||||
return unless newPosition?
|
||||
ctrl.setPdfPosition scope.pages[newPosition.page-1], newPosition
|
||||
scope.$watch 'elementWidth', (newVal, oldVal) ->
|
||||
console.log '*** watch INTERVAL element width is', newVal, oldVal
|
||||
|
||||
scope.$watch 'navigateTo', (newVal, oldVal) ->
|
||||
return unless newVal?
|
||||
console.log 'got request to navigate to', newVal, 'oldVal', oldVal
|
||||
scope.navigateTo = undefined
|
||||
console.log 'navigate to', newVal
|
||||
console.log 'look up page num'
|
||||
scope.loaded.then () ->
|
||||
console.log 'destinations are', scope.destinations
|
||||
r = scope.destinations[newVal.dest]
|
||||
console.log 'need to go to', r
|
||||
console.log 'page ref is', r[0]
|
||||
scope.document.getPageIndex(r[0]).then (pidx) ->
|
||||
console.log 'page num is', pidx
|
||||
page = scope.pages[pidx]
|
||||
scope.document.getPdfViewport(page.pageNum).then (viewport) ->
|
||||
console.log 'got viewport', viewport
|
||||
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]
|
||||
newPosition = {page: pidx, offset: {top: r[3], left: r[2]}}
|
||||
ctrl.setPdfPosition scope.pages[pidx], newPosition # XXX?
|
||||
scope.$watch 'pleaseScrollTo', (newVal, oldVal) ->
|
||||
console.log 'got request to ScrollTo', newVal, 'oldVal', oldVal
|
||||
return unless newVal?
|
||||
scope.adjustingScroll = true # temporarily disable scroll
|
||||
# handler while we reposition
|
||||
$(element).scrollTop(newVal)
|
||||
scope.pleaseScrollTo = undefined
|
||||
|
||||
scope.$watch "highlights", (areas) ->
|
||||
console.log 'got HIGHLIGHTS in pdfViewer', areas
|
||||
return if !areas?
|
||||
console.log 'areas are', areas
|
||||
highlights = for area in areas or []
|
||||
{
|
||||
page: area.page - 1
|
||||
highlight:
|
||||
left: area.h
|
||||
top: area.v
|
||||
height: area.height
|
||||
width: area.width
|
||||
}
|
||||
console.log 'highlights', highlights
|
||||
scope.$watch 'pleaseJumpTo', (newPosition, oldPosition) ->
|
||||
console.log 'in pleaseJumpTo', newPosition, oldPosition
|
||||
return unless newPosition?
|
||||
ctrl.setPdfPosition scope.pages[newPosition.page-1], newPosition
|
||||
|
||||
return if !highlights.length
|
||||
scope.$watch 'navigateTo', (newVal, oldVal) ->
|
||||
return unless newVal?
|
||||
console.log 'got request to navigate to', newVal, 'oldVal', oldVal
|
||||
scope.navigateTo = undefined
|
||||
console.log 'navigate to', newVal
|
||||
console.log 'look up page num'
|
||||
scope.loaded.then () ->
|
||||
console.log 'destinations are', scope.destinations
|
||||
r = scope.destinations[newVal.dest]
|
||||
console.log 'need to go to', r
|
||||
console.log 'page ref is', r[0]
|
||||
scope.document.getPageIndex(r[0]).then (pidx) ->
|
||||
console.log 'page num is', pidx
|
||||
page = scope.pages[pidx]
|
||||
scope.document.getPdfViewport(page.pageNum).then (viewport) ->
|
||||
console.log 'got viewport', viewport
|
||||
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]
|
||||
newPosition = {page: pidx, offset: {top: r[3], left: r[2]}}
|
||||
ctrl.setPdfPosition scope.pages[pidx], newPosition # XXX?
|
||||
|
||||
first = highlights[0]
|
||||
scope.$watch "highlights", (areas) ->
|
||||
console.log 'got HIGHLIGHTS in pdfViewer', areas
|
||||
return if !areas?
|
||||
console.log 'areas are', areas
|
||||
highlights = for area in areas or []
|
||||
{
|
||||
page: area.page - 1
|
||||
highlight:
|
||||
left: area.h
|
||||
top: area.v
|
||||
height: area.height
|
||||
width: area.width
|
||||
}
|
||||
console.log 'highlights', highlights
|
||||
|
||||
pageNum = scope.pages[first.page].pageNum
|
||||
return if !highlights.length
|
||||
|
||||
scope.document.getPdfViewport(pageNum).then (viewport) ->
|
||||
position = {
|
||||
page: first.page
|
||||
offset:
|
||||
left: first.highlight.left
|
||||
top: viewport.viewBox[3] - first.highlight.top + first.highlight.height + 72
|
||||
}
|
||||
ctrl.setPdfPosition(scope.pages[first.page], position)
|
||||
first = highlights[0]
|
||||
|
||||
pageNum = scope.pages[first.page].pageNum
|
||||
|
||||
scope.document.getPdfViewport(pageNum).then (viewport) ->
|
||||
position = {
|
||||
page: first.page
|
||||
offset:
|
||||
left: first.highlight.left
|
||||
top: viewport.viewBox[3] - first.highlight.top + first.highlight.height + 72
|
||||
}
|
||||
ctrl.setPdfPosition(scope.pages[first.page], position)
|
||||
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue