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; +} diff --git a/static/js/annotation.js b/static/js/annotation.js index bf69252..aeda34a 100644 --- a/static/js/annotation.js +++ b/static/js/annotation.js @@ -14,21 +14,17 @@ 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: addNote, submit: function(data) { var note = Ox.getObjectById(annotation.notes, data.id) if (note) { @@ -58,11 +54,26 @@ oml.ui.annotation = function(annotation, $iframe) { id: annotation.id }) } - }).append($quote).append($note); + }).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() { @@ -70,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/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 98a3598..36ad0d8 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,14 @@ 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 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 1372628..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) @@ -49,6 +74,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 +120,7 @@ function onHighlightClicked(e) { other.classList.remove('selected') }) e.target.classList.add('selected') + Ox.$parent.postMessage('selectAnnotation', {id: e.target.dataset.id}) } } @@ -106,24 +144,16 @@ 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) { - /* - 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 + if (selected) { + deselectAllAnnotations() + } + createAnnotation() + } else if (selected) { + console.log('editNote?', selected.dataset.id) + } } if (event.keyCode == 61 && event.shiftKey) { @@ -142,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) @@ -155,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 44ae07b..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) @@ -44,17 +46,25 @@ 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) { - var annot = getHighlight() - renderAnnotation(annot) - addAnnotation(annot) - window.getSelection().removeAllRanges(); + createAnnotation() + } else if (selected) { + console.log('editNote?', selected.dataset.id) } event.stopPropagation() 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) { @@ -89,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); @@ -139,6 +161,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 +169,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()