From 8bb7503675437b6f0daa8493b7fc87d3df13ca5b Mon Sep 17 00:00:00 2001 From: j Date: Thu, 31 Jan 2019 23:02:17 +0530 Subject: [PATCH 1/4] add Add note placeholder --- static/js/annotation.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/static/js/annotation.js b/static/js/annotation.js index bf69252..64d42de 100644 --- a/static/js/annotation.js +++ b/static/js/annotation.js @@ -14,21 +14,28 @@ oml.ui.annotation = function(annotation, $iframe) { var notes = annotation.notes.length ? annotation.notes.map(function(note) { note.editable = !note.user return note - }) : [{ - id: 'A', - placeholder: 'Add Note', - value: '', - editable: true - }]; + }) : [] console.log(annotation.notes) - var $note = Ox.ArrayEditable({ + var $notes = Ox.ArrayEditable({ editing: true, items: notes, + placeholder: 'Add note', type: 'textarea' }).css({ margin: '2px', minHeight: '12px' }).bindEvent({ + doubleclick: function(data) { + if (!$notes.options('items').length) { + $notes.addItem(0, { + id: 'A', + value: '', + editable: true + }).options({ + selected: 'A' + }).editItem() + } + }, submit: function(data) { var note = Ox.getObjectById(annotation.notes, data.id) if (note) { @@ -58,7 +65,7 @@ oml.ui.annotation = function(annotation, $iframe) { id: annotation.id }) } - }).append($quote).append($note); + }).append($quote).append($notes); that.annotate = function() { var item = { From 8ab9ac958827b6ac9cf6d588e79318a77d817d4d Mon Sep 17 00:00:00 2001 From: j Date: Thu, 31 Jan 2019 23:07:24 +0530 Subject: [PATCH 2/4] only show Add note for selected annotation --- static/css/oml.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/static/css/oml.css b/static/css/oml.css index 382cccd..33ae71b 100644 --- a/static/css/oml.css +++ b/static/css/oml.css @@ -9,3 +9,10 @@ .OMLAnnotation.selected .OMLQuote { background-color: rgb(128, 192, 255); } + +.OMLAnnotation .OxPlaceholder { + display: none; +} +.OMLAnnotation.selected .OxPlaceholder { + display: block; +} From fedd0c7e80fd1c34f55af9e7f3e6e8bb9beb7cee Mon Sep 17 00:00:00 2001 From: j Date: Fri, 1 Feb 2019 00:12:52 +0530 Subject: [PATCH 3/4] enter to add annotation --- static/js/annotation.js | 35 +++++++++++++++++++++-------------- static/js/viewer.js | 8 ++++---- static/reader/epub.js | 22 +++++++++++++++++++++- static/reader/pdf.js | 23 ++++++++++++++++++++++- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/static/js/annotation.js b/static/js/annotation.js index 64d42de..aeda34a 100644 --- a/static/js/annotation.js +++ b/static/js/annotation.js @@ -15,7 +15,6 @@ oml.ui.annotation = function(annotation, $iframe) { note.editable = !note.user return note }) : [] - console.log(annotation.notes) var $notes = Ox.ArrayEditable({ editing: true, items: notes, @@ -25,17 +24,7 @@ oml.ui.annotation = function(annotation, $iframe) { margin: '2px', minHeight: '12px' }).bindEvent({ - doubleclick: function(data) { - if (!$notes.options('items').length) { - $notes.addItem(0, { - id: 'A', - value: '', - editable: true - }).options({ - selected: 'A' - }).editItem() - } - }, + doubleclick: addNote, submit: function(data) { var note = Ox.getObjectById(annotation.notes, data.id) if (note) { @@ -67,9 +56,24 @@ oml.ui.annotation = function(annotation, $iframe) { } }).append($quote).append($notes); + + function addNote() { + if (!$notes.options('items').length) { + that.select() + $notes.addItem(0, { + id: 'A', + value: '', + editable: true + }).options({ + selected: 'A' + }).editItem() + } + } + + that.annotate = function() { - var item = { - id: 'note', value: '', editable: true + if (oml.user.ui.showAnnotations) { + addNote() } } that.deselect = function() { @@ -77,6 +81,9 @@ oml.ui.annotation = function(annotation, $iframe) { that.loseFocus() } that.select = function () { + $iframe.postMessage('selectAnnotation', { + id: annotation.id + }) let selected = document.querySelector('.OMLAnnotation.selected') selected && selected.classList.remove('selected') that.addClass('selected') diff --git a/static/js/viewer.js b/static/js/viewer.js index 98a3598..d0a4e70 100644 --- a/static/js/viewer.js +++ b/static/js/viewer.js @@ -95,7 +95,6 @@ oml.ui.viewer = function() { height: '100%', border: 0 }).onMessage(function(data, event) { - console.log('got', event, data) if (event == 'addAnnotation') { console.log('adding', data.id) saveAnnotations(data); @@ -107,11 +106,12 @@ oml.ui.viewer = function() { removeAnnotation(data.id) } else if (event == 'selectAnnotation') { var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id) - $annotation.select() + $annotation && $annotation.select() } else if (event == 'deselectAnnotation') { - var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id) - $annotation.deselect() + var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id)[0] + $annotation && $annotation.deselect() } else { + console.log('got', event, data) that.triggerEvent(event, data); } diff --git a/static/reader/epub.js b/static/reader/epub.js index 1372628..12f2483 100644 --- a/static/reader/epub.js +++ b/static/reader/epub.js @@ -49,6 +49,18 @@ function deselectAnnotation(id) { }) } + +function deselectAllAnnotations() { + var ids = [] + document.querySelectorAll('.epubjs-hl.selected').forEach(function(g) { + g.classList.remove('selected') + if (!Ox.contains(ids, id)) { + ids.push(id) + Ox.$parent.postMessage('deselectAnnotation', {id: id}) + } + }) +} + function removeAnnotation(id) { var a = annotations.filter(function(a) { return a.id == id })[0] if (a) { @@ -83,6 +95,7 @@ function onHighlightClicked(e) { other.classList.remove('selected') }) e.target.classList.add('selected') + Ox.$parent.postMessage('selectAnnotation', {id: e.target.dataset.id}) } } @@ -106,8 +119,12 @@ document.onreadystatechange = function () { removeAnnotation(a.dataset.id) }) } - if (event.key == 'n') { + if (event.key == 'n' || event.keyCode == 13) { + var selected = document.querySelector('.epubjs-hl.selected') if (currentSelection) { + if (selected) { + deselectAllAnnotations() + } /* var range = currentSelection.contents.window.getSelection().getRangeAt(0) console.log( @@ -124,6 +141,9 @@ document.onreadystatechange = function () { other.classList.remove('selected') }) currentSelection = null + } else if (selected) { + console.log('editNote?', selected.dataset.id) + } } if (event.keyCode == 61 && event.shiftKey) { diff --git a/static/reader/pdf.js b/static/reader/pdf.js index 44ae07b..d0cd52f 100644 --- a/static/reader/pdf.js +++ b/static/reader/pdf.js @@ -44,12 +44,18 @@ window.addEventListener('keydown', function(event) { if (selected) { removeAnnotation(selected.dataset.id) } - } else if (event.key == 'n') { + } else if (event.key == 'n' || event.keyCode == 13) { + var selected = document.querySelector('.oml-annotation.selected') if (!window.getSelection().isCollapsed) { + if (selected) { + deselectAllAnnotations() + } var annot = getHighlight() renderAnnotation(annot) addAnnotation(annot) window.getSelection().removeAllRanges(); + } else if (selected) { + console.log('editNote?', selected.dataset.id) } event.stopPropagation() event.preventDefault() @@ -139,6 +145,7 @@ function selectAnnotation(id) { g.style.backgroundColor = 'blue' }) } + function deselectAnnotation(id) { document.querySelectorAll('.oml-annotation.a' + id).forEach(function(g) { g.classList.remove('selected') @@ -146,6 +153,20 @@ function deselectAnnotation(id) { }) } +function deselectAllAnnotations() { + var ids = [] + document.querySelectorAll('.oml-annotation.selected').forEach(function(g) { + g.classList.remove('selected') + g.style.backgroundColor = 'yellow' + var id = $(g).parents('.oml-annotation').data('id') + console.log('deselect', g, id) + if (!Ox.contains(ids, id)) { + ids.push(id) + Ox.$parent.postMessage('deselectAnnotation', {id: id}) + } + }) +} + function removeAnnotation(id) { document.querySelectorAll('.oml-annotation.a' + id).forEach(function(a) { a.remove() From fe9b0618edb176eb1871191c77ce9d32cdc86816 Mon Sep 17 00:00:00 2001 From: j Date: Fri, 1 Feb 2019 01:02:55 +0530 Subject: [PATCH 4/4] add annotation event from annotation panel --- static/js/annotationPanel.js | 10 +++++++ static/js/viewer.js | 2 ++ static/reader/epub.js | 54 ++++++++++++++++++++++++------------ static/reader/pdf.js | 30 +++++++++++++++----- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/static/js/annotationPanel.js b/static/js/annotationPanel.js index 428afcc..ffae227 100644 --- a/static/js/annotationPanel.js +++ b/static/js/annotationPanel.js @@ -10,6 +10,10 @@ oml.ui.annotationPanel = function() { title: 'add', tooltip: Ox._('Add Quote'), type: 'image' + }).bindEvent({ + click: function() { + oml.$ui.viewer.postMessage('addAnnotation', {}) + } }).appendTo($bar); var $menuButton = Ox.MenuButton({ @@ -50,6 +54,12 @@ oml.ui.annotationPanel = function() { orientation: 'vertical' }); + that.updateSelection = function(selection) { + $button.options({ + disabled: !selection + }) + } + return that; }; diff --git a/static/js/viewer.js b/static/js/viewer.js index d0a4e70..36ad0d8 100644 --- a/static/js/viewer.js +++ b/static/js/viewer.js @@ -110,6 +110,8 @@ oml.ui.viewer = function() { } else if (event == 'deselectAnnotation') { var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id)[0] $annotation && $annotation.deselect() + } else if (event == 'selection') { + oml.$ui.annotationPanel.updateSelection(data) } else { console.log('got', event, data) that.triggerEvent(event, data); diff --git a/static/reader/epub.js b/static/reader/epub.js index 12f2483..14a309d 100644 --- a/static/reader/epub.js +++ b/static/reader/epub.js @@ -18,6 +18,8 @@ Ox.load({ if (annotation) { reader.rendition.display(annotation.cfiRange) } + } else if (event == 'addAnnotation') { + createAnnotation() } else if (event == 'addAnnotations') { data.annotations.forEach(function(annotation) { annotations.push(annotation) @@ -29,6 +31,29 @@ Ox.load({ }) }) + +function createAnnotation() { + console.log('createAnnotation', currentSelection) + if (currentSelection) { + /* + var range = currentSelection.contents.window.getSelection().getRangeAt(0) + console.log( + currentSelection.cfiRange, + reader.rendition.book.section().cfiFromRange(range).toString() + ) + //currentSelection.cfiRange = reader.rendition.book.section().cfiFromRange(range).toString() + */ + renderAnnotation(currentSelection) + currentSelection.contents.window.getSelection().removeAllRanges(); + delete currentSelection.contents + addAnnotation(currentSelection) + document.querySelectorAll('.epubjs-hl.selected').forEach(function(other) { + other.classList.remove('selected') + }) + currentSelection = null + } +} + function addAnnotation(annotation) { annotations.push(annotation) Ox.$parent.postMessage('addAnnotation', annotation) @@ -125,22 +150,7 @@ document.onreadystatechange = function () { if (selected) { deselectAllAnnotations() } - /* - var range = currentSelection.contents.window.getSelection().getRangeAt(0) - console.log( - currentSelection.cfiRange, - reader.rendition.book.section().cfiFromRange(range).toString() - ) - //currentSelection.cfiRange = reader.rendition.book.section().cfiFromRange(range).toString() - */ - renderAnnotation(currentSelection) - currentSelection.contents.window.getSelection().removeAllRanges(); - delete currentSelection.contents - addAnnotation(currentSelection) - document.querySelectorAll('.epubjs-hl.selected').forEach(function(other) { - other.classList.remove('selected') - }) - currentSelection = null + createAnnotation() } else if (selected) { console.log('editNote?', selected.dataset.id) @@ -162,7 +172,16 @@ document.onreadystatechange = function () { localStorage.epubFontSize = fontSize event.preventDefault() } - console.log(fontSize) + }).on('mouseup', function(event) { + if (currentSelection) { + var selection = window.getSelection() + if (selection.isCollapsed) { + currentSelection = null + } + if (!currentSelection) { + Ox.$parent.postMessage('selection', false) + } + } }) rendition.on("mark", function(cfiRange, contents) { console.log('!! mark', cfiRange) @@ -175,6 +194,7 @@ document.onreadystatechange = function () { text: text, contents: contents } + Ox.$parent.postMessage('selection', text ? true : false) }) }); } diff --git a/static/reader/pdf.js b/static/reader/pdf.js index d0cd52f..164fba9 100644 --- a/static/reader/pdf.js +++ b/static/reader/pdf.js @@ -27,6 +27,8 @@ Ox.load({ } }, delay) selectAnnotation(data.id) + } else if (event == 'addAnnotation') { + createAnnotation() } else if (event == 'addAnnotations') { data.annotations.forEach(function(annotation) { annotations.push(annotation) @@ -47,13 +49,7 @@ window.addEventListener('keydown', function(event) { } else if (event.key == 'n' || event.keyCode == 13) { var selected = document.querySelector('.oml-annotation.selected') if (!window.getSelection().isCollapsed) { - if (selected) { - deselectAllAnnotations() - } - var annot = getHighlight() - renderAnnotation(annot) - addAnnotation(annot) - window.getSelection().removeAllRanges(); + createAnnotation() } else if (selected) { console.log('editNote?', selected.dataset.id) } @@ -61,6 +57,14 @@ window.addEventListener('keydown', function(event) { event.preventDefault() } }) +window.addEventListener('mouseup', function(event) { + var selection = window.getSelection() + if (selection.isCollapsed) { + Ox.$parent.postMessage('selection', false) + } else { + Ox.$parent.postMessage('selection', true) + } +}) function bindEvents() { if (!window.PDFViewerApplication || !window.PDFViewerApplication.eventBus) { @@ -95,6 +99,18 @@ function getHighlight() { }; } +function createAnnotation() { + var selected = document.querySelector('.oml-annotation.selected') + if (selected) { + deselectAllAnnotations() + } + var annot = getHighlight() + renderAnnotation(annot) + addAnnotation(annot) + window.getSelection().removeAllRanges(); +} + + function renderAnnotation(annotation) { var pageIndex = annotation.page - 1; var page = PDFViewerApplication.pdfViewer.getPageView(pageIndex);