diff --git a/src/PDFJSAnnotate.js b/src/PDFJSAnnotate.js index 77e0cc9e..9bdfa6ca 100644 --- a/src/PDFJSAnnotate.js +++ b/src/PDFJSAnnotate.js @@ -78,7 +78,7 @@ export default { * @param {String} pageNumber The page number * @return {Promise} */ - getAnnotations(documentId, pageNumber) { + getAnnotations(documentId, userId, pageNumber) { return this.getStoreAdapter().getAnnotations(...arguments); }, diff --git a/src/UI/arrow.js b/src/UI/arrow.js index 8dbf4213..b8e66b1c 100644 --- a/src/UI/arrow.js +++ b/src/UI/arrow.js @@ -33,11 +33,11 @@ function handleDocumentMousedown(e) { } let svg = findSVGContainer(target); - let { documentId } = getMetadata(svg); + let { documentId, userId } = getMetadata(svg); let annotationId = target.getAttribute('data-pdf-annotate-id'); let event = e; - PDFJSAnnotate.getStoreAdapter().getAnnotation(documentId, annotationId).then((annotation) => { + PDFJSAnnotate.getStoreAdapter().getAnnotation(documentId, userId, annotationId).then((annotation) => { if (annotation) { path = null; lines = []; diff --git a/src/UI/circle.js b/src/UI/circle.js index bf211cb9..f880b1ce 100644 --- a/src/UI/circle.js +++ b/src/UI/circle.js @@ -59,10 +59,10 @@ function saveCircle(svg, type, pt, radius, color) { r: radius }; - let { documentId, pageNumber } = getMetadata(svg); + let { documentId, userId, pageNumber } = getMetadata(svg); // Add the annotation - PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, pageNumber, annotation) + PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, userId, pageNumber, annotation) .then((annotation) => { appendChild(svg, annotation); }); diff --git a/src/UI/edit.js b/src/UI/edit.js index dc74ecaf..7ef7e432 100644 --- a/src/UI/edit.js +++ b/src/UI/edit.js @@ -225,11 +225,11 @@ function handleDocumentMouseup(e) { let target = document.querySelectorAll(`[data-pdf-annotate-id="${annotationId}"]`); let type = target[0].getAttribute('data-pdf-annotate-type'); let svg = overlay.parentNode.querySelector(config.annotationSvgQuery()); - let { documentId } = getMetadata(svg); + let { documentId, userId } = getMetadata(svg); overlay.querySelector('a').style.display = ''; - PDFJSAnnotate.getStoreAdapter().getAnnotation(documentId, annotationId).then((annotation) => { + PDFJSAnnotate.getStoreAdapter().getAnnotation(documentId, userId, annotationId).then((annotation) => { let attribX = 'x'; let attribY = 'y'; if (['circle', 'fillcircle', 'emptycircle'].indexOf(type) > -1) { diff --git a/src/UI/eraser.js b/src/UI/eraser.js index e9515d15..a9f4b143 100644 --- a/src/UI/eraser.js +++ b/src/UI/eraser.js @@ -19,7 +19,7 @@ function handleDocumentMouseMove(e){ let target = findAnnotationAtPoint(e.clientX, e.clientY); if(target){ console.log(target); - let annotationId = target.getAttribute('data-pdf-annotate-id'); + // let annotationId = target.getAttribute('data-pdf-annotate-id'); // let nodes = document.querySelectorAll(`[data-pdf-annotate-id="${annotationId}"]`); // let svg = overlay.parentNode.querySelector(config.annotationSvgQuery()); // let { documentId } = getMetadata(svg); diff --git a/src/UI/page.js b/src/UI/page.js index 717c0d0d..0a54b4e0 100644 --- a/src/UI/page.js +++ b/src/UI/page.js @@ -48,6 +48,7 @@ export function createPage(pageNumber) { export function renderPage(pageNumber, renderOptions) { let { documentId, + userId, pdfDocument, scale, rotate @@ -56,7 +57,7 @@ export function renderPage(pageNumber, renderOptions) { // Load the page and annotations return Promise.all([ pdfDocument.getPage(pageNumber), - PDFJSAnnotate.getAnnotations(documentId, pageNumber) + PDFJSAnnotate.getAnnotations(documentId, userId, pageNumber) ]).then(([pdfPage, annotations]) => { let page = document.getElementById(`pageContainer${pageNumber}`); let svg = page.querySelector(config.annotationClassQuery()); diff --git a/src/UI/pen.js b/src/UI/pen.js index 85bede78..a323e98c 100644 --- a/src/UI/pen.js +++ b/src/UI/pen.js @@ -41,9 +41,8 @@ function saveToStorage(x, y){ _candraw = false; let svg; if (lines.length > 1 && (svg = findSVGAtPoint(x, y))) { - let { documentId, pageNumber } = getMetadata(svg); - - PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, pageNumber, { + let { documentId, userId, pageNumber } = getMetadata(svg); + PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, userId, pageNumber, { type: 'drawing', width: _penSize, color: _penColor, diff --git a/src/UI/point.js b/src/UI/point.js index fb5da3f6..cde303f3 100644 --- a/src/UI/point.js +++ b/src/UI/point.js @@ -70,7 +70,7 @@ function savePoint() { } let rect = svg.getBoundingClientRect(); - let { documentId, pageNumber } = getMetadata(svg); + let { documentId, userId, pageNumber } = getMetadata(svg); let annotation = Object.assign({ type: 'point' }, scaleDown(svg, { @@ -79,7 +79,7 @@ function savePoint() { }) ); - PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, pageNumber, annotation) + PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, userId, pageNumber, annotation) .then((annotation) => { PDFJSAnnotate.getStoreAdapter().addComment( documentId, diff --git a/src/UI/rect.js b/src/UI/rect.js index 0f1b9c4f..fa7c2af3 100644 --- a/src/UI/rect.js +++ b/src/UI/rect.js @@ -195,10 +195,10 @@ function saveRect(type, rects, color) { annotation.height = rect.height; } - let { documentId, pageNumber } = getMetadata(svg); + let { documentId, userId, pageNumber } = getMetadata(svg); // Add the annotation - PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, pageNumber, annotation) + PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, userId, pageNumber, annotation) .then((annotation) => { appendChild(svg, annotation); }); diff --git a/src/UI/text.js b/src/UI/text.js index 120b39d8..e571f276 100644 --- a/src/UI/text.js +++ b/src/UI/text.js @@ -71,7 +71,7 @@ function saveText() { return; } let height = _textSize; - let { documentId, pageNumber, viewport } = getMetadata(svg); + let { documentId, userId, pageNumber, viewport } = getMetadata(svg); let scale = 1 / viewport.scale; let rect = svg.getBoundingClientRect(); let pt = convertToSvgPoint([ @@ -87,7 +87,7 @@ function saveText() { rotation: -viewport.rotation } - PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, pageNumber, annotation) + PDFJSAnnotate.getStoreAdapter().addAnnotation(documentId, userId, pageNumber, annotation) .then((annotation) => { appendChild(svg, annotation); }); diff --git a/src/UI/utils.js b/src/UI/utils.js index e8078765..fd59d3b2 100644 --- a/src/UI/utils.js +++ b/src/UI/utils.js @@ -264,6 +264,7 @@ export function enableUserSelect() { export function getMetadata(svg) { return { documentId: svg.getAttribute('data-pdf-annotate-document'), + userId: svg.getAttribute('data-pdf-annotate-user'), pageNumber: parseInt(svg.getAttribute('data-pdf-annotate-page'), 10), viewport: JSON.parse(svg.getAttribute('data-pdf-annotate-viewport')) }; diff --git a/src/a11y/initEventHandlers.js b/src/a11y/initEventHandlers.js index f0243daa..b5d15127 100644 --- a/src/a11y/initEventHandlers.js +++ b/src/a11y/initEventHandlers.js @@ -9,11 +9,11 @@ import PDFJSAnnotate from '../PDFJSAnnotate'; * Initialize the event handlers for keeping screen reader hints synced with data */ export default function initEventHandlers() { - addEventListener('annotation:add', (documentId, pageNumber, annotation) => { - reorderAnnotationsByType(documentId, pageNumber, annotation.type); + addEventListener('annotation:add', (documentId, userId, pageNumber, annotation) => { + reorderAnnotationsByType(documentId, userId, pageNumber, annotation.type); }); - addEventListener('annotation:edit', (documentId, annotationId, annotation) => { - reorderAnnotationsByType(documentId, annotation.page, annotation.type); + addEventListener('annotation:edit', (documentId, userId, annotationId, annotation) => { + reorderAnnotationsByType(documentId, userId, annotation.page, annotation.type); }); addEventListener('annotation:delete', removeAnnotation); addEventListener('comment:add', insertComment); @@ -24,11 +24,12 @@ export default function initEventHandlers() { * Reorder the annotation numbers by annotation type * * @param {String} documentId The ID of the document + * @param {String} userId The ID of the user * @param {Number} pageNumber The page number of the annotations * @param {Strig} type The annotation type */ -function reorderAnnotationsByType(documentId, pageNumber, type) { - PDFJSAnnotate.getStoreAdapter().getAnnotations(documentId, pageNumber) +function reorderAnnotationsByType(documentId, userId, pageNumber, type) { + PDFJSAnnotate.getStoreAdapter().getAnnotations(documentId, userId, pageNumber) .then((annotations) => { return annotations.annotations.filter((a) => { return a.type === type; diff --git a/src/adapter/LocalStoreAdapter.js b/src/adapter/LocalStoreAdapter.js index 72a04c89..2cb6f0c8 100644 --- a/src/adapter/LocalStoreAdapter.js +++ b/src/adapter/LocalStoreAdapter.js @@ -6,70 +6,71 @@ import StoreAdapter from './StoreAdapter'; export default class LocalStoreAdapter extends StoreAdapter { constructor() { super({ - getAnnotations(documentId, pageNumber) { + getAnnotations(documentId, userId, pageNumber) { return new Promise((resolve, reject) => { - let annotations = getAnnotations(documentId).filter((i) => { + let annotations = getAnnotations(documentId, userId).filter((i) => { return i.page === pageNumber && i.class === 'Annotation'; }); resolve({ documentId, + userId, pageNumber, annotations }); }); }, - getAnnotation(documentId, annotationId) { - return Promise.resolve(getAnnotations(documentId)[findAnnotation(documentId, annotationId)]); + getAnnotation(documentId, userId, annotationId) { + return Promise.resolve(getAnnotations(documentId, userId)[findAnnotation(documentId, userId, annotationId)]); }, - addAnnotation(documentId, pageNumber, annotation) { + addAnnotation(documentId, userId, pageNumber, annotation) { return new Promise((resolve, reject) => { annotation.class = 'Annotation'; annotation.uuid = uuid(); annotation.page = pageNumber; - let annotations = getAnnotations(documentId); + let annotations = getAnnotations(documentId, userId); annotations.push(annotation); - updateAnnotations(documentId, annotations); + updateAnnotations(documentId, userId, annotations); resolve(annotation); }); }, - editAnnotation(documentId, annotationId, annotation) { + editAnnotation(documentId, userId, annotationId, annotation) { return new Promise((resolve, reject) => { - let annotations = getAnnotations(documentId); - annotations[findAnnotation(documentId, annotationId)] = annotation; - updateAnnotations(documentId, annotations); + let annotations = getAnnotations(documentId, userId); + annotations[findAnnotation(documentId, userId, annotationId)] = annotation; + updateAnnotations(documentId, userId, annotations); resolve(annotation); }); }, - deleteAnnotation(documentId, annotationId) { + deleteAnnotation(documentId, userId, annotationId) { return new Promise((resolve, reject) => { - let index = findAnnotation(documentId, annotationId); + let index = findAnnotation(documentId, userId, annotationId); if (index > -1) { - let annotations = getAnnotations(documentId); + let annotations = getAnnotations(documentId, userId); annotations.splice(index, 1); - updateAnnotations(documentId, annotations); + updateAnnotations(documentId, userId, annotations); } resolve(true); }); }, - getComments(documentId, annotationId) { + getComments(documentId, userId, annotationId) { return new Promise((resolve, reject) => { - resolve(getAnnotations(documentId).filter((i) => { + resolve(getAnnotations(documentId, userId).filter((i) => { return i.class === 'Comment' && i.annotation === annotationId; })); }); }, - addComment(documentId, annotationId, content) { + addComment(documentId, userId, annotationId, content) { return new Promise((resolve, reject) => { let comment = { class: 'Comment', @@ -78,19 +79,19 @@ export default class LocalStoreAdapter extends StoreAdapter { content: content }; - let annotations = getAnnotations(documentId); + let annotations = getAnnotations(documentId, userId); annotations.push(comment); - updateAnnotations(documentId, annotations); + updateAnnotations(documentId, userId, annotations); resolve(comment); }); }, - deleteComment(documentId, commentId) { + deleteComment(documentId, userId, commentId) { return new Promise((resolve, reject) => { - getAnnotations(documentId); + getAnnotations(documentId, userId); let index = -1; - let annotations = getAnnotations(documentId); + let annotations = getAnnotations(documentId, userId); for (let i=0, l=annotations.length; i -1) { annotations.splice(index, 1); - updateAnnotations(documentId, annotations); + updateAnnotations(documentId, userId, annotations); } resolve(true); @@ -110,17 +111,17 @@ export default class LocalStoreAdapter extends StoreAdapter { } } -function getAnnotations(documentId) { - return JSON.parse(localStorage.getItem(`${documentId}/annotations`)) || []; +function getAnnotations(documentId, userId) { + return JSON.parse(localStorage.getItem(`${documentId}/${userId}/annotations`)) || []; } - -function updateAnnotations(documentId, annotations) { - localStorage.setItem(`${documentId}/annotations`, JSON.stringify(annotations)); +// Note, userId should not be an optional parameter, leaving it here for debugging purposes +function updateAnnotations(documentId, userId='bitdiddle', annotations) { + localStorage.setItem(`${documentId}/${userId}/annotations`, JSON.stringify(annotations)); } -function findAnnotation(documentId, annotationId) { +function findAnnotation(documentId, userId, annotationId) { let index = -1; - let annotations = getAnnotations(documentId); + let annotations = getAnnotations(documentId, userId); for (let i=0, l=annotations.length; i { // TODO may be best to have this happen on the server if (annotations.annotations) { @@ -58,12 +58,12 @@ export default class StoreAdapter { * @param {Object} annotation The definition for the new annotation * @return {Promise} */ - __addAnnotation(documentId, pageNumber, annotation) { abstractFunction('addAnnotation'); } + __addAnnotation(documentId, userId, pageNumber, annotation) { abstractFunction('addAnnotation'); } get addAnnotation() { return this.__addAnnotation; } set addAnnotation(fn) { - this.__addAnnotation = function addAnnotation(documentId, pageNumber, annotation) { + this.__addAnnotation = function addAnnotation(documentId, userId, pageNumber, annotation) { return fn(...arguments).then((annotation) => { - fireEvent('annotation:add', documentId, pageNumber, annotation); + fireEvent('annotation:add', documentId, userId, pageNumber, annotation); return annotation; }); }; diff --git a/src/render/index.js b/src/render/index.js index acce9d2a..3262fb4d 100644 --- a/src/render/index.js +++ b/src/render/index.js @@ -28,6 +28,7 @@ export default function render(svg, viewport, data) { } svg.setAttribute('data-pdf-annotate-document', data.documentId); + svg.setAttribute('data-pdf-annotate-user', data.userId); svg.setAttribute('data-pdf-annotate-page', data.pageNumber); // Make sure annotations is an array diff --git a/web/index.js b/web/index.js index 548d2bd6..a0a51933 100644 --- a/web/index.js +++ b/web/index.js @@ -7,6 +7,7 @@ const documentId = 'example.pdf'; let PAGE_HEIGHT; let RENDER_OPTIONS = { documentId, + userId: 'aphacker', pdfDocument: null, scale: parseFloat(localStorage.getItem(`${documentId}/scale`), 10) || 1.33, rotate: parseInt(localStorage.getItem(`${documentId}/rotate`), 10) || 0 @@ -383,7 +384,7 @@ render(); document.querySelector(`div#pageContainer${i+1} svg.annotationLayer`).innerHTML = ''; } - localStorage.removeItem(`${RENDER_OPTIONS.documentId}/annotations`); + localStorage.removeItem(`${RENDER_OPTIONS.documentId}/${RENDER_OPTIONS.userId}/annotations`); } } document.querySelector('a.clear').addEventListener('click', handleClearClick);