mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More work on editing notes in the content server
This commit is contained in:
parent
72ab25a5b8
commit
a3becde4de
@ -98,7 +98,9 @@ def show_note_url(book_id, field, item_id, item_value, library_id=None, close_ac
|
|||||||
|
|
||||||
def show_note(book_id, field, item_id, item_value, replace=False, library_id=None, close_action='back', panel='show_note'):
|
def show_note(book_id, field, item_id, item_value, replace=False, library_id=None, close_action='back', panel='show_note'):
|
||||||
lid = library_id or current_library_id()
|
lid = library_id or current_library_id()
|
||||||
q = {'book_id':book_id, 'field': field, 'item':item_value, 'item_id': item_id, 'panel': panel, 'close_action': close_action}
|
q = {'book_id':book_id, 'field': field, 'item':item_value, 'item_id': item_id, 'panel': panel}
|
||||||
|
if panel is 'show_note':
|
||||||
|
q.close_action = close_action
|
||||||
if lid:
|
if lid:
|
||||||
q.library_id = lid
|
q.library_id = lid
|
||||||
push_state(q, replace=replace)
|
push_state(q, replace=replace)
|
||||||
|
@ -3,23 +3,56 @@
|
|||||||
from __python__ import bound_methods, hash_literals
|
from __python__ import bound_methods, hash_literals
|
||||||
|
|
||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
|
|
||||||
from ajax import ajax
|
from ajax import ajax
|
||||||
|
from book_list.comments_editor import (
|
||||||
|
create_comments_editor, focus_comments_editor, get_comments_html, set_comments_html
|
||||||
|
)
|
||||||
from book_list.details_list import sandbox_css
|
from book_list.details_list import sandbox_css
|
||||||
from book_list.router import back, home
|
from book_list.router import back, home, show_note
|
||||||
from book_list.top_bar import create_top_bar
|
from book_list.top_bar import add_button, create_top_bar
|
||||||
from book_list.ui import set_panel_handler
|
from book_list.ui import set_panel_handler
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from utils import parse_url_params, sandboxed_html
|
from utils import parse_url_params, safe_set_inner_html, sandboxed_html
|
||||||
|
|
||||||
|
|
||||||
|
def message_from_iframe(ev):
|
||||||
|
c = document.getElementById(current_container_id)
|
||||||
|
if c and c.lastChild:
|
||||||
|
iframe = c.querySelector('iframe')
|
||||||
|
if iframe and ev.source is iframe.contentWindow:
|
||||||
|
if ev.data.key:
|
||||||
|
ev.data.from_iframe = True
|
||||||
|
close_action = get_close_action()[0]
|
||||||
|
onkeydown(current_container_id, close_action, ev.data)
|
||||||
|
|
||||||
|
|
||||||
def make_iframe(html):
|
def make_iframe(html):
|
||||||
iframe = sandboxed_html(html, sandbox_css() + '\n\nhtml { overflow: visible; margin: 0.5rem; }')
|
html += '''
|
||||||
|
<script>
|
||||||
|
function onkeydown(ev) {
|
||||||
|
ev.preventDefault()
|
||||||
|
ev.stopPropagation()
|
||||||
|
msg = {
|
||||||
|
key: ev.key, altKey: ev.altKey, ctrlKey: ev.ctrlKey, code: ev.code, isComposing: ev.isComposing,
|
||||||
|
repeat: ev.repeat, shiftKey: ev.shiftKey, metaKey: ev.metaKey,
|
||||||
|
}
|
||||||
|
window.parent.postMessage(msg, '*')
|
||||||
|
}
|
||||||
|
document.onkeydown = onkeydown
|
||||||
|
''' + '<' + '/script>'
|
||||||
|
iframe = sandboxed_html(html, sandbox_css() + '\n\nhtml { overflow: visible; margin: 0.5rem; }', 'allow-scripts')
|
||||||
|
iframe.tabIndex = -1 # prevent tab from focusing this iframe
|
||||||
iframe.style.width = '100%'
|
iframe.style.width = '100%'
|
||||||
iframe.style.flexGrow = '10'
|
iframe.style.flexGrow = '10'
|
||||||
|
if not message_from_iframe.added:
|
||||||
|
message_from_iframe.added = True
|
||||||
|
window.addEventListener('message', message_from_iframe, False)
|
||||||
return iframe
|
return iframe
|
||||||
|
|
||||||
|
|
||||||
current_note_markup = None
|
current_note_markup = None
|
||||||
|
current_container_id = ''
|
||||||
|
|
||||||
|
|
||||||
def on_notes_fetched(load_type, xhr, ev):
|
def on_notes_fetched(load_type, xhr, ev):
|
||||||
@ -30,55 +63,106 @@ def on_notes_fetched(load_type, xhr, ev):
|
|||||||
q.html = xhr.responseText
|
q.html = xhr.responseText
|
||||||
current_note_markup = q
|
current_note_markup = q
|
||||||
else:
|
else:
|
||||||
|
current_note_markup = None
|
||||||
html = xhr.error_html
|
html = xhr.error_html
|
||||||
iframe = make_iframe(html)
|
|
||||||
container = document.getElementById(this)
|
container = document.getElementById(this)
|
||||||
old = container.querySelector('div.loading')
|
old = container.querySelector('div.loading')
|
||||||
p = old.parentNode
|
p = old.parentNode
|
||||||
p.removeChild(old)
|
p.removeChild(old)
|
||||||
if q.panel is 'show_note':
|
if q.panel is 'show_note':
|
||||||
|
iframe = make_iframe(html)
|
||||||
p.appendChild(iframe)
|
p.appendChild(iframe)
|
||||||
elif q.panel is 'edit_note':
|
elif q.panel is 'edit_note':
|
||||||
create_editor(container, current_note_markup.html)
|
if current_note_markup:
|
||||||
|
create_editor(container.lastChild, current_note_markup.html)
|
||||||
|
else:
|
||||||
|
container.appendChild(E.div())
|
||||||
|
safe_set_inner_html(container.lastChild, html)
|
||||||
|
|
||||||
|
|
||||||
def init(container_id):
|
def edit_note():
|
||||||
container = document.getElementById(container_id)
|
|
||||||
close_action, close_icon = back, 'close'
|
|
||||||
q = parse_url_params()
|
q = parse_url_params()
|
||||||
ca = q.close_action
|
show_note(q.book_id, q.field, q.item_id, q.item, library_id=q.library_id, panel='edit_note')
|
||||||
if ca is 'home':
|
|
||||||
close_action, close_icon = def(): home();, 'home'
|
|
||||||
create_top_bar(container, title=q.item, action=close_action, icon=close_icon)
|
def onkeydown(container_id, close_action, ev):
|
||||||
|
if ev.key is 'Escape':
|
||||||
|
if not ev.from_iframe:
|
||||||
|
ev.preventDefault(), ev.stopPropagation()
|
||||||
|
close_action()
|
||||||
|
elif ev.key is 'e' or ev.key is 'E':
|
||||||
|
q = parse_url_params()
|
||||||
|
if q.panel is 'show_note':
|
||||||
|
if not ev.from_iframe:
|
||||||
|
ev.preventDefault(), ev.stopPropagation()
|
||||||
|
edit_note()
|
||||||
|
|
||||||
|
|
||||||
|
def setup_container(container, close_action):
|
||||||
container.style.height = '100vh'
|
container.style.height = '100vh'
|
||||||
container.style.display = 'flex'
|
container.style.display = 'flex'
|
||||||
container.style.flexDirection = 'column'
|
container.style.flexDirection = 'column'
|
||||||
|
container.appendChild(E.div(tabindex='0', style='flex-grow: 10; display: flex; align-items: stretch'))
|
||||||
|
container.lastChild.addEventListener('keydown', onkeydown.bind(None, container.id, close_action), {'passive': False, 'capture': True})
|
||||||
|
container.lastChild.focus()
|
||||||
|
|
||||||
|
|
||||||
|
def get_close_action():
|
||||||
|
q = parse_url_params()
|
||||||
|
if q.panel is 'show_note':
|
||||||
|
close_action, close_icon = back, 'close'
|
||||||
|
q = parse_url_params()
|
||||||
|
ca = q.close_action
|
||||||
|
if ca is 'home':
|
||||||
|
close_action, close_icon = def(): home();, 'home'
|
||||||
|
else:
|
||||||
|
close_action, close_icon = back, 'close'
|
||||||
|
return close_action, close_icon
|
||||||
|
|
||||||
|
|
||||||
|
def init_display_note(container_id):
|
||||||
|
nonlocal current_container_id
|
||||||
|
current_container_id = container_id
|
||||||
|
container = document.getElementById(container_id)
|
||||||
|
close_action, close_icon = get_close_action()
|
||||||
|
q = parse_url_params()
|
||||||
|
create_top_bar(container, title=q.item, action=close_action, icon=close_icon)
|
||||||
|
add_button(container, 'edit', action=edit_note, tooltip=_('Edit this note [E]'))
|
||||||
|
setup_container(container, close_action)
|
||||||
if current_note_markup and current_note_markup.library_id is q.library_id and current_note_markup.field is q.field and current_note_markup.item_id is q.item_id:
|
if current_note_markup and current_note_markup.library_id is q.library_id and current_note_markup.field is q.field and current_note_markup.item_id is q.item_id:
|
||||||
html = current_note_markup.html
|
html = current_note_markup.html
|
||||||
container.appendChild(make_iframe(html))
|
container.lastChild.appendChild(make_iframe(html))
|
||||||
else:
|
else:
|
||||||
container.appendChild(E.div(_('Loading') + '…', style='margin: 0.5rem', class_='loading'))
|
container.lastChild.appendChild(E.div(_('Loading') + '…', style='margin: 0.5rem', class_='loading'))
|
||||||
url = 'get-note/' + encodeURIComponent(q.field) + '/' + encodeURIComponent(q.item_id)
|
url = 'get-note/' + encodeURIComponent(q.field) + '/' + encodeURIComponent(q.item_id)
|
||||||
if q.library_id:
|
if q.library_id:
|
||||||
url += '/' + encodeURIComponent(q.library_id)
|
url += '/' + encodeURIComponent(q.library_id)
|
||||||
ajax(url, on_notes_fetched.bind(container_id), bypass_cache=False).send()
|
ajax(url, on_notes_fetched.bind(container_id), bypass_cache=False).send()
|
||||||
|
|
||||||
|
|
||||||
|
def save(container_id):
|
||||||
|
c = document.getElementById(container_id)
|
||||||
|
if not c:
|
||||||
|
return
|
||||||
|
get_comments_html(c, def(html):
|
||||||
|
print(html)
|
||||||
|
print('TODO: Implement saving')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def init_edit(container_id):
|
def init_edit(container_id):
|
||||||
|
nonlocal current_container_id
|
||||||
|
current_container_id = container_id
|
||||||
container = document.getElementById(container_id)
|
container = document.getElementById(container_id)
|
||||||
close_action, close_icon = back, 'close'
|
close_action, close_icon = get_close_action()
|
||||||
q = parse_url_params()
|
q = parse_url_params()
|
||||||
ca = q.close_action
|
create_top_bar(container, title=_('Edit notes for:') + ' ' + q.item, action=close_action, icon=close_icon, tooltip=_('Discard any changes'))
|
||||||
if ca is 'home':
|
add_button(container, 'check', action=save.bind(None, container_id), tooltip=_('Save the changes'))
|
||||||
close_action, close_icon = def(): home();, 'home'
|
setup_container(container, close_action)
|
||||||
create_top_bar(container, title=_('Edit notes for:') + ' ' + q.item, action=close_action, icon=close_icon)
|
|
||||||
container.style.height = '100vh'
|
|
||||||
container.style.display = 'flex'
|
|
||||||
container.style.flexDirection = 'column'
|
|
||||||
if current_note_markup and current_note_markup.library_id is q.library_id and current_note_markup.field is q.field and current_note_markup.item_id is q.item_id:
|
if current_note_markup and current_note_markup.library_id is q.library_id and current_note_markup.field is q.field and current_note_markup.item_id is q.item_id:
|
||||||
create_editor(container, current_note_markup.html)
|
create_editor(container.lastChild, current_note_markup.html)
|
||||||
else:
|
else:
|
||||||
container.appendChild(E.div(_('Loading') + '…', style='margin: 0.5rem', class_='loading'))
|
container.lastChild.appendChild(E.div(_('Loading') + '…', style='margin: 0.5rem', class_='loading'))
|
||||||
url = 'get-note/' + encodeURIComponent(q.field) + '/' + encodeURIComponent(q.item_id)
|
url = 'get-note/' + encodeURIComponent(q.field) + '/' + encodeURIComponent(q.item_id)
|
||||||
if q.library_id:
|
if q.library_id:
|
||||||
url += '/' + encodeURIComponent(q.library_id)
|
url += '/' + encodeURIComponent(q.library_id)
|
||||||
@ -86,8 +170,12 @@ def init_edit(container_id):
|
|||||||
|
|
||||||
|
|
||||||
def create_editor(container, html):
|
def create_editor(container, html):
|
||||||
pass
|
c = container.appendChild(E.div(style='flex-grow:10'))
|
||||||
|
editor = create_comments_editor(c)
|
||||||
|
set_comments_html(c, html)
|
||||||
|
focus_comments_editor(c)
|
||||||
|
editor.init()
|
||||||
|
|
||||||
|
|
||||||
set_panel_handler('show_note', init)
|
set_panel_handler('show_note', init_display_note)
|
||||||
set_panel_handler('edit_note', init_edit)
|
set_panel_handler('edit_note', init_edit)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user