Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3eb39c0
add NgPdfFactory
endorama Sep 9, 2017
0abc968
start isolating directive scope
endorama Sep 9, 2017
e173b53
move template out of directive
endorama Sep 9, 2017
1679591
move page next-prev to factory
endorama Sep 9, 2017
dc70c7c
move zoom functions to factory
endorama Sep 9, 2017
740eaeb
remove change pdf functionality (temporary)
endorama Sep 9, 2017
53259a0
move fit to page to factory
endorama Sep 9, 2017
11d5a93
refactor fit to page to properly use factory
endorama Sep 9, 2017
a236c52
use url from factory
endorama Sep 9, 2017
b783564
directive renderPage should be private
endorama Sep 9, 2017
577d3f7
remove unused options from template
endorama Sep 9, 2017
240f710
defined options as properties on factory
endorama Sep 9, 2017
8658b0c
use currentPage from factory
endorama Sep 9, 2017
15ff712
check pdfDoc presence in renderPage
endorama Sep 9, 2017
e9b3b5b
move rotate to factory
endorama Sep 9, 2017
4010f34
change page from controller in a sane way
endorama Sep 9, 2017
68d4f3b
fix pdf left rotation
endorama Sep 9, 2017
b84926c
pass url to factory as a proper argument
endorama Sep 9, 2017
67e41cb
directive should properly render pdf again if it changes
endorama Sep 9, 2017
7404096
refactor directive hooks
endorama Sep 9, 2017
fa999c7
disable not implemented features
endorama Sep 9, 2017
a50d845
implement password callback in directive
endorama Sep 11, 2017
7d6944d
implement password callback for controller
endorama Sep 11, 2017
6f33d72
add example for protected pdf
endorama Sep 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@

<div class="wrapper" ng-controller="DocCtrl">
<h1>{{pdfName}}</h1>
<ng-pdf template-url="partials/viewer.html" scale="page-fit" page=13></ng-pdf>
<ng-include src="'partials/viewer.html'"></ng-include>
<ng-pdf pdf="pdfConfig"
on-error="onPdfLoadingError()"
on-progress="onPdfLoadingProgress()"
on-success="onPdfLoadingSuccess()"
on-incorrect-password="onIncorrectPdfPassword()">
</ng-pdf>
</div>

