mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Start work on porting live css
This commit is contained in:
parent
8aa52dbcba
commit
4eb75032db
@ -5,8 +5,6 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import json
|
||||
|
||||
from PyQt5.Qt import (
|
||||
QWidget, QTimer, QStackedLayout, QLabel, QScrollArea, QVBoxLayout,
|
||||
QPainter, Qt, QPalette, QRect, QSize, QSizePolicy, pyqtSignal,
|
||||
@ -382,6 +380,7 @@ class LiveCSS(QWidget):
|
||||
def __init__(self, preview, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self.preview = preview
|
||||
preview.live_css_data.connect(self.got_live_css_data)
|
||||
self.preview_is_refreshing = False
|
||||
self.refresh_needed = False
|
||||
preview.refresh_starting.connect(self.preview_refresh_starting)
|
||||
@ -417,8 +416,6 @@ class LiveCSS(QWidget):
|
||||
|
||||
def preview_refreshed(self):
|
||||
self.preview_is_refreshing = False
|
||||
# We must let the event loop run otherwise the webview will return
|
||||
# stale data in read_data()
|
||||
self.refresh_needed = True
|
||||
self.start_update_timer()
|
||||
|
||||
@ -448,7 +445,25 @@ class LiveCSS(QWidget):
|
||||
if sourceline is None:
|
||||
self.clear()
|
||||
else:
|
||||
data = self.read_data(sourceline, tags)
|
||||
self.preview.request_live_css_data(editor_name, sourceline, tags)
|
||||
|
||||
def got_live_css_data(self, result):
|
||||
maximum_specificities = {}
|
||||
for node in result['nodes']:
|
||||
is_ancestor = node['is_ancestor']
|
||||
for rule in node['css']:
|
||||
self.process_rule(rule, is_ancestor, maximum_specificities)
|
||||
for node in result['nodes']:
|
||||
for rule in node['css']:
|
||||
for prop in rule['properties']:
|
||||
if prop.specificity < maximum_specificities[prop.name]:
|
||||
prop.is_overriden = True
|
||||
self.display_received_live_css_data(result)
|
||||
|
||||
def display_received_live_css_data(self, data):
|
||||
editor_name = data['editor_name']
|
||||
sourceline = data['sourceline']
|
||||
tags = data['tags']
|
||||
if data is None or len(data['computed_css']) < 1:
|
||||
if editor_name == self.current_name and (editor_name, sourceline, tags) == self.now_showing:
|
||||
# Try again in a little while in case there was a transient
|
||||
@ -471,31 +486,6 @@ class LiveCSS(QWidget):
|
||||
self.refresh_needed = False
|
||||
self.stack.setCurrentIndex(1)
|
||||
|
||||
def read_data(self, sourceline, tags):
|
||||
return None # TODO: Implement this
|
||||
mf = self.preview.view.page().mainFrame()
|
||||
tags = [x.lower() for x in tags]
|
||||
result = unicode_type(mf.evaluateJavaScript(
|
||||
'window.calibre_preview_integration.live_css(%s, %s)' % (
|
||||
json.dumps(sourceline), json.dumps(tags))) or '')
|
||||
try:
|
||||
result = json.loads(result)
|
||||
except ValueError:
|
||||
result = None
|
||||
if result is not None:
|
||||
maximum_specificities = {}
|
||||
for node in result['nodes']:
|
||||
is_ancestor = node['is_ancestor']
|
||||
for rule in node['css']:
|
||||
self.process_rule(rule, is_ancestor, maximum_specificities)
|
||||
for node in result['nodes']:
|
||||
for rule in node['css']:
|
||||
for prop in rule['properties']:
|
||||
if prop.specificity < maximum_specificities[prop.name]:
|
||||
prop.is_overriden = True
|
||||
|
||||
return result
|
||||
|
||||
def process_rule(self, rule, is_ancestor, maximum_specificities):
|
||||
selector = rule['selector']
|
||||
sheet_index = rule['sheet_index']
|
||||
|
@ -280,13 +280,12 @@ class PreviewBridge(Bridge):
|
||||
|
||||
request_sync = from_js(object, object, object)
|
||||
request_split = from_js(object, object)
|
||||
live_css_data = from_js(object)
|
||||
|
||||
go_to_sourceline_address = to_js()
|
||||
go_to_anchor = to_js()
|
||||
set_split_mode = to_js()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
Bridge.__init__(self, parent)
|
||||
live_css = to_js()
|
||||
|
||||
|
||||
class WebPage(QWebEnginePage):
|
||||
@ -423,6 +422,7 @@ class Preview(QWidget):
|
||||
link_clicked = pyqtSignal(object, object)
|
||||
refresh_starting = pyqtSignal()
|
||||
refreshed = pyqtSignal()
|
||||
live_css_data = pyqtSignal(object)
|
||||
render_process_restarted = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@ -433,6 +433,7 @@ class Preview(QWidget):
|
||||
self.view = WebView(self)
|
||||
self.view._page.bridge.request_sync.connect(self.request_sync)
|
||||
self.view._page.bridge.request_split.connect(self.request_split)
|
||||
self.view._page.bridge.live_css_data.connect(self.live_css_data)
|
||||
self.view._page.loadFinished.connect(self.load_finished)
|
||||
self.view.render_process_restarted.connect(self.render_process_restarted)
|
||||
self.pending_go_to_anchor = None
|
||||
@ -645,6 +646,9 @@ class Preview(QWidget):
|
||||
else:
|
||||
self.stop_split()
|
||||
|
||||
def request_live_css_data(self, editor_name, sourceline, tags):
|
||||
self.view._page.bridge.live_css(editor_name, sourceline, tags)
|
||||
|
||||
def apply_settings(self):
|
||||
s = self.view.settings()
|
||||
s.setFontSize(s.DefaultFontSize, tprefs['preview_base_font_size'])
|
||||
|
@ -336,19 +336,21 @@ def go_to_anchor(anchor):
|
||||
address = get_sourceline_address(elem)
|
||||
to_python.request_sync('', '', address)
|
||||
|
||||
def live_css(sourceline, tags):
|
||||
@from_python
|
||||
def live_css(editor_name, sourceline, tags):
|
||||
all_properties = {}
|
||||
ans = {'nodes':v'[]', 'computed_css':all_properties, 'editor_name': editor_name, 'sourceline': sourceline, 'tags': tags}
|
||||
target = None
|
||||
i = 0
|
||||
for node in document.querySelectorAll(f'[data-lnum="{sourceline}"]'):
|
||||
tn = node.tagName.toLowerCase() if node.tagName else ''
|
||||
if tn is not tags[i]:
|
||||
return JSON.stringify(None)
|
||||
to_python.live_css_data(ans)
|
||||
return
|
||||
i += 1
|
||||
target = node
|
||||
if i >= tags.length:
|
||||
break
|
||||
all_properties = {}
|
||||
ans = {'nodes':v'[]', 'computed_css':all_properties}
|
||||
is_ancestor = False
|
||||
while target and target.ownerDocument:
|
||||
css = get_matched_css(target, is_ancestor, all_properties)
|
||||
@ -362,7 +364,8 @@ def live_css(sourceline, tags):
|
||||
})
|
||||
target = target.parentNode
|
||||
is_ancestor = True
|
||||
return JSON.stringify(ans)
|
||||
to_python.live_css_data(ans)
|
||||
|
||||
|
||||
document.body.addEventListener('click', onclick, True)
|
||||
document.documentElement.appendChild(E.style(
|
||||
|
Loading…
x
Reference in New Issue
Block a user