Implementation of marking selection using spans

This commit is contained in:
Kovid Goyal 2020-03-24 13:51:32 +05:30
parent 4144f76ec3
commit 5d9515c115
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 38 additions and 5 deletions

View File

@ -75,7 +75,7 @@ def create_wrapper_function(wrapper_elem, r):
current_range.setStart(node, start_offset) current_range.setStart(node, start_offset)
start_node = current_wrapper start_node = current_wrapper
start_offset = 0 start_offset = 0
elif node is end_node and end_node.nodeType is Node.TEXT_NODE: if node is end_node and end_node.nodeType is Node.TEXT_NODE:
current_range.setEnd(node, end_offset) current_range.setEnd(node, end_offset)
end_node = current_wrapper end_node = current_wrapper
end_offset = 1 end_offset = 1
@ -89,7 +89,7 @@ def create_wrapper_function(wrapper_elem, r):
wrapper_counter = 0 wrapper_counter = 0
def wrap_text_in_range(r, style): def wrap_text_in_range(style, r):
if not r: if not r:
r = window.getSelection().getRangeAt(0) r = window.getSelection().getRangeAt(0)
if r.isCollapsed: if r.isCollapsed:
@ -101,6 +101,11 @@ def wrap_text_in_range(r, style):
wrapper_elem.setAttribute('style', style) wrapper_elem.setAttribute('style', style)
wrap_node = create_wrapper_function(wrapper_elem, r) wrap_node = create_wrapper_function(wrapper_elem, r)
nodes = get_text_nodes(r) nodes = text_nodes_in_range(r)
nodes = nodes.map(wrap_node) nodes = nodes.map(wrap_node)
return wrapper_elem.dataset.calibreRangeWrapper return wrapper_elem.dataset.calibreRangeWrapper
def reset_highlight_counter():
nonlocal wrapper_counter
wrapper_counter = 0

View File

@ -4,10 +4,12 @@ from __python__ import bound_methods, hash_literals
from elementmaker import E from elementmaker import E
from gettext import gettext as _ from gettext import gettext as _
from uuid import short_uuid
from book_list.globals import get_session_data from book_list.globals import get_session_data
from book_list.theme import get_color, cached_color_to_rgba from book_list.theme import cached_color_to_rgba, get_color
from dom import add_extra_css, clear, ensure_id, svgicon, unique_id from dom import add_extra_css, clear, ensure_id, svgicon, unique_id
from modals import error_dialog
from read_book.shortcuts import shortcut_for_key_event from read_book.shortcuts import shortcut_for_key_event
WAITING_FOR_CLICK = 1 WAITING_FOR_CLICK = 1
@ -241,10 +243,19 @@ class CreateAnnotation:
h.style.display = h.dataset.savedState h.style.display = h.dataset.savedState
def accept(self): def accept(self):
self.send_message('apply-highlight', style=self.current_highlight_style) s = self.current_highlight_style
style = ''
for k in Object.keys(self.current_highlight_style):
style += f'{k}: {s[k]}; '
self.send_message(
'apply-highlight', style=style, uuid=short_uuid()
)
self.hide()
def on_keydown(self, ev): def on_keydown(self, ev):
ev.stopPropagation(), ev.preventDefault() ev.stopPropagation(), ev.preventDefault()
if ev.key is 'Enter':
return self.accept()
sc_name = shortcut_for_key_event(ev, self.view.keyboard_shortcut_map) sc_name = shortcut_for_key_event(ev, self.view.keyboard_shortcut_map)
if sc_name is 'show_chrome': if sc_name is 'show_chrome':
self.hide() self.hide()
@ -366,6 +377,13 @@ class CreateAnnotation:
self.place_handles(msg.extents) self.place_handles(msg.extents)
elif msg.type is 'update-handles': elif msg.type is 'update-handles':
self.place_handles(msg.extents) self.place_handles(msg.extents)
elif msg.type is 'highlight-applied':
if not msg.ok:
return error_dialog(
_('Highlighting failed'),
_('Failed to apply highlighting, try adjusting extent of highlight')
)
else: else:
print('Ignoring annotations message with unknown type:', msg.type) print('Ignoring annotations message with unknown type:', msg.type)

View File

@ -11,6 +11,7 @@ from select import (
from fs_images import fix_fullscreen_svg_images from fs_images import fix_fullscreen_svg_images
from iframe_comm import IframeClient from iframe_comm import IframeClient
from range_utils import reset_highlight_counter, wrap_text_in_range
from read_book.cfi import scroll_to as scroll_to_cfi from read_book.cfi import scroll_to as scroll_to_cfi
from read_book.extract import get_elements from read_book.extract import get_elements
from read_book.find import reset_find_caches, select_search_result from read_book.find import reset_find_caches, select_search_result
@ -99,6 +100,7 @@ class IframeBoss:
self.reference_mode_enabled = False self.reference_mode_enabled = False
self.replace_history_on_next_cfi_update = True self.replace_history_on_next_cfi_update = True
self.blob_url_map = {} self.blob_url_map = {}
self.annot_id_uuid_map = {}
self.content_ready = False self.content_ready = False
self.last_window_width = self.last_window_height = -1 self.last_window_width = self.last_window_height = -1
self.forward_keypresses = False self.forward_keypresses = False
@ -193,6 +195,8 @@ class IframeBoss:
def display(self, data): def display(self, data):
self.length_before = None self.length_before = None
self.content_ready = False self.content_ready = False
self.annot_id_uuid_map = {}
reset_highlight_counter()
self.replace_history_on_next_cfi_update = True self.replace_history_on_next_cfi_update = True
self.book = current_book.book = data.book self.book = current_book.book = data.book
self.reference_mode_enabled = data.reference_mode_enabled self.reference_mode_enabled = data.reference_mode_enabled
@ -637,6 +641,12 @@ class IframeBoss:
self.send_message('annotations', type='update-handles', extents=selection_extents(in_flow_mode)) self.send_message('annotations', type='update-handles', extents=selection_extents(in_flow_mode))
elif data.type is 'set-highlight-style': elif data.type is 'set-highlight-style':
set_selection_style(data.style) set_selection_style(data.style)
elif data.type is 'apply-highlight':
annot_id = wrap_text_in_range(data.style)
if annot_id is not None:
window.getSelection().removeAllRanges()
self.annot_id_uuid_map[annot_id] = data.uuid
self.send_message('annotations', type='highlight-applied', uuid=data.uuid, ok=annot_id is not None)
else: else:
console.log('Ignoring annotations message to iframe with unknown type: ' + data.type) console.log('Ignoring annotations message to iframe with unknown type: ' + data.type)