<a href="https://github.com/sayanee/angularjs-pdf"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a>
Expand Down
50 changes: 33 additions & 17 deletions example/js/controllers/docCtrl.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
app.controller('DocCtrl', function($scope) {
app.controller('DocCtrl', function($scope, NgPdfFactory) {

$scope.pdfName = 'Relativity: The Special and General Theory by Albert Einstein';
$scope.pdfUrl = 'pdf/relativity.pdf';
$scope.pdfPassword = 'test';
$scope.scroll = 0;
$scope.loading = 'loading';
$scope.changePdfPage = 1;

$scope.pdfConfig = new NgPdfFactory('pdf/relativity.pdf', { fitToPage: true });
$scope.protectedPdfConfig = new NgPdfFactory('pdf/relativity.protected.pdf', { fitToPage: true, useCredentials: true, password: 'test' });

$scope.$watch('pdfUrl', (newVal, oldVal) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests are broken on PhantomJS with ES6 sintax, maybe we can try to update PhantomJS or use old ES5 sintax?

if (newVal !== '' && newVal !== oldVal) {
$scope.pdfConfig = new NgPdfFactory(newVal, { fitToPage: true });
}
});

$scope.$watch('changePdfPage', (newVal, oldVal) => {
if (newVal !== '' && newVal !== oldVal) {
$scope.pdfConfig.goToPage(newVal)
}
});

$scope.$watch(() => { return $scope.pdfConfig.currentPage }, (newVal, oldVal) => {
if (newVal !== '' && newVal !== oldVal) {
$scope.changePdfPage = newVal;
}
});

$scope.getNavStyle = function(scroll) {
if(scroll > 100) return 'pdf-controls fixed';
else return 'pdf-controls';
}

$scope.onError = function(error) {
console.log(error);
}
$scope.onPdfLoadingSuccess = function() {
console.log('pdf loaded')
};

$scope.onLoad = function() {
$scope.loading = '';
}
$scope.onPdfLoadingProgress = function (progressData) {
console.log('pdf loading on progress', progressData);
};

$scope.onProgress = function (progressData) {
console.log(progressData);
$scope.onPdfLoadingError = function(error) {
console.log('pdf loading error', error);
};

$scope.onPassword = function (updatePasswordFn, passwordResponse) {
if (passwordResponse === PDFJS.PasswordResponses.NEED_PASSWORD) {
updatePasswordFn($scope.pdfPassword);
} else if (passwordResponse === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
console.log('Incorrect password')
}
$scope.onIncorrectPdfPassword = function () {
console.error('password is wrong!');
};

});
20 changes: 10 additions & 10 deletions example/partials/viewer.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<nav ng-class="getNavStyle(scroll)">
<button ng-click="goPrevious()"><span>&lt;</span></button>
<button ng-click="goNext()"><span>&gt;</span></button>
<button ng-click="pdfConfig.goPrevious()"><span>&lt;</span></button>
<button ng-click="pdfConfig.goNext()"><span>&gt;</span></button>

<button ng-click="zoomIn()"><span>+</span></button>
<button ng-click="fit()"><span>100%</span></button>
<button ng-click="zoomOut()"><span>-</span></button>
<button ng-click="pdfConfig.zoomIn()"><span>+</span></button>
<button ng-click="pdfConfig.fit()"><span>100%</span></button>
<button ng-click="pdfConfig.zoomOut()"><span>-</span></button>

<button ng-click="rotate()"><span>90</span></button>
<button ng-click="pdfConfig.rotateLeft()"><span>rotate left</span></button>
<button ng-click="pdfConfig.rotateRight()"><span>rotate right</span></button>

<span>Page: </span>
<input type="text" min=1 ng-model="pageNum">
<span> / {{pageCount}}</span>
<input type="text" min=1 ng-model="$parent.changePdfPage">
<span> / {{pdfConfig.pageCount}}</span>

&nbsp;&nbsp;
<span>Document URL: </span>
<input type="text" ng-model="pdfUrl">
<span>Document URL: <em>{{pdfConfig.url}}</em></span>
</nav>

<hr>
Expand Down
176 changes: 74 additions & 102 deletions src/angular-pdf.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,44 @@ export const NgPdf = ($window, $document, $log) => {
canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
return canvas;
};

const initCanvas = (element, canvas) => {
angular.element(canvas).addClass('rotate0');
element.append(canvas);
};

const onPassword = function (password, incorrectPasswordCallback) {
return function (updatePasswordFn, passwordResponse) {
switch (passwordResponse) {
case PDFJS.PasswordResponses.NEED_PASSWORD:
updatePasswordFn(password);
break;
case PDFJS.PasswordResponses.INCORRECT_PASSWORD:
incorrectPasswordCallback();
break;
}
};
};

return {
restrict: 'E',
templateUrl(element, attr) {
return attr.templateUrl ? attr.templateUrl : 'partials/viewer.html';
scope: {
pdf: '=',
onError: '&',
onProgress: '&',
onSuccess: '&',
onIncorrectPassword: '&'
},
link(scope, element, attrs) {
let renderTask = null;
let pdfLoaderTask = null;
let debug = false;
let url = scope.pdfUrl;
let httpHeaders = scope.httpHeaders;
let pdfDoc = null;
let pageToDisplay = isFinite(attrs.page) ? parseInt(attrs.page) : 1;
let pageFit = attrs.scale === 'page-fit';
let httpHeaders = scope.pdf.httpHeaders;
let limitHeight = attrs.limitcanvasheight === '1';
let scale = attrs.scale > 0 ? attrs.scale : 1;
let pdfDoc = null;
let pageToDisplay = scope.pdf.currentPage;
let canvas = $document[0].createElement('canvas');
initCanvas(element, canvas);
let creds = attrs.usecredentials;
debug = attrs.hasOwnProperty('debug') ? attrs.debug : false;

let ctx = canvas.getContext('2d');
Expand All @@ -61,9 +74,19 @@ export const NgPdf = ($window, $document, $log) => {
});

PDFJS.disableWorker = true;
scope.pageNum = pageToDisplay;

scope.renderPage = num => {
renderPDF()
scope.$watch(() => scope.pdf, (newVal, oldVal) => {
if (newVal !== oldVal) {
renderPDF();
}
});

const renderPage = num => {
if (pdfDoc === null) {
console.warn("pdfDoc is null")
return;
}
if (renderTask) {
renderTask._internalRenderTask.cancel();
}
Expand All @@ -73,16 +96,16 @@ export const NgPdf = ($window, $document, $log) => {
let pageWidthScale;
let renderContext;

if (pageFit) {
if (scope.pdf.fitToPage) {
viewport = page.getViewport(1);
const clientRect = element[0].getBoundingClientRect();
pageWidthScale = clientRect.width / viewport.width;
if (limitHeight) {
pageWidthScale = Math.min(pageWidthScale, clientRect.height / viewport.height);
}
scale = pageWidthScale;
scope.pdf.scale = pageWidthScale;
}
viewport = page.getViewport(scale);
viewport = page.getViewport(scope.pdf.scale);

setCanvasDimensions(canvas, viewport.width, viewport.height);

Expand All @@ -102,57 +125,6 @@ export const NgPdf = ($window, $document, $log) => {
});
};

scope.goPrevious = () => {
if (scope.pageToDisplay <= 1) {
return;
}
scope.pageToDisplay = parseInt(scope.pageToDisplay) - 1;
scope.pageNum = scope.pageToDisplay;
};

scope.goNext = () => {
if (scope.pageToDisplay >= pdfDoc.numPages) {
return;
}
scope.pageToDisplay = parseInt(scope.pageToDisplay) + 1;
scope.pageNum = scope.pageToDisplay;
};

scope.zoomIn = () => {
pageFit = false;
scale = parseFloat(scale) + 0.2;
scope.renderPage(scope.pageToDisplay);
return scale;
};

scope.zoomOut = () => {
pageFit = false;
scale = parseFloat(scale) - 0.2;
scope.renderPage(scope.pageToDisplay);
return scale;
};

scope.fit = () => {
pageFit = true;
scope.renderPage(scope.pageToDisplay);
}

scope.changePage = () => {
scope.renderPage(scope.pageToDisplay);
};

scope.rotate = () => {
if (canvas.getAttribute('class') === 'rotate0') {
canvas.setAttribute('class', 'rotate90');
} else if (canvas.getAttribute('class') === 'rotate90') {
canvas.setAttribute('class', 'rotate180');
} else if (canvas.getAttribute('class') === 'rotate180') {
canvas.setAttribute('class', 'rotate270');
} else {
canvas.setAttribute('class', 'rotate0');
}
};

function clearCanvas() {
if (ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
Expand All @@ -163,64 +135,64 @@ export const NgPdf = ($window, $document, $log) => {
clearCanvas();

let params = {
'url': url,
'withCredentials': creds
'url': scope.pdf.url,
'withCredentials': scope.pdf.useCredentials
};

if (httpHeaders) {
params.httpHeaders = httpHeaders;
}
// if (httpHeaders) {
// params.httpHeaders = httpHeaders;
// }

if (url && url.length) {
if (scope.pdf.url && scope.pdf.url.length) {
pdfLoaderTask = PDFJS.getDocument(params);
pdfLoaderTask.onProgress = scope.onProgress;
pdfLoaderTask.onPassword = scope.onPassword;
pdfLoaderTask.onPassword = onPassword(scope.pdf.password, scope.onIncorrectPassword);
pdfLoaderTask.then(
_pdfDoc => {
if (angular.isFunction(scope.onLoad)) {
scope.onLoad();
}
run_success_hook()

pdfDoc = _pdfDoc;
scope.renderPage(scope.pageToDisplay);
renderPage(scope.pdf.currentPage);

scope.$apply(() => {
scope.pageCount = _pdfDoc.numPages;
scope.pdf.pageCount = _pdfDoc.numPages;
});
}, error => {
if (error) {
if (angular.isFunction(scope.onError)) {
scope.onError(error);
}
}
run_error_hook(error)
}
);
}
}

scope.$watch('pageNum', newVal => {
scope.pageToDisplay = parseInt(newVal);
if (pdfDoc !== null) {
scope.renderPage(scope.pageToDisplay);
}
scope.$watch(() => { return scope.pdf.currentPage }, () => {
renderPage(scope.pdf.currentPage);
});

scope.$watch('pdfUrl', newVal => {
if (newVal !== '') {
if (debug) {
$log.log('pdfUrl value change detected: ', scope.pdfUrl);
}
url = newVal;
scope.pageNum = scope.pageToDisplay = pageToDisplay;
if (pdfLoaderTask) {
pdfLoaderTask.destroy().then(() => {
renderPDF();
});
} else {
renderPDF();
}
scope.$watch(() => { return scope.pdf.scale }, () => {
renderPage(scope.pdf.currentPage);
});

scope.$watch(() => { return scope.pdf.fitToPage }, (newVal) => {
if (newVal === true) {
renderPage(scope.pdf.currentPage);
}
});

scope.$watch(() => { return scope.pdf.rotation }, (newVal) => {
canvas.setAttribute('class', 'rotate'+parseInt(newVal));
})

const run_success_hook = () => {
if (angular.isFunction(scope.onSuccess)) {
scope.onSuccess();
}
};

const run_error_hook = (error) => {
if (angular.isFunction(scope.onError)) {
scope.onError(error);
}
};
}
}
}
Loading