[evolution/wip/mcrha/webkit-jsc-api] Style Sheet related functions
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/mcrha/webkit-jsc-api] Style Sheet related functions
- Date: Wed, 25 Sep 2019 21:44:30 +0000 (UTC)
commit 94fe76598331ed4f3c8d18240bf01e3db35ad86b
Author: Milan Crha <mcrha redhat com>
Date: Wed Sep 25 23:44:32 2019 +0200
Style Sheet related functions
src/e-util/e-web-view-jsc-utils.c | 42 +++++++++++++++
src/e-util/e-web-view-jsc-utils.h | 13 +++++
src/e-util/e-web-view.c | 5 ++
src/e-util/test-web-view.c | 107 +++++++++++++++++++++++++++++++++++++-
src/web-extensions/ext-utils.js | 104 ++++++++++++++++++++++++++++++++++--
5 files changed, 267 insertions(+), 4 deletions(-)
---
diff --git a/src/e-util/e-web-view-jsc-utils.c b/src/e-util/e-web-view-jsc-utils.c
index 6c68da614f..04df46ecdd 100644
--- a/src/e-util/e-web-view-jsc-utils.c
+++ b/src/e-util/e-web-view-jsc-utils.c
@@ -296,3 +296,45 @@ e_web_view_jsc_set_element_attribute (WebKitWebView *web_view,
webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
}
+
+void
+e_web_view_jsc_create_css_style_sheet (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *content,
+ GCancellable *cancellable)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id != NULL);
+
+ script = e_web_view_jsc_strdup_call ("Evo.CreateCSSStyleSheet(%s,%s,%s)",
+ iframe_id,
+ style_sheet_id,
+ content);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
+}
+
+void
+e_web_view_jsc_add_css_rule_into_style_sheet (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style,
+ GCancellable *cancellable)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id != NULL);
+
+ script = e_web_view_jsc_strdup_call ("Evo.AddCSSRuleIntoStyleSheet(%s,%s,%s,%s)",
+ iframe_id,
+ style_sheet_id,
+ selector,
+ style);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
+}
diff --git a/src/e-util/e-web-view-jsc-utils.h b/src/e-util/e-web-view-jsc-utils.h
index c5c4136b1d..6cada9a51d 100644
--- a/src/e-util/e-web-view-jsc-utils.h
+++ b/src/e-util/e-web-view-jsc-utils.h
@@ -67,6 +67,19 @@ void e_web_view_jsc_set_element_attribute
const gchar *qualified_name,
const gchar *value,
GCancellable *cancellable);
+void e_web_view_jsc_create_css_style_sheet
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *content,
+ GCancellable *cancellable);
+void e_web_view_jsc_add_css_rule_into_style_sheet
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style,
+ GCancellable *cancellable);
G_END_DECLS
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index ccd9bd4b6d..2a22193835 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -1370,6 +1370,11 @@ e_web_view_content_loaded_cb (WebKitUserContentManager *manager,
iframe_id = jsc_value_to_string (jsc_value);
+ if (!iframe_id || !*iframe_id) {
+ e_web_view_update_fonts (web_view);
+ style_updated_cb (web_view);
+ }
+
g_signal_emit (web_view, signals[CONTENT_LOADED], 0, iframe_id);
g_free (iframe_id);
diff --git a/src/e-util/test-web-view.c b/src/e-util/test-web-view.c
index df21bebfaa..e6c4f196d2 100644
--- a/src/e-util/test-web-view.c
+++ b/src/e-util/test-web-view.c
@@ -332,6 +332,25 @@ test_utils_jsc_call_bool_sync (TestFixture *fixture,
return res;
}
+static gint32
+test_utils_jsc_call_int32_sync (TestFixture *fixture,
+ const gchar *script)
+{
+ JSCValue *result = NULL;
+ gint32 res;
+
+ test_utils_jsc_call_sync (fixture, script, &result);
+
+ g_assert_nonnull (result);
+ g_assert (jsc_value_is_number (result));
+
+ res = jsc_value_to_int32 (result);
+
+ g_clear_object (&result);
+
+ return res;
+}
+
static gchar *
test_utils_jsc_call_string_sync (TestFixture *fixture,
const gchar *script)
@@ -374,7 +393,7 @@ test_utils_jsc_call_string_and_verify (TestFixture *fixture,
static void
test_utils_wait_noop (TestFixture *fixture)
{
- test_utils_jsc_call_sync (fixture, "document.title", NULL);
+ test_utils_jsc_call_sync (fixture, "javascript:void(0);", NULL);
}
static void
@@ -692,6 +711,91 @@ test_set_element_attribute (TestFixture *fixture)
test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").getAttributeNS(\"\", \"myattr\")", NULL);
}
+static void
+test_style_sheets (TestFixture *fixture)
+{
+ test_utils_load_body (fixture);
+
+ test_utils_jsc_call_sync (fixture,
+ "var Test = {};\n"
+ "\n"
+ "Test.nStyles = function(iframe_id)\n"
+ "{\n"
+ " return
Evo.findIFrameDocument(iframe_id).head.getElementsByTagName(\"style\").length;\n"
+ "}\n"
+ "\n"
+ "Test.getStyle = function(iframe_id, style_sheet_id, selector, property_name)\n"
+ "{\n"
+ " var styles = Evo.findIFrameDocument(iframe_id).head.getElementsByTagName(\"style\"),
ii;\n"
+ "\n"
+ " for (ii = 0; ii < styles.length; ii++) {\n"
+ " if (styles[ii].id == style_sheet_id) {\n"
+ " break;\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " if (ii >= styles.length)\n"
+ " return null;\n"
+ "\n"
+ " styles = styles[ii].sheet;\n"
+ "\n"
+ " for (ii = 0; ii < styles.cssRules.length; ii++) {\n"
+ " if (styles.cssRules[ii].selectorText == selector) {\n"
+ " return styles.cssRules[ii].style.getPropertyValue(property_name);\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " return null;\n"
+ "}\n"
+ "\n"
+ "javascript:void(0);\n",
+ NULL);
+
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1\")"));
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet1\", \"body\",
\"color\")", NULL);
+
+ e_web_view_jsc_create_css_style_sheet (fixture->web_view, "", "sheet1", "body { color:green; }",
NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1\")"));
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet1\", \"body\",
\"color\")", "green");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"body\",
\"background-color\")", NULL);
+
+ e_web_view_jsc_add_css_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheet2", "body",
"background-color:black;", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1\")"));
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet1\", \"body\",
\"color\")", "green");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"body\",
\"background-color\")", "black");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet3\", \"body\",
\"color\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1\", \"sheet3\", \"body\",
\"color\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet3\", \"body\",
\"color\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm2\", \"sheet3\", \"body\",
\"color\")", NULL);
+
+ e_web_view_jsc_add_css_rule_into_style_sheet (fixture->web_view, "*", "sheet3", "body",
"color:orange;", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (3, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet1\", \"body\",
\"color\")", "green");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"body\",
\"background-color\")", "black");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"\", \"sheet3\", \"body\",
\"color\")", "orange");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1\", \"sheet3\", \"body\",
\"color\")", "orange");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet3\", \"body\",
\"color\")", "orange");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm2\", \"sheet3\", \"body\",
\"color\")", "orange");
+}
+
gint
main (gint argc,
gchar *argv[])
@@ -712,6 +816,7 @@ main (gint argc,
test_utils_add_test ("/EWebView/SetElementHidden", test_set_element_hidden);
test_utils_add_test ("/EWebView/SetElementStyleProperty", test_set_element_style_property);
test_utils_add_test ("/EWebView/SetElementAttribute", test_set_element_attribute);
+ test_utils_add_test ("/EWebView/StyleSheets", test_style_sheets);
res = g_test_run ();
diff --git a/src/web-extensions/ext-utils.js b/src/web-extensions/ext-utils.js
index 6062e60cc6..275b375aed 100644
--- a/src/web-extensions/ext-utils.js
+++ b/src/web-extensions/ext-utils.js
@@ -32,6 +32,16 @@ Evo.findIFrame = function(iframe_id)
return Evo.findIFrameInDocument(document, iframe_id);
}
+Evo.findIFrameDocument = function(iframe_id)
+{
+ var iframe = Evo.findIFrame(iframe_id);
+
+ if (iframe)
+ return iframe.contentDocument;
+
+ return document;
+}
+
Evo.findElement = function(iframe_id, element_id)
{
var iframe;
@@ -79,6 +89,83 @@ Evo.SetElementAttribute = function(iframe_id, element_id, namespace_uri, qualifi
}
}
+Evo.createStyleSheet = function(doc, style_sheet_id, content)
+{
+ var node;
+
+ node = doc.createElement("style");
+ node.id = style_sheet_id;
+ node.media = "screen";
+ node.innerText = content;
+
+ doc.head.append(node);
+
+ return node;
+}
+
+Evo.CreateCSSStyleSheet = function(iframe_id, style_sheet_id, content)
+{
+ var doc = Evo.findIFrameDocument(iframe_id);
+ var styles = doc.head.getElementsByTagName("style"), ii;
+
+ for (ii = 0; ii < styles.length; ii++) {
+ if (styles[ii].id == style_sheet_id) {
+ styles[ii].innerText = content;
+ return;
+ }
+ }
+
+ Evo.createStyleSheet(doc, style_sheet_id, content);
+}
+
+Evo.addCSSRuleIntoStyleSheetDocument = function(doc, style_sheet_id, selector, style)
+{
+ var styles = doc.head.getElementsByTagName("style"), ii, styleobj = null;
+
+ for (ii = 0; ii < styles.length; ii++) {
+ if (styles[ii].id == style_sheet_id) {
+ styleobj = styles[ii];
+ break;
+ }
+ }
+
+ if (!styleobj) {
+ Evo.createStyleSheet(doc, style_sheet_id, selector + " { " + style + " }");
+ return;
+ }
+
+ for (ii = 0; ii < style.cssRules.length; ii++) {
+ if (style.cssRules[ii].selectorText == selector) {
+ style.cssRules[ii].style.cssText = style;
+ return;
+ }
+ }
+}
+
+Evo.addCSSRuleIntoStyleSheetDocumentRecursive = function(doc, style_sheet_id, selector, style)
+{
+ Evo.addCSSRuleIntoStyleSheetDocument(doc, style_sheet_id, selector, style);
+
+ var iframes, ii;
+
+ iframes = doc.getElementsByTagName("iframe");
+
+ for (ii = 0; ii < iframes.length; ii++) {
+ Evo.addCSSRuleIntoStyleSheetDocumentRecursive(iframes[ii].contentDocument, style_sheet_id,
selector, style);
+ }
+}
+
+Evo.AddCSSRuleIntoStyleSheet = function(iframe_id, style_sheet_id, selector, style)
+{
+ if (iframe_id == "*") {
+ Evo.addCSSRuleIntoStyleSheetDocumentRecursive(document, style_sheet_id, selector, style);
+ } else {
+ var doc = Evo.findIFrameDocument(iframe_id);
+
+ Evo.addCSSRuleIntoStyleSheetDocument(doc, style_sheet_id, selector, style);
+ }
+}
+
Evo.SetDocumentContent = function(content)
{
document.documentElement.innerHTML = content;
@@ -163,16 +250,27 @@ Evo.ElemClicked = function(elem)
Evo.Initialize = function(elem)
{
- var elems, ii;
+ var doc, elems, ii;
if (elem && elem instanceof HTMLIFrameElement && elem.contentDocument)
- elems = elem.contentDocument.getElementsByTagName("iframe");
+ doc = elem.contentDocument;
else
- elems = document.getElementsByTagName("iframe");
+ doc = document;
+
+ elems = doc.getElementsByTagName("iframe");
for (ii = 0; ii < elems.length; ii++) {
elems[ii].onload = function() { Evo.PostContentLoadedAndInitialize(this) };
}
+
+ if (!doc.body.hasAttribute("class"))
+ doc.body.className = "-e-web-view-background-color -e-web-view-text-color";
+
+ if (doc.documentElement.style.getPropertyValue("color") == "" ||
+ doc.documentElement.style.getPropertyValue("color") == "text") {
+ doc.documentElement.style.setProperty("color", "inherit");
+ doc.documentElement.style.setProperty("background-color", "inherit");
+ }
}
Evo.PostContentLoadedAndInitialize = function(elem)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]