// Generated by CoffeeScript 1.8.0 (function() { var app; app = angular.module('pdfViewerApp', ['pdfPage', 'PDFRenderer', 'pdfHighlights']); app.controller('pdfViewerController', [ '$scope', '$q', 'PDFRenderer', '$element', 'pdfHighlights', function($scope, $q, PDFRenderer, $element, pdfHighlights) { this.load = function() { $scope.document = new PDFRenderer($scope.pdfSrc, { scale: 1, navigateFn: function(ref) { $scope.navigateTo = ref; return $scope.$apply(); } }); return $scope.loaded = $q.all({ numPages: $scope.document.getNumPages(), destinations: $scope.document.getDestinations(), pdfViewport: $scope.document.getPdfViewport(1, 1) }).then(function(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); return $scope.numPages = result.numPages; }); }; this.setScale = function(scale, containerHeight, containerWidth) { return $scope.loaded.then(function() { var numScale; if (scale == null) { scale = {}; } if (scale.scaleMode === 'scale_mode_fit_width') { numScale = (containerWidth - 40) / $scope.pdfPageSize[1]; } else if (scale.scaleMode === 'scale_mode_fit_height') { numScale = (containerHeight - 20) / $scope.pdfPageSize[0]; } else if (scale.scaleMode === 'scale_mode_value') { numScale = scale.scale; } else if (scale.scaleMode === 'scale_mode_auto') { } else { scale.scaleMode = 'scale_mode_fit_width'; numScale = (containerWidth - 40) / $scope.pdfPageSize[1]; } $scope.scale.scale = numScale; $scope.document.setScale(numScale); $scope.defaultPageSize = [numScale * $scope.pdfPageSize[0], numScale * $scope.pdfPageSize[1]]; return console.log('in setScale result', $scope.scale.scale, $scope.defaultPageSize); }); }; this.redraw = function(position) { var i, pagenum; console.log('in redraw'); console.log('reseting pages array for', $scope.numPages); console.log('position is', position.page, position.offset); $scope.pages = (function() { var _i, _ref, _results; _results = []; for (i = _i = 0, _ref = $scope.numPages - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { _results.push({ pageNum: i + 1 }); } return _results; })(); if ((position != null) && (position.page != null)) { console.log('setting current page', position.page); pagenum = position.page; $scope.pages[pagenum].current = true; return $scope.pages[pagenum].position = position; } }; this.zoomIn = function() { var newScale; console.log('zoom in'); newScale = $scope.scale.scale * 1.2; return $scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }; }; this.zoomOut = function() { var newScale; console.log('zoom out'); newScale = $scope.scale.scale / 1.2; return $scope.forceScale = { scaleMode: 'scale_mode_value', scale: newScale }; }; this.fitWidth = function() { console.log('fit width'); return $scope.forceScale = { scaleMode: 'scale_mode_fit_width' }; }; this.fitHeight = function() { console.log('fit height'); return $scope.forceScale = { scaleMode: 'scale_mode_fit_height' }; }; this.checkPosition = function() { console.log('check position'); return $scope.forceCheck = ($scope.forceCheck || 0) + 1; }; this.showRandomHighlights = function() { console.log('show highlights'); return $scope.highlights = [ { page: 3, h: 100, v: 100, height: 30, width: 200 } ]; }; this.getPdfPosition = function() { var bottom, canvasOffset, newPosition, pdfOffset, scaledOffset, someContentVisible, top, topPage, topVisible, viewport, viewportHeight, viewportTop, visible; console.log('in getPdfPosition'); visible = function(page, i) { var topPage, topPageIdx; if (page.visible) { topPageIdx = i; return topPage = page; } }; if ($scope.pages.some(visible)) { topPage = visiblePages[0]; } else { console.log('CANNOT FIND TOP PAGE'); topPage = $scope.pages[0]; } 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); 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": topPage.pageNum, "offset": { "top": pdfOffset[1], "left": 0 } }; return newPosition; }; this.computeOffset = function(page, position) { var currentScroll, element, offset, pageTop; 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; return $scope.document.getPdfViewport(page.pageNum).then(function(viewport) { var pageOffset; page.viewport = viewport; pageOffset = viewport.convertToViewportPoint(offset.left, offset.top); console.log('addition offset =', pageOffset); console.log('total', pageTop + pageOffset[1]); return Math.round(pageTop + pageOffset[1] + currentScroll); }); }; this.setPdfPosition = function(page, position) { console.log('required pdf Position is', position); return this.computeOffset(page, position).then(function(offset) { $scope.pleaseScrollTo = offset; return $scope.position = position; }); }; return this; } ]); app.directive('pdfViewer', [ '$q', '$timeout', function($q, $timeout) { return { controller: 'pdfViewerController', controllerAs: 'ctrl', scope: { "pdfSrc": "=", "highlights": "=", "position": "=", "scale": "=", "dblClickCallback": "=", "pleaseJumpTo": "=" }, template: "
", link: function(scope, element, attrs, ctrl) { var doRescale, layoutReady, updateContainer; console.log('in pdfViewer element is', element); console.log('attrs', attrs); layoutReady = $q.defer(); layoutReady.notify('waiting for layout'); layoutReady.promise.then(function() { return console.log('layoutReady was resolved'); }); updateContainer = function() { return scope.containerSize = [element.innerWidth(), element.innerHeight(), element.offset().top]; }; doRescale = function(scale) { var origposition; console.log('doRescale', scale); origposition = angular.copy(scope.position); console.log('origposition', origposition); return layoutReady.promise.then(function() { var h, w, _ref; _ref = [element.innerHeight(), element.width()], h = _ref[0], w = _ref[1]; console.log('in promise', h, w); return ctrl.setScale(scale, h, w).then(function() { return ctrl.redraw(origposition); }); }); }; scope.$on('layout-ready', function() { console.log('GOT LAYOUT READY EVENT'); console.log('calling refresh'); updateContainer(); layoutReady.resolve('layout is ready'); return scope.parentSize = [element.innerHeight(), element.innerWidth()]; }); scope.$on('layout:pdf:resize', function() { console.log('GOT LAYOUT-RESIZE EVENT'); return scope.parentSize = [element.innerHeight(), element.innerWidth()]; }); element.on('scroll', function() { console.log('scroll detected', scope.adjustingScroll); updateContainer(); scope.$apply(); if (scope.adjustingScroll) { scope.adjustingScroll = false; return; } scope.position = ctrl.getPdfPosition(); console.log('position is', scope.position.page, scope.position.offset); return scope.$apply(); }); scope.$watch('pdfSrc', function(newVal, oldVal) { console.log('loading pdf', newVal, oldVal); if (newVal == null) { return; } ctrl.load(); return doRescale(scope.scale); }); scope.$watch('scale', function(newVal, oldVal) { if (newVal === oldVal) { return; } console.log('XXX calling Setscale in scale watch'); return doRescale(newVal); }); scope.$watch('forceScale', function(newVal, oldVal) { console.log('got change in numscale watcher', newVal, oldVal); if (newVal == null) { return; } return doRescale(newVal); }); scope.$watch('position', function(newVal, oldVal) { return 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; return doRescale(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; } if (oldVal == null) { return; } console.log('XXX calling setScale in parentSize watcher'); return doRescale(scope.scale); }, true); scope.$watch('elementWidth', function(newVal, oldVal) { return 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; $(element).scrollTop(newVal); return scope.pleaseScrollTo = void 0; }); 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 = void 0; console.log('navigate to', newVal); console.log('look up page num'); return scope.loaded.then(function() { var r; 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]); return scope.document.getPageIndex(r[0]).then(function(pidx) { console.log('page num is', pidx); return scope.document.getPdfViewport(pidx).then(function(viewport) { var coords, newPosition; 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] } }; return ctrl.setPdfPosition(scope.pages[pidx], newPosition); } }); }); }); }); return scope.$watch("highlights", function(areas) { var area, first, highlights; console.log('got HIGHLIGHTS in pdfViewer', areas); if (areas == null) { return; } console.log('areas are', areas); highlights = (function() { var _i, _len, _ref, _results; _ref = areas || []; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { area = _ref[_i]; _results.push({ page: area.page - 1, highlight: { left: area.h, top: area.v, height: area.height, width: area.width } }); } return _results; })(); console.log('highlights', highlights); if (!highlights.length) { return; } first = highlights[0]; return scope.document.getPdfViewport(first.page).then(function(viewport) { var position; 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); }); }); } }; } ]); }).call(this);