[evolution] EWebView: Use JavaScriptCore API of WebKitGTK+
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] EWebView: Use JavaScriptCore API of WebKitGTK+
- Date: Wed, 9 Oct 2019 10:32:55 +0000 (UTC)
commit 1d7e3e75cc1f02e9096125aad41f650a7c1fcb45
Author: Milan Crha <mcrha redhat com>
Date: Wed Oct 9 12:26:12 2019 +0200
EWebView: Use JavaScriptCore API of WebKitGTK+
All the previews (in Mail, Contacts, Memos and Tasks) stop using
deprecated WebKitGTK+ DOM API through a WebExtension (and its D-Bus
API) and start using the JavaScriptCore API (and JavaScript as such).
This allows to lightweight the WebExtension for the EWebView
significantly, including drop of the D-Bus API of it, fully relying
on the Inter-Process-Communication of WebKitGTK+ itself.
CMakeLists.txt | 3 +-
data/CMakeLists.txt | 7 +-
data/webkit/CMakeLists.txt | 10 +
data/webkit/e-convert.js | 12 +
data/webkit/e-web-view.js | 1437 ++++++++++++
data/{ => webkit}/webview-print.css | 0
data/{ => webkit}/webview.css | 0
src/addressbook/gui/widgets/eab-contact-display.c | 30 +-
.../gui/widgets/eab-contact-formatter.c | 4 +-
src/calendar/gui/CMakeLists.txt | 1 -
src/calendar/gui/e-cal-component-preview.c | 2 +-
src/e-util/CMakeLists.txt | 8 +-
src/e-util/e-file-request.c | 12 +-
src/e-util/e-util-private.h | 4 +
src/e-util/e-util.h | 3 +-
src/e-util/e-web-view-jsc-utils.c | 711 ++++++
src/e-util/e-web-view-jsc-utils.h | 181 ++
src/e-util/e-web-view.c | 1376 ++++--------
src/e-util/e-web-view.h | 84 +-
src/e-util/e-win32-reloc.c | 7 +
src/e-util/test-web-view-jsc.c | 1955 ++++++++++++++++
src/em-format/CMakeLists.txt | 1 -
src/em-format/e-mail-formatter-print.c | 3 +-
src/em-format/e-mail-formatter.c | 3 +-
src/em-format/e-mail-part-headers.c | 21 -
src/em-format/e-mail-part-secure-button.c | 8 +-
src/em-format/e-mail-part.c | 28 +-
src/em-format/e-mail-part.h | 12 +-
src/mail/e-mail-display-popup-extension.c | 8 +-
src/mail/e-mail-display-popup-extension.h | 6 +-
src/mail/e-mail-display.c | 607 ++---
src/mail/e-mail-display.h | 9 -
src/mail/e-mail-reader-utils.c | 150 +-
src/mail/e-mail-reader.c | 2 +-
src/modules/CMakeLists.txt | 29 -
src/modules/itip-formatter/e-mail-part-itip.c | 29 +-
src/modules/itip-formatter/itip-view.c | 913 +++-----
src/modules/itip-formatter/itip-view.h | 4 +-
.../e-mail-display-popup-prefer-plain.c | 43 +-
.../e-mail-display-popup-text-highlight.c | 43 +-
src/modules/vcard-inline/e-mail-formatter-vcard.c | 107 +-
src/modules/vcard-inline/e-mail-parser-vcard.c | 6 +-
src/modules/vcard-inline/e-mail-part-vcard.c | 244 +-
src/modules/vcard-inline/e-mail-part-vcard.h | 12 +-
.../webkit-editor/web-extension/CMakeLists.txt | 26 +
.../web-extension/e-composer-dom-functions.c | 3 +-
.../web-extension/e-dialogs-dom-functions.c | 3 +-
.../webkit-editor/web-extension/e-dom-utils.c | 621 ++++++
.../webkit-editor/web-extension/e-dom-utils.h | 91 +
.../web-extension/e-editor-dom-functions.c | 3 +-
.../webkit-editor/web-extension/e-editor-page.c | 3 +-
.../web-extension/e-editor-undo-redo-manager.c | 3 +-
.../web-extension/e-editor-web-extension.c | 3 +-
src/plugins/mail-to-task/mail-to-task.c | 92 +-
src/web-extensions/CMakeLists.txt | 55 +-
src/web-extensions/e-dom-utils.c | 2349 --------------------
src/web-extensions/e-dom-utils.h | 183 --
src/web-extensions/e-itip-formatter-dom-utils.c | 649 ------
src/web-extensions/e-itip-formatter-dom-utils.h | 111 -
src/web-extensions/e-web-extension-main.c | 49 +-
src/web-extensions/e-web-extension-names.h | 25 -
src/web-extensions/e-web-extension.c | 2144 +-----------------
src/web-extensions/e-web-extension.h | 6 -
63 files changed, 6470 insertions(+), 8084 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a325ef261..a14e730f2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -82,7 +82,7 @@ set(gsettings_desktop_schemas_minimum_version 2.91.92)
set(libpst_minimum_version 0.6.54)
set(libxml_minimum_version 2.7.3)
set(shared_mime_info_minimum_version 0.22)
-set(webkit2gtk_minimum_version 2.16.0)
+set(webkit2gtk_minimum_version 2.24.0)
# Optional Packages
set(champlain_minimum_version 0.12)
@@ -178,6 +178,7 @@ set(plugindir "${privlibdir}/plugins")
set(soundsdir "${privdatadir}/sounds")
set(uidir "${privdatadir}/ui")
set(viewsdir "${privdatadir}/views")
+set(webkitdatadir "${privdatadir}/webkit")
set(webextensionsdir "${privlibdir}/web-extensions")
set(webextensionswebkiteditordir "${webextensionsdir}/webkit-editor")
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
index 5f5608a5d2..06e1e17006 100644
--- a/data/CMakeLists.txt
+++ b/data/CMakeLists.txt
@@ -1,6 +1,5 @@
set(filedeps)
set(desktopdir ${SHARE_INSTALL_PREFIX}/applications)
-set(themedir ${privdatadir}/theme)
configure_file(org.gnome.Evolution.desktop.in.in
org.gnome.Evolution.desktop.in
@@ -30,11 +29,6 @@ configure_file(org.gnome.Evolution.appdata.xml.in.in
add_appdata_file(${CMAKE_CURRENT_BINARY_DIR}/org.gnome.Evolution.appdata.xml.in
org.gnome.Evolution.appdata.xml)
-install(FILES webview.css
- webview-print.css
- DESTINATION ${themedir}
-)
-
set(SCHEMAS
org.gnome.evolution.gschema.xml
org.gnome.evolution.addressbook.gschema.xml
@@ -83,3 +77,4 @@ add_subdirectory(images)
add_subdirectory(sounds)
add_subdirectory(ui)
add_subdirectory(views)
+add_subdirectory(webkit)
diff --git a/data/webkit/CMakeLists.txt b/data/webkit/CMakeLists.txt
new file mode 100644
index 0000000000..37832ac9df
--- /dev/null
+++ b/data/webkit/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(DATA_FILES
+ e-convert.js
+ e-web-view.js
+ webview.css
+ webview-print.css
+)
+
+install(FILES ${DATA_FILES}
+ DESTINATION ${webkitdatadir}
+)
diff --git a/data/webkit/e-convert.js b/data/webkit/e-convert.js
new file mode 100644
index 0000000000..4e67b92dc2
--- /dev/null
+++ b/data/webkit/e-convert.js
@@ -0,0 +1,12 @@
+'use strict';
+
+/* semi-convention: private functions start with lower-case letter,
+ public functions start with upper-case letter. */
+
+function EvoConvertToPlainText(element)
+{
+ if (!element)
+ return null;
+
+ return element.innerText;
+}
diff --git a/data/webkit/e-web-view.js b/data/webkit/e-web-view.js
new file mode 100644
index 0000000000..cd01ed870d
--- /dev/null
+++ b/data/webkit/e-web-view.js
@@ -0,0 +1,1437 @@
+'use strict';
+
+/* semi-convention: private functions start with lower-case letter,
+ public functions start with upper-case letter. */
+
+var Evo = {
+ hasSelection : false,
+ blockquoteStyle : "margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex",
+ magicSpacebarState: -1
+};
+
+/* The 'traversar_obj' is an object, which implements a callback function:
+ boolean exec(doc, iframe_id, level);
+ and it returns whether continue the traversar */
+Evo.foreachIFrameDocument = function(doc, traversar_obj, call_also_for_doc, level)
+{
+ if (!doc)
+ return false;
+
+ if (call_also_for_doc && !traversar_obj.exec(doc, doc.defaultView.frameElement ?
doc.defaultView.frameElement.id : "", level))
+ return false;
+
+ var iframes, ii;
+
+ iframes = doc.getElementsByTagName("iframe");
+
+ for (ii = 0; ii < iframes.length; ii++) {
+ if (!traversar_obj.exec(iframes[ii].contentDocument, iframes[ii].id, level + 1))
+ return false;
+
+ if (!Evo.foreachIFrameDocument(iframes[ii].contentDocument, traversar_obj, false, level + 1))
+ return false;
+ }
+
+ return true;
+}
+
+Evo.findIFrame = function(iframe_id)
+{
+ if (iframe_id == "")
+ return null;
+
+ var traversar = {
+ iframe_id : iframe_id,
+ iframe : null,
+ exec : function(doc, iframe_id, level) {
+ if (iframe_id == this.iframe_id) {
+ this.iframe = doc.defaultView.frameElement;
+ return false;
+ }
+ return true;
+ }
+ };
+
+ Evo.foreachIFrameDocument(document, traversar, true, 0);
+
+ return traversar.iframe;
+}
+
+Evo.findIFrameDocument = function(iframe_id)
+{
+ if (iframe_id == "")
+ return document;
+
+ var iframe = Evo.findIFrame(iframe_id);
+
+ if (iframe)
+ return iframe.contentDocument;
+
+ return null;
+}
+
+Evo.runTraversarForIFrameId = function(iframe_id, traversar_obj)
+{
+ if (iframe_id == "*") {
+ Evo.foreachIFrameDocument(document, traversar_obj, true, 0);
+ } else {
+ var doc = Evo.findIFrameDocument(iframe_id);
+
+ if (doc) {
+ var level = 0, parent;
+
+ for (parent = doc.defaultView.frameElement; parent; parent =
parent.ownerDocument.defaultView.frameElement) {
+ level++;
+ }
+
+ traversar_obj.exec(doc, iframe_id, level);
+ }
+ }
+}
+
+Evo.findElementInDocumentById = function(doc, element_id)
+{
+ if (!doc)
+ return null;
+
+ if (element_id == "*html")
+ return doc.documentElement;
+
+ if (element_id == "*head")
+ return doc.head;
+
+ if (element_id == "*body")
+ return doc.body;
+
+ return doc.getElementById(element_id);
+}
+
+Evo.findElement = function(iframe_id, element_id)
+{
+ var traversar = {
+ element_id : element_id,
+ res : null,
+ exec : function(doc, iframe_id, level) {
+ this.res = Evo.findElementInDocumentById(doc, this.element_id);
+ if (this.res)
+ return false;
+ return true;
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+
+ return traversar.res;
+}
+
+Evo.SetElementHidden = function(iframe_id, element_id, value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem)
+ elem.hidden = value;
+}
+
+Evo.SetElementDisabled = function(iframe_id, element_id, value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem)
+ elem.disabled = value;
+}
+
+Evo.SetElementChecked = function(iframe_id, element_id, value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem)
+ elem.checked = value;
+}
+
+Evo.SetElementStyleProperty = function(iframe_id, element_id, property_name, value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ if (value != null && value != "")
+ elem.style.setProperty(property_name, value);
+ else
+ elem.style.removeProperty(property_name);
+ }
+}
+
+Evo.SetElementAttribute = function(iframe_id, element_id, namespace_uri, qualified_name, value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ if (value != null && value != "")
+ elem.setAttributeNS(namespace_uri, qualified_name, value);
+ else
+ elem.removeAttributeNS(namespace_uri, qualified_name);
+ }
+}
+
+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.CreateStyleSheet = function(iframe_id, style_sheet_id, content)
+{
+ var doc = Evo.findIFrameDocument(iframe_id);
+
+ if (!doc)
+ return;
+
+ 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.RemoveStyleSheet = function(iframe_id, style_sheet_id)
+{
+ var traversar = {
+ style_sheet_id : style_sheet_id,
+ exec : function(doc, iframe_id, level) {
+ if (doc && doc.head) {
+ var ii, styles = doc.head.getElementsByTagName("style");
+
+ for (ii = styles.length - 1; ii >= 0; ii--) {
+ if (this.style_sheet_id == "*" || styles[ii].id ==
this.style_sheet_id) {
+ doc.head.removeChild(styles[ii]);
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+}
+
+Evo.addRuleIntoStyleSheetDocument = 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 < styleobj.sheet.cssRules.length; ii++) {
+ if (styleobj.sheet.cssRules[ii].selectorText == selector) {
+ styleobj.sheet.cssRules[ii].style.cssText = style;
+ return;
+ }
+ }
+
+ styleobj.sheet.addRule(selector, style);
+}
+
+Evo.AddRuleIntoStyleSheet = function(iframe_id, style_sheet_id, selector, style)
+{
+ var traversar = {
+ style_sheet_id : style_sheet_id,
+ selector : selector,
+ style : style,
+ exec : function(doc, iframe_id, level) {
+ if (doc && doc.head) {
+ Evo.addRuleIntoStyleSheetDocument(doc, this.style_sheet_id, this.selector,
this.style);
+ }
+
+ return true;
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+}
+
+Evo.SetDocumentContent = function(content)
+{
+ document.documentElement.innerHTML = content;
+
+ Evo.initialize(null);
+ window.webkit.messageHandlers.contentLoaded.postMessage("");
+}
+
+Evo.SetIFrameSrc = function(iframe_id, src_uri)
+{
+ var iframe = Evo.findIFrame(iframe_id);
+
+ if (iframe)
+ iframe.src = src_uri;
+}
+
+Evo.SetIFrameContent = function(iframe_id, content)
+{
+ var iframe = Evo.findIFrame(iframe_id);
+
+ if (iframe) {
+ iframe.contentDocument.documentElement.innerHTML = content;
+
+ Evo.initialize(iframe);
+ window.webkit.messageHandlers.contentLoaded.postMessage(iframe_id);
+ }
+}
+
+Evo.elementClicked = function(elem)
+{
+ var with_parents_left, with_parents_top, scroll_x = 0, scroll_y = 0, offset_parent, dom_window;
+ var parent_iframe_id = "";
+
+ if (elem.ownerDocument.defaultView.frameElement)
+ parent_iframe_id = elem.ownerDocument.defaultView.frameElement.id;
+
+ with_parents_left = elem.offsetLeft;
+ with_parents_top = elem.offsetTop;
+
+ offset_parent = elem;
+ while (offset_parent = offset_parent.offsetParent, offset_parent) {
+ with_parents_left += offset_parent.offsetLeft;
+ with_parents_top += offset_parent.offsetTop;
+ }
+
+ dom_window = elem.ownerDocument.defaultView;
+ while (dom_window instanceof Window) {
+ var parent_dom_window, iframe_elem;
+
+ parent_dom_window = dom_window.parent;
+ iframe_elem = dom_window.frameElement;
+
+ while (iframe_elem) {
+ with_parents_left += iframe_elem.offsetLeft;
+ with_parents_top += iframe_elem.offsetTop;
+
+ iframe_elem = iframe_elem.offsetParent;
+ }
+
+ scroll_x += dom_window.scrollX;
+ scroll_y += dom_window.scrollY;
+
+ if (parent_dom_window == dom_window)
+ break;
+
+ dom_window = parent_dom_window;
+ }
+
+ var res = [];
+
+ res["iframe-id"] = parent_iframe_id;
+ res["elem-id"] = elem.id;
+ res["elem-class"] = elem.className;
+ res["elem-value"] = elem.getAttribute("value");
+ res["left"] = with_parents_left - scroll_x;
+ res["top"] = with_parents_top - scroll_y;
+ res["width"] = elem.offsetWidth;
+ res["height"] = elem.offsetHeight;
+
+ window.webkit.messageHandlers.elementClicked.postMessage(res);
+}
+
+Evo.RegisterElementClicked = function(iframe_id, elem_classes_str)
+{
+ var traversar = {
+ elem_classes : elem_classes_str.split("\n"),
+ exec : function(doc, iframe_id, level) {
+ if (doc && this.elem_classes) {
+ var ii;
+
+ for (ii = 0; ii < this.elem_classes.length; ii++) {
+ if (this.elem_classes[ii] != "") {
+ var jj, elems;
+
+ elems = doc.getElementsByClassName(this.elem_classes[ii]);
+
+ for (jj = 0; jj < elems.length; jj++) {
+ elems[jj].onclick = function() {
Evo.elementClicked(this); };
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+}
+
+Evo.checkAnyParentIsPre = function(node)
+{
+ if (!node)
+ return false;
+
+ while (node = node.parentElement, node) {
+ if (/* node instanceof HTMLPreElement */ node.tagName.toUpperCase() == "PRE")
+ return true;
+ if (/* node instanceof HTMLIFrameElement */ node.tagName.toUpperCase() == "IFRAME")
+ break;
+ }
+
+ return false;
+}
+
+Evo.getElementContent = function(node, format, useOuterHTML)
+{
+ if (!node)
+ return null;
+
+ var data;
+
+ if (format == 1) {
+ data = EvoConvertToPlainText(node);
+ } else if (format == 2) {
+ data = useOuterHTML ? node.outerHTML : node.innerHTML;
+ } else if (format == 3) {
+ data = {};
+ data["plain"] = EvoConvertToPlainText(node);
+ data["html"] = useOuterHTML ? node.outerHTML : node.innerHTML;
+ }
+
+ return data;
+}
+
+Evo.checkHasSelection = function(content)
+{
+ var traversar = {
+ content : content,
+ has : false,
+ exec : function(doc, iframe_id, level) {
+ if (doc && !doc.defaultView.getSelection().isCollapsed) {
+ if (content) {
+ var fragment, node, inpre;
+
+ fragment =
doc.defaultView.getSelection().getRangeAt(0).cloneContents();
+ inpre =
Evo.checkAnyParentIsPre(doc.defaultView.getSelection().getRangeAt(0).startContainer);
+ node = doc.createElement(inpre ? "PRE" : "DIV");
+ node.appendChild(fragment);
+
+ content.data = Evo.getElementContent(node, content.format, inpre);
+ }
+
+ this.has = true;
+
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ Evo.foreachIFrameDocument(document, traversar, true, 0);
+
+ return traversar.has;
+}
+
+Evo.selectionChanged = function()
+{
+
+ var has;
+
+ has = Evo.checkHasSelection(null);
+
+ if (has != Evo.hasSelection) {
+ Evo.hasSelection = has;
+ window.webkit.messageHandlers.hasSelection.postMessage(has);
+ }
+}
+
+Evo.GetSelection = function(format)
+{
+ var content = { format: 0, data: null };
+
+ content.format = format;
+
+ if (!Evo.checkHasSelection(content))
+ return null;
+
+ return content.data;
+}
+
+Evo.GetDocumentContent = function(iframe_id, format)
+{
+ var doc;
+
+ if (iframe_id == "") {
+ doc = document;
+ } else {
+ var iframe = Evo.findIFrame(iframe_id);
+
+ if (!iframe)
+ return null;
+
+ doc = iframe.contentDocument;
+ }
+
+ return Evo.getElementContent(doc.documentElement, format, true);
+}
+
+Evo.GetElementContent = function(iframe_id, element_id, format, use_outer_html)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (!elem)
+ return null;
+
+ return Evo.getElementContent(elem, format, use_outer_html);
+}
+
+Evo.findElementFromPoint = function(doc, xx, yy, parent_elem)
+{
+ var elem;
+
+ if (!parent_elem) {
+ elem = doc.elementFromPoint(xx, yy);
+ } else {
+ var left_offset = 0, top_offset = 0, offset_parent, use_parent;
+
+ for (use_parent = parent_elem; use_parent; use_parent =
use_parent.ownerDocument.defaultView.frameElement) {
+ offset_parent = use_parent;
+ do {
+ left_offset += offset_parent.offsetLeft - offset_parent.scrollLeft;
+ top_offset += offset_parent.offsetTop - offset_parent.scrollTop;
+
+ offset_parent = offset_parent.offsetParent;
+ /* Stop on body, because it sometimes have the same offset/scroll values as its
iframe parent and sometimes not. */
+ } while (offset_parent && !(/* offset_parent instanceof HTMLBodyElement */
offset_parent.tagName.toUpperCase() == "BODY"));
+ }
+
+ elem = doc.elementFromPoint(xx - left_offset + window.scrollX, yy - top_offset +
window.scrollY);
+ }
+
+ if (!elem) {
+ return parent_elem;
+ }
+
+ if (/* !(elem instanceof HTMLIFrameElement) */ elem.tagName.toUpperCase() != "IFRAME") {
+ return elem;
+ }
+
+ if (parent_elem && parent_elem.isEqualNode(elem)) {
+ return parent_elem;
+ }
+
+ var iframedoc = elem.contentDocument;
+
+ if (!iframedoc) {
+ return parent_elem;
+ }
+
+ return Evo.findElementFromPoint(iframedoc, xx, yy, elem);
+}
+
+Evo.GetElementFromPoint = function(xx, yy)
+{
+ var elem;
+
+ if (xx == -1 && yy == -1)
+ elem = document.activeElement;
+ else
+ elem = Evo.findElementFromPoint(document, xx, yy, null);
+
+ if (!elem)
+ return null;
+
+ var res = [], iframe;
+
+ iframe = elem.ownerDocument.defaultView.frameElement;
+
+ res["iframe-src"] = iframe ? iframe.src : document.documentURI;
+ res["iframe-id"] = iframe ? iframe.id : "";
+ res["elem-id"] = elem.id;
+
+ return res;
+}
+
+Evo.initialize = function(elem)
+{
+ var doc, elems, ii;
+
+ if (elem && /*elem instanceof HTMLIFrameElement*/ elem.tagName.toUpperCase() == "IFRAME" &&
elem.contentDocument) {
+ elem.onload = function() { Evo.initializeAndPostContentLoaded(this); };
+ doc = elem.contentDocument;
+ } else
+ doc = document;
+
+ elems = doc.getElementsByTagName("iframe");
+
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onload = function() { Evo.initializeAndPostContentLoaded(this); };
+
+ if (elems[ii].contentDocument.body && elems[ii].contentDocument.body.childElementCount > 0)
+ Evo.initializeAndPostContentLoaded(elems[ii]);
+ }
+
+ 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");
+ }
+
+ elems = doc.querySelectorAll("input, textarea, select, button, label");
+
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onfocus = function() {
window.webkit.messageHandlers.needInputChanged.postMessage(true); };
+ elems[ii].onblur = function() {
window.webkit.messageHandlers.needInputChanged.postMessage(false); };
+ }
+
+ elems = doc.querySelectorAll("img[src^=\"file://\"]");
+
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].src = "evo-" + elems[ii].src;
+ }
+
+ if (doc.body && doc.querySelector("[data-evo-signature-plain-text-mode]")) {
+ doc.body.setAttribute("style", "font-family: Monospace;");
+ }
+
+ doc.onselectionchange = Evo.selectionChanged;
+}
+
+Evo.initializeAndPostContentLoaded = function(elem)
+{
+ var iframe_id = "";
+
+ if (elem && /*elem instanceof HTMLIFrameElement*/ elem.tagName.toUpperCase() == "IFRAME")
+ iframe_id = elem.id;
+ if (elem && elem.ownerDocument && elem.ownerDocument.defaultView.frameElement)
+ iframe_id = elem.ownerDocument.defaultView.frameElement.id;
+ else if (window.frameElement)
+ iframe_id = window.frameElement.id;
+
+ Evo.initialize(elem);
+ window.webkit.messageHandlers.contentLoaded.postMessage(iframe_id);
+
+ if (window.webkit.messageHandlers.mailDisplayMagicSpacebarStateChanged)
+ Evo.mailDisplayUpdateMagicSpacebarState();
+}
+
+Evo.EnsureMainDocumentInitialized = function()
+{
+ Evo.initializeAndPostContentLoaded(null);
+}
+
+if (this instanceof Window && this.document) {
+ this.document.onload = function() { Evo.initializeAndPostContentLoaded(this); };
+
+ if (this.document.body && this.document.body.firstChild)
+ Evo.initializeAndPostContentLoaded(this.document);
+}
+
+Evo.vCardCollapseContactList = function(elem)
+{
+ if (elem && elem.id && elem.id != "" && elem.ownerDocument) {
+ var list;
+
+ list = elem.ownerDocument.getElementById("list-" + elem.id);
+ if (list) {
+ var child;
+
+ list.hidden = !list.hidden;
+
+ for (child = elem.firstElementChild; child; child = child.nextElementSibling) {
+ if (/*child instanceof HTMLImageElement*/ child.tagName.toUpperCase() ==
"IMG") {
+ child.src = list.hidden ? "gtk-stock://pan-end-symbolic" :
"gtk-stock://pan-down-symbolic";
+ }
+ }
+ }
+ }
+}
+
+Evo.vCardBindInDocument = function(doc)
+{
+ if (!doc)
+ return;
+
+ var elems, ii;
+
+ elems = doc.querySelectorAll("._evo_vcard_collapse_button");
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onclick = function() { Evo.vCardCollapseContactList(this); };
+ }
+}
+
+Evo.VCardBind = function(iframe_id)
+{
+ var traversar = {
+ exec : function(doc, iframe_id, level) {
+ Evo.vCardBindInDocument(doc);
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+}
+
+Evo.mailDisplayResizeContentToPreviewWidth = function()
+{
+ if (!document || !document.documentElement ||
+ document.documentElement.scrollWidth < document.documentElement.clientWidth) {
+ return;
+ }
+
+ var traversar = {
+ can_force_width_on_iframe : function(iframe) {
+ if (!iframe || !iframe.contentDocument)
+ return false;
+
+ /* We can force the width on every message that was not formatted
+ * by text-highlight module. */
+ if (iframe.id.indexOf("text-highlight") < 0)
+ return true;
+
+ /* If the message was formatted with text-highlight we can adjust the
+ * width just for the messages that were formatted as plain text. */
+ return iframe.src.indexOf("__formatas=txt") >= 0;
+ },
+
+ set_iframe_and_body_width : function(doc, width, original_width, level) {
+ if (!doc)
+ return;
+
+ var ii, iframes, local_width = width;
+
+ iframes = doc.getElementsByTagName("iframe");
+
+ if (level == 0) {
+ local_width -= 2; /* 1 + 1 frame borders */
+ } else if (!iframes.length) {
+ /* Message main body */
+ local_width -= 8; /* 8 + 8 margins of body without iframes */
+ if (level > 1)
+ local_width -= 8;
+
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
"body", "width: " + local_width + "px;");
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
".part-container", "width: " + local_width + "px;");
+ } else if (level == 1) {
+ local_width -= 20; /* 10 + 10 margins of body with iframes */
+
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
"body",
+ "width: " + local_width + "px;");
+
+ local_width -= 2; /* 1 + 1 frame borders */
+
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
".part-container-nostyle iframe",
+ "width: " + local_width + "px;");
+
+ /* We need to subtract another 10 pixels from the iframe width to
+ * have the iframe's borders on the correct place. We can't subtract
+ * it from local_width as we don't want to propagate this change
+ * further. */
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
".part-container iframe",
+ "width: " + (local_width - 10) + "px;");
+ } else {
+ local_width -= 20; /* 10 + 10 margins of body with iframes */
+ local_width -= 8; /* attachment margin */
+ local_width -= 2; /* 1 + 1 frame borders */
+
+ /* We need to subtract another 10 pixels from the iframe width to
+ * have the iframe's borders on the correct place. We can't subtract
+ * it from local_width as we don't want to propagate this change
+ * further. */
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet",
".part-container-nostyle iframe",
+ "width: " + (local_width - 10) + "px;");
+
+ Evo.addRuleIntoStyleSheetDocument(doc, "-e-mail-formatter-style-sheet", "body
.part-container-nostyle iframe",
+ "width: " + (local_width - 10) + "px;");
+ }
+
+ /* Add rules to every sub document */
+ for (ii = 0; ii < iframes.length; ii++) {
+ if (!this.can_force_width_on_iframe (iframes[ii]))
+ continue;
+
+ var tmp_local_width = local_width;
+
+ if (level == 0) {
+ tmp_local_width -= 8; /* attachment's margin */
+
+ Evo.addRuleIntoStyleSheetDocument(doc,
"-e-mail-formatter-style-sheet", ".attachment-wrapper iframe:not([src*=\"__formatas=\"])",
+ "width: " + tmp_local_width + "px;");
+
+ Evo.addRuleIntoStyleSheetDocument(doc,
"-e-mail-formatter-style-sheet", ".attachment-wrapper iframe[src*=\"__formatas=txt\"]",
+ "width: " + tmp_local_width + "px;");
+
+ Evo.addRuleIntoStyleSheetDocument(doc,
"-e-mail-formatter-style-sheet", "body > .part-container-nostyle iframe",
+ "width: " + local_width + "px;");
+ }
+
+ this.set_iframe_and_body_width (iframes[ii].contentDocument, tmp_local_width,
original_width, level + 1);
+ }
+ }
+ };
+
+ var width = document.documentElement.clientWidth;
+
+ width -= 20; /* 10 + 10 margins of body */
+
+ traversar.set_iframe_and_body_width(document, width, width, 0);
+}
+
+Evo.mailDisplayUpdateMagicSpacebarState = function()
+{
+ var new_state = 0;
+
+ if (document && document.defaultView && document.documentElement &&
document.documentElement.scrollHeight) {
+ if (document.defaultView.scrollY + document.defaultView.innerHeight <
document.documentElement.scrollHeight)
+ new_state |= (1 << 0); /* E_MAGIC_SPACEBAR_CAN_GO_BOTTOM */
+
+ if (document.defaultView.scrollY > 0)
+ new_state |= (1 << 1); /* E_MAGIC_SPACEBAR_CAN_GO_TOP */
+ }
+
+ if (new_state != Evo.magicSpacebarState) {
+ Evo.magicSpacebarState = new_state;
+
window.webkit.messageHandlers.mailDisplayMagicSpacebarStateChanged.postMessage(Evo.magicSpacebarState);
+ }
+}
+
+Evo.mailDisplayResized = function()
+{
+ Evo.mailDisplayResizeContentToPreviewWidth();
+ Evo.mailDisplayUpdateMagicSpacebarState();
+}
+
+Evo.mailDisplayToggleHeadersVisibility = function(elem)
+{
+ if (!elem || !elem.ownerDocument)
+ return;
+
+ var short_headers, full_headers;
+
+ short_headers = elem.ownerDocument.getElementById("__evo-short-headers");
+ full_headers = elem.ownerDocument.getElementById("__evo-full-headers");
+
+ if (!short_headers || !full_headers)
+ return;
+
+ var expanded = full_headers.style.getPropertyValue("display") == "table";
+
+ full_headers.style.setProperty("display", expanded ? "none" : "table");
+ short_headers.style.setProperty("display", expanded ? "table" : "none");
+
+ if (elem.firstElementChild && /* elem.firstElementChild instanceof HTMLImageElement */
elem.firstElementChild.tagName.toUpperCase() == "IMG") {
+ elem.firstElementChild.src = expanded ? "gtk-stock://pan-end-symbolic" :
"gtk-stock://pan-down-symbolic";
+ }
+
+ window.webkit.messageHandlers.mailDisplayHeadersCollapsed.postMessage(expanded);
+}
+
+Evo.mailDisplayToggleAddressVisibility = function(elem)
+{
+ if (!elem || !elem.ownerDocument)
+ return;
+
+ var parent, img;
+
+ /* get img and parent depending on which element the click came from (button/ellipsis) */
+ if (/* elem instanceof HTMLButtonElement */ elem.tagName.toUpperCase() == "BUTTON") {
+ parent = elem.parentElement.parentElement;
+ img = elem.firstElementChild;
+ } else {
+ var button;
+
+ parent = elem.parentElement;
+ button = parent.parentElement.querySelector("#__evo-moreaddr-button");
+ img = button.firstElementChild;
+ }
+
+ var full_addr, ellipsis;
+
+ full_addr = parent.querySelector("#__evo-moreaddr");
+ ellipsis = parent.querySelector("#__evo-moreaddr-ellipsis");
+
+ if (full_addr && ellipsis) {
+ var expanded;
+
+ expanded = full_addr.style.getPropertyValue("display") == "inline";
+
+ full_addr.style.setProperty("display", expanded ? "none" : "inline");
+ ellipsis.style.setProperty("display", expanded ? "inline" : "none");
+ img.src = expanded ? "gtk-stock://pan-end-symbolic" : "gtk-stock://pan-down-symbolic";
+ }
+}
+
+Evo.mailDisplayVCardModeButtonClicked = function(elem)
+{
+ if (!elem || !elem.parentElement)
+ return;
+
+ var normal_btn = null, compact_btn = null, iframe_elem = null, child;
+
+ for (child = elem.parentElement.firstElementChild; child; child = child.nextElementSibling) {
+ if (!iframe_elem && /* child instanceof HTMLImageElement */ child.tagName.toUpperCase() ==
"IFRAME") {
+ iframe_elem = child;
+
+ if (normal_btn && compact_btn)
+ break;
+
+ continue;
+ }
+
+ var name = child.getAttribute("name");
+
+ if (name) {
+ if (!normal_btn && name == "set-display-mode-normal")
+ normal_btn = child;
+ else if (!compact_btn && name == "set-display-mode-compact")
+ compact_btn = child;
+
+ if (normal_btn && compact_btn && iframe_elem)
+ break;
+ }
+ }
+
+ if (normal_btn && compact_btn && iframe_elem) {
+ normal_btn.hidden = normal_btn.isEqualNode(elem);
+ compact_btn.hidden = !normal_btn.hidden;
+ iframe_elem.src = elem.getAttribute("evo-iframe-uri");
+ }
+}
+
+Evo.MailDisplayBindDOM = function(iframe_id)
+{
+ var traversar = {
+ unstyleBlockquotes : function(doc) {
+ var ii, elems;
+
+ elems = doc.getElementsByTagName("blockquote");
+ for (ii = 0; ii < elems.length; ii++) {
+ var elem = elems[ii];
+
+ if (elem.hasAttribute("type")) {
+ if (elem.getAttribute("type").toLowerCase() == "cite")
+ elem.removeAttribute("style");
+ } else {
+ elem.removeAttribute("style");
+ elem.setAttribute("type", "cite");
+ }
+
+ if (elem.hasAttribute("style") &&
+ elem.getAttribute("style") == Evo.blockquoteStyle) {
+ elem.removeAttribute("style");
+ }
+ }
+ },
+ textRequiresWrap : function(text) {
+ if (!text || text.length <= 80)
+ return false;
+
+ var cnt = -1, ii;
+
+ for (ii = 0; ii < text.length; ii++) {
+ cnt++;
+
+ var chr = text.charAt(ii);
+
+ if (chr == ' ' || chr == '\t' || chr == '\r' || chr == '\n')
+ cnt == -1;
+ else if (cnt > 80)
+ return true;
+ }
+
+ return false;
+ },
+ wrapLongAchors : function(doc) {
+ var ii, elems;
+
+ elems = doc.getElementsByTagName("blockquote");
+ for (ii = 0; ii < elems.length; ii++) {
+ var elem = elems[ii];
+
+ if (this.textRequiresWrap(elem.innerText))
+ elem.classList.add("evo-awrap");
+ else
+ elem.classList.remove("evo-awrap");
+ }
+ },
+ bind : function(doc) {
+ var ii, elems;
+
+ elems = doc.querySelectorAll("#__evo-collapse-headers-img");
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onclick = function() {
Evo.mailDisplayToggleHeadersVisibility(this); };
+ }
+
+ elems = doc.querySelectorAll("#__evo-moreaddr-ellipsis");
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onclick = function() {
Evo.mailDisplayToggleAddressVisibility(this); };
+ }
+
+ elems = doc.querySelectorAll("#__evo-moreaddr-button");
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onclick = function() {
Evo.mailDisplayToggleAddressVisibility(this); };
+ }
+
+ elems = doc.querySelectorAll(".org-gnome-vcard-display-mode-button");
+ for (ii = 0; ii < elems.length; ii++) {
+ elems[ii].onclick = function() { Evo.mailDisplayVCardModeButtonClicked(this);
};
+ }
+
+ var elem;
+
+ elem = doc.getElementById("__evo-contact-photo");
+
+ if (elem && elem.hasAttribute("data-mailaddr")) {
+ var mail_addr;
+
+ mail_addr = elem.getAttribute("data-mailaddr");
+ if (mail_addr != "") {
+ elem.src = "mail://contact-photo?mailaddr=" + mail_addr;
+ }
+ }
+ },
+ exec : function(doc, iframe_id, level) {
+ if (doc) {
+ this.unstyleBlockquotes(doc);
+ this.wrapLongAchors(doc);
+ this.bind(doc);
+
+ Evo.vCardBindInDocument(doc);
+
+ Evo.addRuleIntoStyleSheetDocument(doc,
+ "-e-mail-formatter-style-sheet",
+ "a.evo-awrap",
+ "white-space: normal; word-break: break-all;");
+ }
+
+ return true;
+ }
+ };
+
+ Evo.runTraversarForIFrameId(iframe_id, traversar);
+
+ Evo.mailDisplayResizeContentToPreviewWidth();
+ Evo.mailDisplayUpdateMagicSpacebarState();
+
+ document.defaultView.onresize = Evo.mailDisplayResized;
+ document.defaultView.onscroll = Evo.mailDisplayUpdateMagicSpacebarState;
+}
+
+Evo.MailDisplayShowAttachment = function(element_id, show)
+{
+ var elem;
+
+ elem = Evo.findElement("*", element_id);
+
+ if (!elem) {
+ return;
+ }
+
+ elem.hidden = !show;
+
+ if (elem.hasAttribute("inner-html-data")) {
+ var html_data = elem.getAttribute("inner-html-data");
+
+ elem.removeAttribute("inner-html-data");
+
+ if (html_data && html_data != "") {
+ elem.innerHTML = html_data;
+
+ var iframe;
+
+ iframe = elem.querySelector("iframe");
+
+ if (iframe) {
+ Evo.initializeAndPostContentLoaded(iframe);
+ Evo.MailDisplayBindDOM(iframe.id);
+ }
+
+ var iframe_id = "";
+
+ if (elem.ownerDocument.defaultView.frameElement)
+ iframe_id = elem.ownerDocument.defaultView.frameElement.id;
+
+ window.webkit.messageHandlers.contentLoaded.postMessage(iframe_id);
+ Evo.mailDisplayUpdateMagicSpacebarState();
+ }
+ }
+}
+
+Evo.MailDisplayProcessMagicSpacebar = function(towards_bottom)
+{
+ if (document && document.defaultView && document.defaultView.innerHeight) {
+ document.defaultView.scrollBy(0, (towards_bottom ? 1 : -1) *
document.defaultView.innerHeight);
+ }
+
+ Evo.mailDisplayUpdateMagicSpacebarState();
+}
+
+var EvoItip = {
+ SELECT_ESOURCE : "select_esource",
+ TEXTAREA_RSVP_COMMENT : "textarea_rsvp_comment",
+ CHECKBOX_RSVP : "checkbox_rsvp",
+ CHECKBOX_RECUR : "checkbox_recur",
+ CHECKBOX_KEEP_ALARM : "checkbox_keep_alarm",
+ CHECKBOX_INHERIT_ALARM : "checkbox_inherit_alarm",
+ CHECKBOX_UPDATE : "checkbox_update",
+ CHECKBOX_FREE_TIME : "checkbox_free_time",
+ TABLE_ROW_BUTTONS : "table_row_buttons"
+};
+
+EvoItip.alarmCheckClickedCb = function(check1)
+{
+ var check2;
+
+ if (check1.id == EvoItip.CHECKBOX_KEEP_ALARM) {
+ check2 = check1.ownerDocument.getElementById(EvoItip.CHECKBOX_INHERIT_ALARM);
+ } else {
+ check2 = check1.ownerDocument.getElementById(EvoItip.CHECKBOX_KEEP_ALARM);
+ }
+
+ if (check2) {
+ check2.disabled = check1.hidden && check1.checked;
+ }
+}
+
+EvoItip.selectedSourceChanged = function(elem)
+{
+ var data = {};
+
+ data["iframe-id"] = elem.ownerDocument.defaultView.frameElement.id;
+ data["source-uid"] = elem.value;
+
+ window.webkit.messageHandlers.itipSourceChanged.postMessage(data);
+}
+
+EvoItip.Initialize = function(iframe_id)
+{
+ var doc = Evo.findIFrameDocument(iframe_id);
+
+ if (!doc) {
+ return;
+ }
+
+ var elem;
+
+ elem = doc.getElementById(EvoItip.SELECT_ESOURCE);
+ if (elem) {
+ elem.onchange = function() { EvoItip.selectedSourceChanged(this); };
+ }
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RECUR);
+ if (elem) {
+ elem.onclick = function() {
window.webkit.messageHandlers.itipRecurToggled.postMessage(this.ownerDocument.defaultView.frameElement.id); };
+ }
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RSVP);
+ if (elem) {
+ elem.onclick = function() {
+ var elem = this.ownerDocument.getElementById(EvoItip.TEXTAREA_RSVP_COMMENT);
+ if (elem) {
+ elem.disabled = !this.checked;
+ }
+ };
+ }
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_INHERIT_ALARM);
+ if (elem) {
+ elem.onclick = function() { EvoItip.alarmCheckClickedCb(this); };
+ }
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_KEEP_ALARM);
+ if (elem) {
+ elem.onclick = function() { EvoItip.alarmCheckClickedCb(this); };
+ }
+}
+
+EvoItip.SetElementInnerHTML = function(iframe_id, element_id, html_content)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem)
+ elem.innerHTML = html_content;
+}
+
+EvoItip.SetShowCheckbox = function(iframe_id, element_id, show, update_second)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ elem.hidden = !show;
+
+ if (elem.nextElementSibling) {
+ elem.nextElementSibling.hidden = !show;
+ }
+
+ if (!show) {
+ elem.checked = false;
+ }
+
+ if (update_second) {
+ EvoItip.alarmCheckClickedCb(elem);
+ }
+
+ elem = elem.ownerDocument.getElementById("table_row_" + element_id);
+ if (elem) {
+ elem.hidden = !show;
+ }
+ }
+}
+
+EvoItip.SetAreaText = function(iframe_id, element_id, text)
+{
+ var row = Evo.findElement(iframe_id, element_id);
+
+ if (row) {
+ row.hidden = text == "";
+
+ if (row.lastElementChild) {
+ row.lastElementChild.innerHTML = text;
+ }
+ }
+}
+
+EvoItip.UpdateTimes = function(iframe_id, element_id, header, label)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ elem.hidden = false;
+
+ if (elem.firstElementChild) {
+ elem.firstElementChild.innerHTML = header;
+ }
+
+ if (elem.lastElementChild) {
+ elem.lastElementChild.innerHTML = label;
+ }
+ }
+}
+
+EvoItip.AppendInfoRow = function(iframe_id, table_id, row_id, icon_name, message)
+{
+ var cell, row, table = Evo.findElement(iframe_id, table_id);
+
+ if (!table) {
+ return;
+ }
+
+ row = table.insertRow(-1);
+ row.id = row_id;
+
+ cell = row.insertCell(-1);
+
+ if (icon_name && icon_name != "") {
+ var img;
+
+ img = table.ownerDocument.createElement("img");
+ img.src = "gtk-stock://" + icon_name;
+
+ cell.appendChild(img);
+ }
+
+ cell = row.insertCell(-1);
+ cell.innerHTML = message;
+}
+
+EvoItip.RemoveInfoRow = function(iframe_id, row_id)
+{
+ var row = Evo.findElement(iframe_id, row_id);
+
+ if (row && row.parentNode) {
+ row.parentNode.removeChild(row);
+ }
+}
+
+EvoItip.RemoveChildNodes = function(iframe_id, element_id)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ while (elem.lastChild) {
+ elem.removeChild(elem.lastChild);
+ }
+ }
+}
+
+EvoItip.AddToSourceList = function(iframe_id, optgroup_id, optgroup_label, option_id, option_label, writable)
+{
+ var doc, select_elem;
+
+ doc = Evo.findIFrameDocument(iframe_id);
+ select_elem = doc ? doc.getElementById(EvoItip.SELECT_ESOURCE) : null;
+
+ if (!select_elem) {
+ return;
+ }
+
+ var option, optgroup;
+
+ optgroup = doc.getElementById (optgroup_id);
+
+ if (!optgroup) {
+ optgroup = doc.createElement("optgroup");
+ optgroup.id = optgroup_id;
+ optgroup.label = optgroup_label;
+
+ select_elem.appendChild(optgroup);
+ }
+
+ option = doc.createElement("option");
+ option.value = option_id;
+ option.label = option_label;
+ option.innerHTML = option_label;
+ option.className = "calendar";
+
+ if (!writable) {
+ option.disabled = true;
+ }
+
+ optgroup.appendChild(option);
+}
+
+EvoItip.HideButtons = function(iframe_id, element_id)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ var child;
+
+ for (child = elem.firstElementChild; child; child = child.nextElementSibling) {
+ var button = child.firstElementChild;
+
+ if (button)
+ button.hidden = true;
+ }
+ }
+}
+
+EvoItip.SetElementAccessKey = function(iframe_id, element_id, access_key)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ elem.accessKey = access_key;
+ }
+}
+
+EvoItip.SetSelectSelected = function(iframe_id, element_id, option_value)
+{
+ var elem = Evo.findElement(iframe_id, element_id);
+
+ if (elem) {
+ var ii;
+
+ for (ii = 0; ii < elem.length; ii++) {
+ if (elem.item(ii).value == option_value) {
+ elem.item(ii).selected = true;
+ break;
+ }
+ }
+ }
+}
+
+EvoItip.SetButtonsDisabled = function(iframe_id, disabled)
+{
+ var doc = Evo.findIFrameDocument(iframe_id);
+
+ if (!doc) {
+ return;
+ }
+
+ var elem, cell;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_UPDATE);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RECUR);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_FREE_TIME);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_KEEP_ALARM);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_INHERIT_ALARM);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RSVP);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.TEXTAREA_RSVP_COMMENT);
+ if (elem)
+ elem.disabled = disabled;
+
+ elem = doc.getElementById(EvoItip.TABLE_ROW_BUTTONS);
+ if (!elem)
+ return;
+
+ for (cell = elem.firstElementChild; cell; cell = cell.nextElementSibling) {
+ var btn = cell.firstElementChild;
+
+ if (btn && !btn.hidden) {
+ btn.disabled = disabled;
+ }
+ }
+}
+
+EvoItip.GetState = function(iframe_id)
+{
+ var doc;
+
+ doc = Evo.findIFrameDocument(iframe_id);
+
+ if (!doc) {
+ return null;
+ }
+
+ var elem, res = {};
+
+ elem = doc.getElementById(EvoItip.TEXTAREA_RSVP_COMMENT);
+ res["rsvp-comment"] = elem ? elem.value : null;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RSVP);
+ res["rsvp-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_UPDATE);
+ res["update-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_RECUR);
+ res["recur-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_FREE_TIME);
+ res["free-time-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_KEEP_ALARM);
+ res["keep-alarm-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ elem = doc.getElementById(EvoItip.CHECKBOX_INHERIT_ALARM);
+ res["inherit-alarm-check"] = elem && elem.checked && !elem.hidden && !elem.disabled;
+
+ return res;
+}
diff --git a/data/webview-print.css b/data/webkit/webview-print.css
similarity index 100%
rename from data/webview-print.css
rename to data/webkit/webview-print.css
diff --git a/data/webview.css b/data/webkit/webview.css
similarity index 100%
rename from data/webview.css
rename to data/webkit/webview.css
diff --git a/src/addressbook/gui/widgets/eab-contact-display.c
b/src/addressbook/gui/widgets/eab-contact-display.c
index 5389924d34..b9eae723e2 100644
--- a/src/addressbook/gui/widgets/eab-contact-display.c
+++ b/src/addressbook/gui/widgets/eab-contact-display.c
@@ -385,26 +385,14 @@ contact_display_link_clicked (EWebView *web_view,
}
static void
-contact_display_notify_web_extension_proxy_cb (GObject *web_view,
- GParamSpec *param,
- gpointer user_data)
+contact_display_content_loaded_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ gpointer user_data)
{
- GDBusProxy *web_extension;
- GVariant* result;
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
- if (web_extension) {
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- web_extension,
- "EABContactFormatterBindDOM",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view))),
- NULL);
-
- if (result)
- g_variant_unref (result);
- }
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (web_view));
+
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "Evo.VCardBind(%s);", iframe_id);
}
static void
@@ -532,8 +520,8 @@ eab_contact_display_init (EABContactDisplay *display)
G_CALLBACK (contact_display_web_process_crashed_cb), NULL);
g_signal_connect (
- web_view, "notify::web-extension-proxy",
- G_CALLBACK (contact_display_notify_web_extension_proxy_cb), NULL);
+ web_view, "content-loaded",
+ G_CALLBACK (contact_display_content_loaded_cb), NULL);
g_signal_connect (
web_view, "style-updated",
G_CALLBACK (load_contact), NULL);
diff --git a/src/addressbook/gui/widgets/eab-contact-formatter.c
b/src/addressbook/gui/widgets/eab-contact-formatter.c
index 3276743434..197068a306 100644
--- a/src/addressbook/gui/widgets/eab-contact-formatter.c
+++ b/src/addressbook/gui/widgets/eab-contact-formatter.c
@@ -51,7 +51,7 @@
#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
"<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n" \
-"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR
"/theme/webview.css\">" \
+"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://$EVOLUTION_WEBKITDATADIR/webview.css\">" \
"<style type=\"text/css\">\n" \
" div#header { width:100%; clear: both; }\n" \
" div#columns { width: 100%; clear: both; }\n" \
@@ -621,7 +621,7 @@ render_contact_list_row (EABContactFormatter *formatter,
g_string_append_printf (
buffer,
"<td width=" IMAGE_COL_WIDTH " valign=\"top\" align=\"left\">"
- "<button type=\"button\" id=\"%s\" class=\"header-collapse _evo_collapse_button\"
style=\"display: inline-block;\">"
+ "<button type=\"button\" id=\"%s\" class=\"header-collapse
_evo_vcard_collapse_button\" style=\"display: inline-block;\">"
"<img src=\"gtk-stock://pan-down-symbolic\" />"
"</button>"
"</td><td width=\"100%%\" align=\"left\">%s",
diff --git a/src/calendar/gui/CMakeLists.txt b/src/calendar/gui/CMakeLists.txt
index dcf5fe171d..405773499f 100644
--- a/src/calendar/gui/CMakeLists.txt
+++ b/src/calendar/gui/CMakeLists.txt
@@ -185,7 +185,6 @@ add_dependencies(evolution-calendar
target_compile_definitions(evolution-calendar PRIVATE
-DG_LOG_DOMAIN=\"evolution-calendar\"
-DEVOLUTION_ETSPECDIR=\"${etspecdir}\"
- -DEVOLUTION_PRIVDATADIR=\"${privdatadir}\"
)
target_compile_options(evolution-calendar PUBLIC
diff --git a/src/calendar/gui/e-cal-component-preview.c b/src/calendar/gui/e-cal-component-preview.c
index e667131732..3f8a1a6aec 100644
--- a/src/calendar/gui/e-cal-component-preview.c
+++ b/src/calendar/gui/e-cal-component-preview.c
@@ -61,7 +61,7 @@ struct _ECalComponentPreviewPrivate {
#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
"<head>\n<meta name=\"generator\" content=\"Evolution Calendar Component\">\n" \
- "<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR
"/theme/webview.css\">\n" \
+ "<link type=\"text/css\" rel=\"stylesheet\"
href=\"evo-file://$EVOLUTION_WEBKITDATADIR/webview.css\">\n" \
"<style>\n" \
".description { font-family: monospace; font-size: 1em; }\n" \
"</style>\n" \
diff --git a/src/e-util/CMakeLists.txt b/src/e-util/CMakeLists.txt
index 81ae3cd72c..eb9523d37a 100644
--- a/src/e-util/CMakeLists.txt
+++ b/src/e-util/CMakeLists.txt
@@ -270,8 +270,9 @@ set(SOURCES
e-util-private.h
e-webdav-browser.c
e-web-extension-container.c
- e-web-view-preview.c
e-web-view.c
+ e-web-view-jsc-utils.c
+ e-web-view-preview.c
e-widget-undo.c
e-xml-utils.c
ea-calendar-cell.c
@@ -543,8 +544,9 @@ set(HEADERS
e-util-enums.h
e-webdav-browser.h
e-web-extension-container.h
- e-web-view-preview.h
e-web-view.h
+ e-web-view-jsc-utils.h
+ e-web-view-preview.h
e-widget-undo.h
e-xml-utils.h
ea-calendar-cell.h
@@ -613,6 +615,7 @@ target_compile_definitions(evolution-util PRIVATE
-DEVOLUTION_UIDIR=\"${uidir}\"
-DEVOLUTION_RULEDIR=\"${privdatadir}\"
-DEVOLUTION_WEB_EXTENSIONS_DIR=\"${webextensionsdir}\"
+ -DEVOLUTION_WEBKITDATADIR=\"${webkitdatadir}\"
-DEVOLUTION_TESTGIOMODULESDIR=\"${CMAKE_CURRENT_BINARY_DIR}\"
-DEVOLUTION_TESTTOPSRCDIR=\"${CMAKE_SOURCE_DIR}\"
-DLIBEUTIL_COMPILATION
@@ -808,6 +811,7 @@ add_private_programs_simple(
test-source-config
test-source-selector
test-tree-view-frame
+ test-web-view-jsc
)
add_private_program(test-html-editor-units
diff --git a/src/e-util/e-file-request.c b/src/e-util/e-file-request.c
index f58c8093be..090f8cf100 100644
--- a/src/e-util/e-file-request.c
+++ b/src/e-util/e-file-request.c
@@ -59,6 +59,7 @@ e_file_request_process_sync (EContentRequest *request,
GFileInputStream *file_input_stream;
GFileInfo *info;
goffset total_size;
+ gchar *filename = NULL;
SoupURI *suri;
g_return_val_if_fail (E_IS_FILE_REQUEST (request), FALSE);
@@ -70,7 +71,13 @@ e_file_request_process_sync (EContentRequest *request,
suri = soup_uri_new (uri);
g_return_val_if_fail (suri != NULL, FALSE);
- file = g_file_new_for_path (suri->path);
+ if (g_strcmp0 (suri->host, "$EVOLUTION_WEBKITDATADIR") == 0) {
+ filename = g_build_filename (EVOLUTION_WEBKITDATADIR, suri->path, NULL);
+ } else if (g_strcmp0 (suri->host, "$EVOLUTION_IMAGESDIR") == 0) {
+ filename = g_build_filename (EVOLUTION_IMAGESDIR, suri->path, NULL);
+ }
+
+ file = g_file_new_for_path (filename ? filename : suri->path);
file_input_stream = g_file_read (file, cancellable, error);
if (file_input_stream) {
@@ -97,7 +104,7 @@ e_file_request_process_sync (EContentRequest *request,
if (file_input_stream) {
*out_stream = G_INPUT_STREAM (file_input_stream);
*out_stream_length = (gint64) total_size;
- *out_mime_type = g_content_type_guess (suri->path, NULL, 0, NULL);
+ *out_mime_type = g_content_type_guess (filename ? filename : suri->path, NULL, 0, NULL);
} else {
*out_stream = NULL;
*out_stream_length = (gint64) total_size;
@@ -106,6 +113,7 @@ e_file_request_process_sync (EContentRequest *request,
g_object_unref (file);
soup_uri_free (suri);
+ g_free (filename);
return file_input_stream != NULL;
}
diff --git a/src/e-util/e-util-private.h b/src/e-util/e-util-private.h
index 030f2b6cbf..f3ce879f86 100644
--- a/src/e-util/e-util-private.h
+++ b/src/e-util/e-util-private.h
@@ -56,6 +56,7 @@ const gchar *_e_get_sounddir (void) G_GNUC_CONST;
const gchar *_e_get_sysconfdir (void) G_GNUC_CONST;
const gchar *_e_get_toolsdir (void) G_GNUC_CONST;
const gchar *_e_get_uidir (void) G_GNUC_CONST;
+const gchar *_e_get_webkitdatadir (void) G_GNUC_CONST;
#undef DATADIR
#define DATADIR _e_get_datadir ()
@@ -123,6 +124,9 @@ const gchar *_e_get_uidir (void) G_GNUC_CONST;
#undef EVOLUTION_RULEDIR
#define EVOLUTION_RULEDIR _e_get_ruledir ()
+#undef EVOLUTION_WEBKITDATADIR
+#define EVOLUTION_WEBKITDATADIR _e_get_webkitdatadir ()
+
#endif /* G_OS_WIN32 */
#endif /* _E_UTIL_PRIVATE_H_ */
diff --git a/src/e-util/e-util.h b/src/e-util/e-util.h
index 84db520bed..fa0d82b540 100644
--- a/src/e-util/e-util.h
+++ b/src/e-util/e-util.h
@@ -266,8 +266,9 @@
#include <e-util/e-webdav-browser.h>
#include <e-util/e-web-extension-container.h>
#ifndef E_UTIL_INCLUDE_WITHOUT_WEBKIT
-#include <e-util/e-web-view-preview.h>
#include <e-util/e-web-view.h>
+#include <e-util/e-web-view-jsc-utils.h>
+#include <e-util/e-web-view-preview.h>
#endif
#include <e-util/e-widget-undo.h>
#include <e-util/e-xml-utils.h>
diff --git a/src/e-util/e-web-view-jsc-utils.c b/src/e-util/e-web-view-jsc-utils.c
new file mode 100644
index 0000000000..ccdd8c84ff
--- /dev/null
+++ b/src/e-util/e-web-view-jsc-utils.c
@@ -0,0 +1,711 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2019 Red Hat (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-config.h"
+
+#include <webkit2/webkit2.h>
+
+#include "e-web-view-jsc-utils.h"
+
+gboolean
+e_web_view_jsc_get_object_property_boolean (JSCValue *jsc_object,
+ const gchar *property_name,
+ gboolean default_value)
+{
+ JSCValue *value;
+ gboolean res = default_value;
+
+ g_return_val_if_fail (JSC_IS_VALUE (jsc_object), default_value);
+ g_return_val_if_fail (property_name != NULL, default_value);
+
+ value = jsc_value_object_get_property (jsc_object, property_name);
+ if (!value)
+ return default_value;
+
+ if (jsc_value_is_boolean (value))
+ res = jsc_value_to_boolean (value);
+
+ g_clear_object (&value);
+
+ return res;
+}
+
+gint32
+e_web_view_jsc_get_object_property_int32 (JSCValue *jsc_object,
+ const gchar *property_name,
+ gint32 default_value)
+{
+ JSCValue *value;
+ gint32 res = default_value;
+
+ g_return_val_if_fail (JSC_IS_VALUE (jsc_object), default_value);
+ g_return_val_if_fail (property_name != NULL, default_value);
+
+ value = jsc_value_object_get_property (jsc_object, property_name);
+ if (!value)
+ return default_value;
+
+ if (jsc_value_is_number (value))
+ res = jsc_value_to_int32 (value);
+
+ g_clear_object (&value);
+
+ return res;
+}
+
+gdouble
+e_web_view_jsc_get_object_property_double (JSCValue *jsc_object,
+ const gchar *property_name,
+ gdouble default_value)
+{
+ JSCValue *value;
+ gdouble res = default_value;
+
+ g_return_val_if_fail (JSC_IS_VALUE (jsc_object), default_value);
+ g_return_val_if_fail (property_name != NULL, default_value);
+
+ value = jsc_value_object_get_property (jsc_object, property_name);
+ if (!value)
+ return default_value;
+
+ if (jsc_value_is_number (value))
+ res = jsc_value_to_double (value);
+
+ g_clear_object (&value);
+
+ return res;
+}
+
+gchar *
+e_web_view_jsc_get_object_property_string (JSCValue *jsc_object,
+ const gchar *property_name,
+ const gchar *default_value)
+{
+ JSCValue *value;
+ gchar *res;
+
+ g_return_val_if_fail (JSC_IS_VALUE (jsc_object), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ value = jsc_value_object_get_property (jsc_object, property_name);
+ if (!value)
+ return g_strdup (default_value);
+
+ if (jsc_value_is_string (value))
+ res = jsc_value_to_string (value);
+ else
+ res = g_strdup (default_value);
+
+ g_clear_object (&value);
+
+ return res;
+}
+
+gchar *
+e_web_view_jsc_printf_script (const gchar *script_format,
+ ...)
+{
+ gchar *script;
+ va_list va;
+
+ g_return_val_if_fail (script_format != NULL, NULL);
+
+ va_start (va, script_format);
+ script = e_web_view_jsc_vprintf_script (script_format, va);
+ va_end (va);
+
+ return script;
+}
+
+gchar *
+e_web_view_jsc_vprintf_script (const gchar *script_format,
+ va_list va)
+{
+ GString *script;
+
+ g_return_val_if_fail (script_format != NULL, NULL);
+
+ script = g_string_sized_new (128);
+
+ e_web_view_jsc_vprintf_script_gstring (script, script_format, va);
+
+ return g_string_free (script, FALSE);
+}
+
+void
+e_web_view_jsc_printf_script_gstring (GString *script,
+ const gchar *script_format,
+ ...)
+{
+ va_list va;
+
+ g_return_if_fail (script != NULL);
+ g_return_if_fail (script_format != NULL);
+
+ va_start (va, script_format);
+ e_web_view_jsc_vprintf_script_gstring (script, script_format, va);
+ va_end (va);
+}
+
+void
+e_web_view_jsc_vprintf_script_gstring (GString *script,
+ const gchar *script_format,
+ va_list va)
+{
+ const gchar *ptr;
+
+ g_return_if_fail (script != NULL);
+ g_return_if_fail (script_format != NULL);
+
+ if (script->len)
+ g_string_append_c (script, '\n');
+
+ for (ptr = script_format; *ptr; ptr++) {
+ if (*ptr == '\\') {
+ g_warn_if_fail (ptr[1]);
+
+ g_string_append_c (script, ptr[0]);
+ g_string_append_c (script, ptr[1]);
+
+ ptr++;
+ } else if (*ptr == '%') {
+ g_warn_if_fail (ptr[1]);
+
+ switch (ptr[1]) {
+ case '%':
+ g_string_append_c (script, ptr[1]);
+ break;
+ /* Using %x for boolean, because %b is unknown to gcc, thus it claims format warnings
*/
+ case 'x': {
+ gboolean arg = va_arg (va, gboolean);
+
+ g_string_append (script, arg ? "true" : "false");
+ } break;
+ case 'd': {
+ gint arg = va_arg (va, gint);
+
+ g_string_append_printf (script, "%d", arg);
+ } break;
+ case 'f': {
+ gdouble arg = va_arg (va, gdouble);
+
+ g_string_append_printf (script, "%f", arg);
+ } break;
+ case 's': {
+ const gchar *arg = va_arg (va, const gchar *);
+
+ /* Enclose strings into double-quotes */
+ g_string_append_c (script, '\"');
+
+ /* Escape significant characters */
+ if (arg && (strchr (arg, '\"') ||
+ strchr (arg, '\\') ||
+ strchr (arg, '\n') ||
+ strchr (arg, '\r') ||
+ strchr (arg, '\t'))) {
+ const gchar *ptr2;
+
+ for (ptr2 = arg; *ptr2; ptr2++) {
+ if (*ptr2 == '\\')
+ g_string_append (script, "\\\\");
+ else if (*ptr2 == '\"')
+ g_string_append (script, "\\\"");
+ else if (*ptr2 == '\r')
+ g_string_append (script, "\\r");
+ else if (*ptr2 == '\n')
+ g_string_append (script, "\\n");
+ else if (*ptr2 == '\t')
+ g_string_append (script, "\\t");
+ else
+ g_string_append_c (script, *ptr2);
+ }
+ } else if (arg && *arg) {
+ g_string_append (script, arg);
+ }
+
+ g_string_append_c (script, '\"');
+
+ } break;
+ default:
+ g_warning ("%s: Unknown percent tag '%c'", G_STRFUNC, *ptr);
+ break;
+ }
+
+ ptr++;
+ } else {
+ g_string_append_c (script, *ptr);
+ }
+ }
+}
+
+static void
+ewv_jsc_call_done_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ WebKitJavascriptResult *js_result;
+ gchar *script = user_data;
+ GError *error = NULL;
+
+ js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (source), result, &error);
+
+ if (error) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ (!g_error_matches (error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED)
||
+ /* WebKit can return empty error message, thus ignore those. */
+ (error->message && *(error->message))))
+ g_warning ("Failed to call '%s' function: %s:%d: %s", script, g_quark_to_string
(error->domain), error->code, error->message);
+ g_clear_error (&error);
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception)
+ g_warning ("Failed to call '%s': %s", script, jsc_exception_get_message (exception));
+
+ webkit_javascript_result_unref (js_result);
+ }
+
+ g_free (script);
+}
+
+void
+e_web_view_jsc_run_script (WebKitWebView *web_view,
+ GCancellable *cancellable,
+ const gchar *script_format,
+ ...)
+{
+ gchar *script;
+ va_list va;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (script_format != NULL);
+
+ va_start (va, script_format);
+ script = e_web_view_jsc_vprintf_script (script_format, va);
+ va_end (va);
+
+ e_web_view_jsc_run_script_take (web_view, script, cancellable);
+}
+
+/* Assumes ownership of the 'script' variable and frees is with g_free(), when no longe needed. */
+void
+e_web_view_jsc_run_script_take (WebKitWebView *web_view,
+ gchar *script,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (script != NULL);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, ewv_jsc_call_done_cb, script);
+}
+
+void
+e_web_view_jsc_set_element_hidden (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.SetElementHidden(%s,%s,%d)",
+ iframe_id,
+ element_id,
+ value ? 1 : 0);
+}
+
+void
+e_web_view_jsc_set_element_disabled (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.SetElementDisabled(%s,%s,%d)",
+ iframe_id,
+ element_id,
+ value ? 1 : 0);
+}
+
+void
+e_web_view_jsc_set_element_checked (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.SetElementChecked(%s,%s,%d)",
+ iframe_id,
+ element_id,
+ value ? 1 : 0);
+}
+
+void
+e_web_view_jsc_set_element_style_property (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *property_name,
+ const gchar *value,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+ g_return_if_fail (property_name != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.SetElementStyleProperty(%s,%s,%s,%s)",
+ iframe_id,
+ element_id,
+ property_name,
+ value);
+}
+
+void
+e_web_view_jsc_set_element_attribute (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *namespace_uri,
+ const gchar *qualified_name,
+ const gchar *value,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+ g_return_if_fail (qualified_name != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.SetElementAttribute(%s,%s,%s,%s,%s)",
+ iframe_id,
+ element_id,
+ namespace_uri,
+ qualified_name,
+ value);
+}
+
+void
+e_web_view_jsc_create_style_sheet (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *content,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.CreateStyleSheet(%s,%s,%s)",
+ iframe_id,
+ style_sheet_id,
+ content);
+}
+
+void
+e_web_view_jsc_remove_style_sheet (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.RemoveStyleSheet(%s,%s)",
+ iframe_id,
+ style_sheet_id);
+}
+
+void
+e_web_view_jsc_add_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_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.AddRuleIntoStyleSheet(%s,%s,%s,%s)",
+ iframe_id,
+ style_sheet_id,
+ selector,
+ style);
+}
+
+void
+e_web_view_jsc_register_element_clicked (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *elem_classes,
+ GCancellable *cancellable)
+{
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (elem_classes != NULL);
+
+ e_web_view_jsc_run_script (web_view, cancellable,
+ "Evo.RegisterElementClicked(%s,%s)",
+ iframe_id,
+ elem_classes);
+}
+
+static gboolean
+ewv_jsc_get_content_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error)
+{
+ WebKitJavascriptResult *js_result;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (out_texts != NULL, FALSE);
+
+ *out_texts = NULL;
+
+ js_result = webkit_web_view_run_javascript_finish (web_view, result, &local_error);
+
+ if (local_error) {
+ g_propagate_error (error, local_error);
+
+ if (js_result)
+ webkit_javascript_result_unref (js_result);
+
+ return FALSE;
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Call failed: %s",
jsc_exception_get_message (exception));
+ webkit_javascript_result_unref (js_result);
+ return FALSE;
+ }
+
+ if (jsc_value_is_string (value)) {
+ *out_texts = g_slist_prepend (*out_texts, jsc_value_to_string (value));
+ } else if (jsc_value_is_object (value)) {
+ *out_texts = g_slist_prepend (*out_texts, e_web_view_jsc_get_object_property_string
(value, "html", NULL));
+ *out_texts = g_slist_prepend (*out_texts, e_web_view_jsc_get_object_property_string
(value, "plain", NULL));
+ }
+
+ webkit_javascript_result_unref (js_result);
+ }
+
+ return TRUE;
+}
+
+void
+e_web_view_jsc_get_selection (WebKitWebView *web_view,
+ ETextFormat format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+
+ script = e_web_view_jsc_printf_script ("Evo.GetSelection(%d)", format);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, callback, user_data);
+
+ g_free (script);
+}
+
+gboolean
+e_web_view_jsc_get_selection_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error)
+{
+ g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (out_texts != NULL, FALSE);
+
+ return ewv_jsc_get_content_finish (web_view, result, out_texts, error);
+}
+
+void
+e_web_view_jsc_get_document_content (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ ETextFormat format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+
+ script = e_web_view_jsc_printf_script ("Evo.GetDocumentContent(%s,%d)", iframe_id, format);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, callback, user_data);
+
+ g_free (script);
+}
+
+gboolean
+e_web_view_jsc_get_document_content_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error)
+{
+ g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (out_texts != NULL, FALSE);
+
+ return ewv_jsc_get_content_finish (web_view, result, out_texts, error);
+}
+
+void
+e_web_view_jsc_get_element_content (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ ETextFormat format,
+ gboolean use_outer_html,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id != NULL);
+
+ script = e_web_view_jsc_printf_script ("Evo.GetElementContent(%s,%s,%d,%x)", iframe_id, element_id,
format, use_outer_html);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, callback, user_data);
+
+ g_free (script);
+}
+
+gboolean
+e_web_view_jsc_get_element_content_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error)
+{
+ g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (out_texts != NULL, FALSE);
+
+ return ewv_jsc_get_content_finish (web_view, result, out_texts, error);
+}
+
+void
+e_web_view_jsc_get_element_from_point (WebKitWebView *web_view,
+ gint xx,
+ gint yy,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar *script;
+
+ g_return_if_fail (WEBKIT_IS_WEB_VIEW (web_view));
+
+ script = e_web_view_jsc_printf_script ("Evo.GetElementFromPoint(%d,%d)", xx, yy);
+
+ webkit_web_view_run_javascript (web_view, script, cancellable, callback, user_data);
+
+ g_free (script);
+}
+
+/* Can return TRUE, but set all out parameters to NULL */
+gboolean
+e_web_view_jsc_get_element_from_point_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ gchar **out_iframe_src,
+ gchar **out_iframe_id,
+ gchar **out_element_id,
+ GError **error)
+{
+ WebKitJavascriptResult *js_result;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+
+ if (out_iframe_src)
+ *out_iframe_src = NULL;
+ if (out_iframe_id)
+ *out_iframe_id = NULL;
+ if (out_element_id)
+ *out_element_id = NULL;
+
+ js_result = webkit_web_view_run_javascript_finish (web_view, result, &local_error);
+
+ if (local_error) {
+ g_propagate_error (error, local_error);
+
+ if (js_result)
+ webkit_javascript_result_unref (js_result);
+
+ return FALSE;
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Call failed: %s",
jsc_exception_get_message (exception));
+ webkit_javascript_result_unref (js_result);
+ return FALSE;
+ }
+
+ if (jsc_value_is_object (value)) {
+ if (out_iframe_src)
+ *out_iframe_src = e_web_view_jsc_get_object_property_string (value,
"iframe-src", NULL);
+ if (out_iframe_id)
+ *out_iframe_id = e_web_view_jsc_get_object_property_string (value,
"iframe-id", NULL);
+ if (out_element_id)
+ *out_element_id = e_web_view_jsc_get_object_property_string (value,
"elem-id", NULL);
+ } else if (!jsc_value_is_null (value)) {
+ g_warn_if_reached ();
+ }
+
+ webkit_javascript_result_unref (js_result);
+ }
+
+ return TRUE;
+}
diff --git a/src/e-util/e-web-view-jsc-utils.h b/src/e-util/e-web-view-jsc-utils.h
new file mode 100644
index 0000000000..8968e0bfb7
--- /dev/null
+++ b/src/e-util/e-web-view-jsc-utils.h
@@ -0,0 +1,181 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2019 Red Hat (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_WEB_VIEW_JSC_UTILS_H
+#define E_WEB_VIEW_JSC_UTILS_H
+
+#include <webkit2/webkit2.h>
+
+G_BEGIN_DECLS
+
+gboolean e_web_view_jsc_get_object_property_boolean
+ (JSCValue *jsc_object,
+ const gchar *property_name,
+ gboolean default_value);
+gint32 e_web_view_jsc_get_object_property_int32
+ (JSCValue *jsc_object,
+ const gchar *property_name,
+ gint32 default_value);
+gdouble e_web_view_jsc_get_object_property_double
+ (JSCValue *jsc_object,
+ const gchar *property_name,
+ gdouble default_value);
+gchar * e_web_view_jsc_get_object_property_string
+ (JSCValue *jsc_object,
+ const gchar *property_name,
+ const gchar *default_value);
+
+gchar * e_web_view_jsc_printf_script (const gchar *script_format,
+ ...) G_GNUC_PRINTF (1, 2);
+gchar * e_web_view_jsc_vprintf_script (const gchar *script_format,
+ va_list va);
+void e_web_view_jsc_printf_script_gstring
+ (GString *script,
+ const gchar *script_format,
+ ...) G_GNUC_PRINTF (2, 3);
+void e_web_view_jsc_vprintf_script_gstring
+ (GString *script,
+ const gchar *script_format,
+ va_list va);
+void e_web_view_jsc_run_script (WebKitWebView *web_view,
+ GCancellable *cancellable,
+ const gchar *script_format,
+ ...) G_GNUC_PRINTF (3, 4);
+void e_web_view_jsc_run_script_take (WebKitWebView *web_view,
+ gchar *script,
+ GCancellable *cancellable);
+void e_web_view_jsc_set_element_hidden
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable);
+void e_web_view_jsc_set_element_disabled
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable);
+void e_web_view_jsc_set_element_checked
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean value,
+ GCancellable *cancellable);
+void e_web_view_jsc_set_element_style_property
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *property_name,
+ const gchar *value,
+ GCancellable *cancellable);
+void e_web_view_jsc_set_element_attribute
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *namespace_uri,
+ const gchar *qualified_name,
+ const gchar *value,
+ GCancellable *cancellable);
+void e_web_view_jsc_create_style_sheet
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *content,
+ GCancellable *cancellable);
+void e_web_view_jsc_remove_style_sheet
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ GCancellable *cancellable);
+void e_web_view_jsc_add_rule_into_style_sheet
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style,
+ GCancellable *cancellable);
+void e_web_view_jsc_register_element_clicked
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *elem_classes,
+ GCancellable *cancellable);
+
+typedef enum _ETextFormat {
+ E_TEXT_FORMAT_PLAIN = 1,
+ E_TEXT_FORMAT_HTML = 2,
+ E_TEXT_FORMAT_BOTH = 3
+} ETextFormat;
+
+void e_web_view_jsc_get_selection (WebKitWebView *web_view,
+ ETextFormat format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_web_view_jsc_get_selection_finish
+ (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error);
+void e_web_view_jsc_get_document_content
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ ETextFormat format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_web_view_jsc_get_document_content_finish
+ (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error);
+void e_web_view_jsc_get_element_content
+ (WebKitWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ ETextFormat format,
+ gboolean use_outer_html,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_web_view_jsc_get_element_content_finish
+ (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GSList **out_texts,
+ GError **error);
+void e_web_view_jsc_get_element_from_point
+ (WebKitWebView *web_view,
+ gint xx,
+ gint yy,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_web_view_jsc_get_element_from_point_finish
+ (WebKitWebView *web_view,
+ GAsyncResult *result,
+ gchar **out_iframe_src,
+ gchar **out_iframe_id,
+ gchar **out_element_id,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_WEB_VIEW_JSC_UTILS_H */
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index 5caa586a6c..411a566c2d 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -39,8 +39,7 @@
#include "e-selectable.h"
#include "e-stock-request.h"
#include "e-web-extension-container.h"
-
-#include "web-extensions/e-web-extension-names.h"
+#include "e-web-view-jsc-utils.h"
#include "e-web-view.h"
@@ -48,8 +47,6 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_WEB_VIEW, EWebViewPrivate))
-static void e_web_view_set_web_extension_proxy (EWebView *web_view, GDBusProxy *proxy);
-
typedef struct _AsyncContext AsyncContext;
typedef struct _ElementClickedData {
@@ -83,10 +80,6 @@ struct _EWebViewPrivate {
GHashTable *old_settings;
- EWebExtensionContainer *container;
- GDBusProxy *web_extension_proxy;
- gint stamp; /* Changed only in the main thread, doesn't need locking */
-
WebKitFindController *find_controller;
gulong found_text_handler_id;
gulong failed_to_find_text_handler_id;
@@ -96,15 +89,16 @@ struct _EWebViewPrivate {
GSList *content_requests; /* EContentRequest * */
GHashTable *element_clicked_cbs; /* gchar *element_class ~> GPtrArray {ElementClickedData} */
- guint web_extension_element_clicked_signal_id;
-
- guint32 clipboard_flags;
- guint web_extension_clipboard_flags_changed_signal_id;
+ gboolean has_selection;
gboolean need_input;
- guint web_extension_need_input_changed_signal_id;
- GCancellable *load_cancellable;
+ GCancellable *cancellable;
+
+ gchar *last_popup_iframe_src;
+ gchar *last_popup_iframe_id;
+ gchar *last_popup_element_id;
+ gchar *last_popup_link_uri;
};
struct _AsyncContext {
@@ -118,18 +112,17 @@ struct _AsyncContext {
enum {
PROP_0,
PROP_CARET_MODE,
- PROP_CLIPBOARD_FLAGS,
PROP_COPY_TARGET_LIST,
PROP_CURSOR_IMAGE_SRC,
PROP_DISABLE_PRINTING,
PROP_DISABLE_SAVE_TO_DISK,
+ PROP_HAS_SELECTION,
PROP_NEED_INPUT,
PROP_OPEN_PROXY,
PROP_PASTE_TARGET_LIST,
PROP_PRINT_PROXY,
PROP_SAVE_AS_PROXY,
- PROP_SELECTED_URI,
- PROP_WEB_EXTENSION_PROXY
+ PROP_SELECTED_URI
};
enum {
@@ -140,6 +133,8 @@ enum {
UPDATE_ACTIONS,
PROCESS_MAILTO,
URI_REQUESTED,
+ CONTENT_LOADED,
+ BEFORE_POPUP_EVENT,
LAST_SIGNAL
};
@@ -213,36 +208,24 @@ action_copy_clipboard_cb (GtkAction *action,
e_web_view_copy_clipboard (web_view);
}
-static gint
-e_web_view_assign_new_stamp (EWebView *web_view)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), 0);
-
- if (web_view->priv->stamp)
- e_web_extension_container_forget_stamp (web_view->priv->container, web_view->priv->stamp);
-
- web_view->priv->stamp = e_web_extension_container_reserve_stamp (web_view->priv->container);
-
- return web_view->priv->stamp;
-}
-
static void
e_web_view_search_web_get_selection_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- gchar *text;
+ GSList *texts;
GError *local_error = NULL;
g_return_if_fail (E_IS_WEB_VIEW (source));
- text = e_web_view_get_selection_content_text_finish (E_WEB_VIEW (source), result, &local_error);
+ e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source), result, &texts, &local_error);
if (local_error &&
!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
e_alert_submit (E_ALERT_SINK (source), "widgets:get-selected-text-failed",
local_error->message, NULL);
- } else if (!local_error) {
+ } else if (texts) {
GSettings *settings;
+ gchar *text = texts->data;
gchar *uri_prefix;
gchar *escaped;
gchar *uri;
@@ -272,14 +255,14 @@ e_web_view_search_web_get_selection_cb (GObject *source,
}
g_clear_error (&local_error);
- g_free (text);
+ g_slist_free_full (texts, g_free);
}
static void
action_search_web_cb (GtkAction *action,
EWebView *web_view)
{
- e_web_view_get_selection_content_text (web_view, web_view->priv->load_cancellable,
+ e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_PLAIN,
web_view->priv->cancellable,
e_web_view_search_web_get_selection_cb, NULL);
}
@@ -594,6 +577,46 @@ web_view_connect_proxy_cb (EWebView *web_view,
G_CALLBACK (web_view_menu_item_deselect_cb), web_view);
}
+static void
+web_view_got_elem_from_point_for_popup_event_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EWebView *web_view;
+ GdkEvent *event = user_data;
+ GError *error = NULL;
+
+ g_return_if_fail (E_IS_WEB_VIEW (source_object));
+
+ web_view = E_WEB_VIEW (source_object);
+
+ g_clear_pointer (&web_view->priv->last_popup_iframe_src, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_iframe_id, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_element_id, g_free);
+
+ if (!e_web_view_jsc_get_element_from_point_finish (WEBKIT_WEB_VIEW (web_view), result,
+ &web_view->priv->last_popup_iframe_src,
+ &web_view->priv->last_popup_iframe_id,
+ &web_view->priv->last_popup_element_id,
+ &error)) {
+ g_warning ("%s: Failed to get element from point: %s", G_STRFUNC, error ? error->message :
"Unknown error");
+ }
+
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ gboolean handled = FALSE;
+
+ g_signal_emit (web_view, signals[BEFORE_POPUP_EVENT], 0,
+ web_view->priv->last_popup_link_uri, NULL);
+
+ g_signal_emit (web_view, signals[POPUP_EVENT], 0,
+ web_view->priv->last_popup_link_uri, event, &handled);
+ }
+
+ if (event)
+ gdk_event_free (event);
+ g_clear_error (&error);
+}
+
static gboolean
web_view_context_menu_cb (WebKitWebView *webkit_web_view,
WebKitContextMenu *context_menu,
@@ -603,15 +626,18 @@ web_view_context_menu_cb (WebKitWebView *webkit_web_view,
{
WebKitHitTestResultContext context;
EWebView *web_view;
- gboolean event_handled = FALSE;
gchar *link_uri = NULL;
+ gdouble xx, yy;
web_view = E_WEB_VIEW (webkit_web_view);
- g_free (web_view->priv->cursor_image_src);
- web_view->priv->cursor_image_src = NULL;
+ g_clear_pointer (&web_view->priv->cursor_image_src, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_iframe_src, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_iframe_id, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_element_id, g_free);
+ g_clear_pointer (&web_view->priv->last_popup_link_uri, g_free);
- if (hit_test_result == NULL)
+ if (!hit_test_result)
return FALSE;
context = webkit_hit_test_result_get_context (hit_test_result);
@@ -621,23 +647,23 @@ web_view_context_menu_cb (WebKitWebView *webkit_web_view,
g_object_get (hit_test_result, "image-uri", &image_uri, NULL);
- if (image_uri != NULL) {
- g_free (web_view->priv->cursor_image_src);
- web_view->priv->cursor_image_src = image_uri;
- }
+ web_view->priv->cursor_image_src = image_uri;
}
if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
g_object_get (hit_test_result, "link-uri", &link_uri, NULL);
- g_signal_emit (
- web_view,
- signals[POPUP_EVENT], 0,
- link_uri, event, &event_handled);
+ web_view->priv->last_popup_link_uri = link_uri;
- g_free (link_uri);
+ if (!gdk_event_get_coords (event, &xx, &yy)) {
+ xx = 1;
+ yy = 1;
+ }
- return event_handled;
+ e_web_view_jsc_get_element_from_point (WEBKIT_WEB_VIEW (web_view), xx, yy,
web_view->priv->cancellable,
+ web_view_got_elem_from_point_for_popup_event_cb, event ? gdk_event_copy (event) : NULL);
+
+ return TRUE;
}
static void
@@ -747,27 +773,14 @@ web_view_decide_policy_cb (EWebView *web_view,
}
static void
-e_web_view_ensure_body_class (EWebView *web_view)
-{
- guint64 page_id;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "EWebViewEnsureBodyClass",
- g_variant_new ("(ts)", page_id, "-e-web-view-background-color -e-web-view-text-color"));
-}
-
-static void
-style_updated_cb (EWebView *web_view)
+e_web_view_update_styles (EWebView *web_view,
+ const gchar *iframe_id)
{
GdkRGBA color;
gchar *color_value;
gchar *style;
GtkStyleContext *style_context;
+ WebKitWebView *webkit_web_view;
style_context = gtk_widget_get_style_context (GTK_WIDGET (web_view));
@@ -785,13 +798,16 @@ style_updated_cb (EWebView *web_view)
style = g_strconcat ("background-color: ", color_value, ";", NULL);
- webkit_web_view_set_background_color (WEBKIT_WEB_VIEW (web_view), &color);
+ webkit_web_view = WEBKIT_WEB_VIEW (web_view);
+
+ webkit_web_view_set_background_color (webkit_web_view, &color);
- e_web_view_add_css_rule_into_style_sheet (
- web_view,
+ e_web_view_jsc_add_rule_into_style_sheet (webkit_web_view,
+ iframe_id,
"-e-web-view-style-sheet",
".-e-web-view-background-color",
- style);
+ style,
+ web_view->priv->cancellable);
g_free (color_value);
g_free (style);
@@ -803,16 +819,23 @@ style_updated_cb (EWebView *web_view)
style = g_strconcat ("color: ", color_value, ";", NULL);
- e_web_view_add_css_rule_into_style_sheet (
- web_view,
+ e_web_view_jsc_add_rule_into_style_sheet (webkit_web_view,
+ iframe_id,
"-e-web-view-style-sheet",
".-e-web-view-text-color",
- style);
+ style,
+ web_view->priv->cancellable);
g_free (color_value);
g_free (style);
}
+static void
+style_updated_cb (EWebView *web_view)
+{
+ e_web_view_update_styles (web_view, "*");
+}
+
static void
web_view_load_changed_cb (WebKitWebView *webkit_web_view,
WebKitLoadEvent load_event,
@@ -828,8 +851,11 @@ web_view_load_changed_cb (WebKitWebView *webkit_web_view,
if (load_event != WEBKIT_LOAD_FINISHED)
return;
- e_web_view_ensure_body_class (web_view);
- style_updated_cb (web_view);
+ /* Make sure the initialize function is called for the top document when it is loaded. */
+ e_web_view_jsc_run_script (webkit_web_view, web_view->priv->cancellable,
+ "Evo.EnsureMainDocumentInitialized();");
+
+ e_web_view_update_styles (web_view, "");
web_view_update_document_highlights (web_view);
}
@@ -906,12 +932,6 @@ web_view_set_property (GObject *object,
g_value_get_boolean (value));
return;
- case PROP_CLIPBOARD_FLAGS:
- e_web_view_set_clipboard_flags (
- E_WEB_VIEW (object),
- g_value_get_uint (value));
- return;
-
case PROP_COPY_TARGET_LIST:
/* This is a fake property. */
g_warning ("%s: EWebView::copy-target-list not used", G_STRFUNC);
@@ -935,12 +955,6 @@ web_view_set_property (GObject *object,
g_value_get_boolean (value));
return;
- case PROP_NEED_INPUT:
- e_web_view_set_need_input (
- E_WEB_VIEW (object),
- g_value_get_boolean (value));
- return;
-
case PROP_OPEN_PROXY:
e_web_view_set_open_proxy (
E_WEB_VIEW (object),
@@ -986,12 +1000,6 @@ web_view_get_property (GObject *object,
E_WEB_VIEW (object)));
return;
- case PROP_CLIPBOARD_FLAGS:
- g_value_set_uint (
- value, e_web_view_get_clipboard_flags (
- E_WEB_VIEW (object)));
- return;
-
case PROP_COPY_TARGET_LIST:
/* This is a fake property. */
g_value_set_boxed (value, NULL);
@@ -1015,6 +1023,10 @@ web_view_get_property (GObject *object,
E_WEB_VIEW (object)));
return;
+ case PROP_HAS_SELECTION:
+ g_value_set_boolean (value, e_web_view_has_selection (E_WEB_VIEW (object)));
+ return;
+
case PROP_NEED_INPUT:
g_value_set_boolean (
value, e_web_view_get_need_input (
@@ -1049,12 +1061,6 @@ web_view_get_property (GObject *object,
value, e_web_view_get_selected_uri (
E_WEB_VIEW (object)));
return;
-
- case PROP_WEB_EXTENSION_PROXY:
- g_value_set_object (
- value, e_web_view_get_web_extension_proxy (
- E_WEB_VIEW (object)));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1065,11 +1071,14 @@ web_view_dispose (GObject *object)
{
EWebViewPrivate *priv;
+ /* This can be called during dispose, thus disconnect early */
+ g_signal_handlers_disconnect_by_func (object, G_CALLBACK (style_updated_cb), NULL);
+
priv = E_WEB_VIEW_GET_PRIVATE (object);
- if (priv->load_cancellable) {
- g_cancellable_cancel (priv->load_cancellable);
- g_clear_object (&priv->load_cancellable);
+ if (priv->cancellable) {
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
}
if (priv->font_name_changed_handler_id > 0) {
@@ -1112,18 +1121,12 @@ web_view_dispose (GObject *object)
g_slist_free_full (priv->content_requests, g_object_unref);
priv->content_requests = NULL;
- e_web_view_set_web_extension_proxy (E_WEB_VIEW (object), NULL);
-
- if (priv->container && priv->stamp)
- e_web_extension_container_forget_stamp (priv->container, priv->stamp);
-
g_clear_object (&priv->ui_manager);
g_clear_object (&priv->open_proxy);
g_clear_object (&priv->print_proxy);
g_clear_object (&priv->save_as_proxy);
g_clear_object (&priv->aliasing_settings);
g_clear_object (&priv->font_settings);
- g_clear_object (&priv->container);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_web_view_parent_class)->dispose (object);
@@ -1136,6 +1139,10 @@ web_view_finalize (GObject *object)
priv = E_WEB_VIEW_GET_PRIVATE (object);
+ g_clear_pointer (&priv->last_popup_iframe_src, g_free);
+ g_clear_pointer (&priv->last_popup_iframe_id, g_free);
+ g_clear_pointer (&priv->last_popup_element_id, g_free);
+ g_clear_pointer (&priv->last_popup_link_uri, g_free);
g_free (priv->selected_uri);
g_free (priv->cursor_image_src);
@@ -1153,7 +1160,6 @@ web_view_finalize (GObject *object)
G_OBJECT_CLASS (e_web_view_parent_class)->finalize (object);
}
-
static void
web_view_uri_request_done_cb (GObject *source_object,
GAsyncResult *result,
@@ -1234,7 +1240,7 @@ web_view_process_uri_request_cb (WebKitURISchemeRequest *request,
web_view = E_WEB_VIEW (requester);
}
- e_content_request_process (content_request, uri, requester, web_view ?
web_view->priv->load_cancellable : NULL,
+ e_content_request_process (content_request, uri, requester, web_view ? web_view->priv->cancellable :
NULL,
web_view_uri_request_done_cb, g_object_ref (request));
g_free (redirect_to_uri);
@@ -1308,19 +1314,184 @@ e_web_view_initialize_web_extensions_cb (WebKitWebContext *web_context,
EWebView *web_view = user_data;
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- g_return_if_fail (web_view->priv->container);
webkit_web_context_set_web_extensions_directory (web_context, EVOLUTION_WEB_EXTENSIONS_DIR);
- webkit_web_context_set_web_extensions_initialization_user_data (web_context,
- g_variant_new ("(ss)",
- e_web_extension_container_get_server_guid (web_view->priv->container),
- e_web_extension_container_get_server_address (web_view->priv->container)));
+}
+
+static void
+e_web_view_element_clicked_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ EWebView *web_view = user_data;
+ GtkAllocation elem_position;
+ GPtrArray *listeners;
+ JSCValue *jsc_object;
+ gchar *iframe_id, *elem_id, *elem_class, *elem_value;
+
+ g_return_if_fail (web_view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_object = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_object (jsc_object));
+
+ iframe_id = e_web_view_jsc_get_object_property_string (jsc_object, "iframe-id", NULL);
+ elem_id = e_web_view_jsc_get_object_property_string (jsc_object, "elem-id", NULL);
+ elem_class = e_web_view_jsc_get_object_property_string (jsc_object, "elem-class", NULL);
+ elem_value = e_web_view_jsc_get_object_property_string (jsc_object, "elem-value", NULL);
+ elem_position.x = e_web_view_jsc_get_object_property_int32 (jsc_object, "left", 0);
+ elem_position.y = e_web_view_jsc_get_object_property_int32 (jsc_object, "top", 0);
+ elem_position.width = e_web_view_jsc_get_object_property_int32 (jsc_object, "width", 0);
+ elem_position.height = e_web_view_jsc_get_object_property_int32 (jsc_object, "height", 0);
+
+ listeners = g_hash_table_lookup (web_view->priv->element_clicked_cbs, elem_class);
+
+ if (listeners) {
+ guint ii;
+
+ for (ii = 0; ii < listeners->len; ii++) {
+ ElementClickedData *ecd = g_ptr_array_index (listeners, ii);
+
+ if (ecd && ecd->callback)
+ ecd->callback (web_view, iframe_id, elem_id, elem_class, elem_value,
&elem_position, ecd->user_data);
+ }
+ }
+
+ g_free (iframe_id);
+ g_free (elem_id);
+ g_free (elem_class);
+ g_free (elem_value);
+}
+
+static void
+web_view_call_register_element_clicked (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *only_elem_class)
+{
+ gchar *elem_classes = NULL;
+
+ if (!only_elem_class) {
+ GHashTableIter iter;
+ gpointer key;
+ GString *classes;
+
+ classes = g_string_sized_new (128);
+
+ g_hash_table_iter_init (&iter, web_view->priv->element_clicked_cbs);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ if (classes->len)
+ g_string_append_c (classes, '\n');
+
+ g_string_append (classes, key);
+ }
+
+ elem_classes = g_string_free (classes, FALSE);
+ }
+
+ e_web_view_jsc_register_element_clicked (WEBKIT_WEB_VIEW (web_view), iframe_id,
+ only_elem_class ? only_elem_class : elem_classes,
+ web_view->priv->cancellable);
+
+ g_free (elem_classes);
+}
+
+static void
+e_web_view_content_loaded_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ EWebView *web_view = user_data;
+ JSCValue *jsc_value;
+ gchar *iframe_id;
+
+ g_return_if_fail (web_view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_string (jsc_value));
+
+ iframe_id = jsc_value_to_string (jsc_value);
+
+ if (!iframe_id || !*iframe_id)
+ e_web_view_update_fonts (web_view);
+ else
+ e_web_view_update_styles (web_view, iframe_id);
+
+ web_view_call_register_element_clicked (web_view, iframe_id, NULL);
+
+ g_signal_emit (web_view, signals[CONTENT_LOADED], 0, iframe_id);
+
+ g_free (iframe_id);
+}
+
+static void
+e_web_view_set_has_selection (EWebView *web_view,
+ gboolean has_selection)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if ((!web_view->priv->has_selection) == (!has_selection))
+ return;
+
+ web_view->priv->has_selection = has_selection;
+
+ g_object_notify (G_OBJECT (web_view), "has-selection");
+}
+
+
+static void
+e_web_view_has_selection_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ EWebView *web_view = user_data;
+ JSCValue *jsc_value;
+
+ g_return_if_fail (web_view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_boolean (jsc_value));
+
+ e_web_view_set_has_selection (web_view, jsc_value_to_boolean (jsc_value));
+}
+
+static void
+e_web_view_set_need_input (EWebView *web_view,
+ gboolean need_input)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if ((!web_view->priv->need_input) == (!need_input))
+ return;
+
+ web_view->priv->need_input = need_input;
+
+ g_object_notify (G_OBJECT (web_view), "need-input");
+}
+
+static void
+e_web_view_need_input_changed_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ EWebView *web_view = user_data;
+ JSCValue *jsc_value;
+
+ g_return_if_fail (web_view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_boolean (jsc_value));
+
+ e_web_view_set_need_input (web_view, jsc_value_to_boolean (jsc_value));
}
static void
web_view_constructed (GObject *object)
{
WebKitSettings *web_settings;
+ WebKitUserContentManager *manager;
EWebView *web_view = E_WEB_VIEW (object);
#ifndef G_OS_WIN32
GSettings *settings;
@@ -1364,6 +1535,25 @@ web_view_constructed (GObject *object)
web_view_initialize (WEBKIT_WEB_VIEW (object));
web_view_set_find_controller (web_view);
+
+ manager = webkit_web_view_get_user_content_manager (WEBKIT_WEB_VIEW (object));
+
+ g_signal_connect_object (manager, "script-message-received::elementClicked",
+ G_CALLBACK (e_web_view_element_clicked_cb), web_view, 0);
+
+ g_signal_connect_object (manager, "script-message-received::contentLoaded",
+ G_CALLBACK (e_web_view_content_loaded_cb), web_view, 0);
+
+ g_signal_connect_object (manager, "script-message-received::hasSelection",
+ G_CALLBACK (e_web_view_has_selection_cb), web_view, 0);
+
+ g_signal_connect_object (manager, "script-message-received::needInputChanged",
+ G_CALLBACK (e_web_view_need_input_changed_cb), web_view, 0);
+
+ webkit_user_content_manager_register_script_message_handler (manager, "contentLoaded");
+ webkit_user_content_manager_register_script_message_handler (manager, "elementClicked");
+ webkit_user_content_manager_register_script_message_handler (manager, "hasSelection");
+ webkit_user_content_manager_register_script_message_handler (manager, "needInputChanged");
}
static void
@@ -1372,13 +1562,13 @@ e_web_view_replace_load_cancellable (EWebView *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- if (web_view->priv->load_cancellable) {
- g_cancellable_cancel (web_view->priv->load_cancellable);
- g_clear_object (&web_view->priv->load_cancellable);
+ if (web_view->priv->cancellable) {
+ g_cancellable_cancel (web_view->priv->cancellable);
+ g_clear_object (&web_view->priv->cancellable);
}
if (create_new)
- web_view->priv->load_cancellable = g_cancellable_new ();
+ web_view->priv->cancellable = g_cancellable_new ();
}
static gboolean
@@ -1549,40 +1739,25 @@ static void
web_view_load_string (EWebView *web_view,
const gchar *string)
{
- gchar *uri_with_stamp;
-
- uri_with_stamp = g_strdup_printf ("evo-file:///?evo-stamp=%d", e_web_view_assign_new_stamp
(web_view));
-
if (!string || !*string) {
- webkit_web_view_load_html (WEBKIT_WEB_VIEW (web_view), "", uri_with_stamp);
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (web_view), "", "evo-file:///");
} else {
GBytes *bytes;
bytes = g_bytes_new (string, strlen (string));
- webkit_web_view_load_bytes (WEBKIT_WEB_VIEW (web_view), bytes, NULL, NULL, uri_with_stamp);
+ webkit_web_view_load_bytes (WEBKIT_WEB_VIEW (web_view), bytes, NULL, NULL, "evo-file:///");
g_bytes_unref (bytes);
}
-
- g_free (uri_with_stamp);
}
static void
web_view_load_uri (EWebView *web_view,
const gchar *uri)
{
- gchar *uri_with_stamp;
-
- if (uri == NULL)
+ if (!uri)
uri = "about:blank";
- if (strchr (uri, '?'))
- uri_with_stamp = g_strdup_printf ("%s&evo-stamp=%d", uri, e_web_view_assign_new_stamp
(web_view));
- else
- uri_with_stamp = g_strdup_printf ("%s?evo-stamp=%d", uri, e_web_view_assign_new_stamp
(web_view));
-
- webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri_with_stamp);
-
- g_free (uri_with_stamp);
+ webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri);
}
static gchar *
@@ -1604,6 +1779,14 @@ web_view_suggest_filename (EWebView *web_view,
return g_strdup (cp);
}
+static void
+web_view_before_popup_event (EWebView *web_view,
+ const gchar *uri)
+{
+ e_web_view_set_selected_uri (web_view, uri);
+ e_web_view_update_actions (web_view);
+}
+
static gboolean
web_view_popup_event (EWebView *web_view,
const gchar *uri,
@@ -1622,243 +1805,6 @@ web_view_stop_loading (EWebView *web_view)
webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
}
-static void
-web_view_register_element_clicked_hfunc (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- const gchar *elem_class = key;
- EWebView *web_view = user_data;
- guint64 page_id;
-
- g_return_if_fail (elem_class && *elem_class);
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "RegisterElementClicked",
- g_variant_new ("(ts)", page_id, elem_class));
-}
-
-static void
-web_view_need_input_changed_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- EWebView *web_view = user_data;
- guint64 page_id = 0;
- gboolean need_input = FALSE;
-
- if (g_strcmp0 (signal_name, "NeedInputChanged") != 0)
- return;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (!parameters)
- return;
-
- g_variant_get (parameters, "(tb)", &page_id, &need_input);
-
- if (page_id == webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)))
- e_web_view_set_need_input (web_view, need_input);
-}
-
-static void
-web_view_clipboard_flags_changed_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- EWebView *web_view = user_data;
- guint64 page_id = 0;
- guint32 clipboard_flags = 0;
-
- if (g_strcmp0 (signal_name, "ClipboardFlagsChanged") != 0)
- return;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (!parameters)
- return;
-
- g_variant_get (parameters, "(tu)", &page_id, &clipboard_flags);
-
- if (page_id == webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)))
- e_web_view_set_clipboard_flags (web_view, clipboard_flags);
-}
-
-static void
-web_view_element_clicked_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- EWebView *web_view = user_data;
- const gchar *elem_class = NULL, *elem_value = NULL;
- GtkAllocation elem_position;
- guint64 page_id = 0;
- gint position_left = 0, position_top = 0, position_width = 0, position_height = 0;
- GPtrArray *listeners;
-
- if (g_strcmp0 (signal_name, "ElementClicked") != 0)
- return;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (!parameters)
- return;
-
- g_variant_get (parameters, "(t&s&siiii)", &page_id, &elem_class, &elem_value, &position_left,
&position_top, &position_width, &position_height);
-
- if (!elem_class || !*elem_class || page_id != webkit_web_view_get_page_id (WEBKIT_WEB_VIEW
(web_view)))
- return;
-
- elem_position.x = position_left;
- elem_position.y = position_top;
- elem_position.width = position_width;
- elem_position.height = position_height;
-
- listeners = g_hash_table_lookup (web_view->priv->element_clicked_cbs, elem_class);
- if (listeners) {
- guint ii;
-
- for (ii = 0; ii <listeners->len; ii++) {
- ElementClickedData *ecd = g_ptr_array_index (listeners, ii);
-
- if (ecd && ecd->callback)
- ecd->callback (web_view, elem_class, elem_value, &elem_position,
ecd->user_data);
- }
- }
-}
-
-static void
-e_web_view_set_web_extension_proxy (EWebView *web_view,
- GDBusProxy *proxy)
-{
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (web_view->priv->web_extension_proxy == proxy)
- return;
-
- if (web_view->priv->web_extension_proxy) {
- GDBusConnection *connection;
-
- connection = g_dbus_proxy_get_connection (web_view->priv->web_extension_proxy);
-
- if (connection && g_dbus_connection_is_closed (connection))
- connection = NULL;
-
- if (web_view->priv->web_extension_clipboard_flags_changed_signal_id) {
- if (connection)
- g_dbus_connection_signal_unsubscribe (connection,
web_view->priv->web_extension_clipboard_flags_changed_signal_id);
- web_view->priv->web_extension_clipboard_flags_changed_signal_id = 0;
- }
-
- if (web_view->priv->web_extension_need_input_changed_signal_id) {
- if (connection)
- g_dbus_connection_signal_unsubscribe (connection,
web_view->priv->web_extension_need_input_changed_signal_id);
- web_view->priv->web_extension_need_input_changed_signal_id = 0;
- }
-
- if (web_view->priv->web_extension_element_clicked_signal_id) {
- if (connection)
- g_dbus_connection_signal_unsubscribe (connection,
web_view->priv->web_extension_element_clicked_signal_id);
- web_view->priv->web_extension_element_clicked_signal_id = 0;
- }
-
- g_clear_object (&web_view->priv->web_extension_proxy);
- }
-
- if (proxy) {
- web_view->priv->web_extension_proxy = g_object_ref (proxy);
-
- web_view->priv->web_extension_clipboard_flags_changed_signal_id =
- g_dbus_connection_signal_subscribe (
- g_dbus_proxy_get_connection (proxy),
- g_dbus_proxy_get_name (proxy),
- E_WEB_EXTENSION_INTERFACE,
- "ClipboardFlagsChanged",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- web_view_clipboard_flags_changed_signal_cb,
- web_view,
- NULL);
-
- web_view->priv->web_extension_need_input_changed_signal_id =
- g_dbus_connection_signal_subscribe (
- g_dbus_proxy_get_connection (proxy),
- g_dbus_proxy_get_name (proxy),
- E_WEB_EXTENSION_INTERFACE,
- "NeedInputChanged",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- web_view_need_input_changed_signal_cb,
- web_view,
- NULL);
-
- web_view->priv->web_extension_element_clicked_signal_id =
- g_dbus_connection_signal_subscribe (
- g_dbus_proxy_get_connection (proxy),
- g_dbus_proxy_get_name (proxy),
- E_WEB_EXTENSION_INTERFACE,
- "ElementClicked",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- web_view_element_clicked_signal_cb,
- web_view,
- NULL);
- }
-
- g_object_notify (G_OBJECT (web_view), "web-extension-proxy");
-}
-
-static void
-e_web_view_page_proxy_changed_cb (EWebExtensionContainer *container,
- guint64 page_id,
- gint stamp,
- GDBusProxy *proxy,
- gpointer user_data)
-{
- EWebView *web_view = user_data;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (stamp == web_view->priv->stamp &&
- page_id == webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view))) {
- e_web_view_set_web_extension_proxy (web_view, proxy);
-
- if (proxy) {
- g_hash_table_foreach (web_view->priv->element_clicked_cbs,
web_view_register_element_clicked_hfunc, web_view);
-
- e_web_view_ensure_body_class (web_view);
- style_updated_cb (web_view);
- }
- }
-}
-
-GDBusProxy *
-e_web_view_get_web_extension_proxy (EWebView *web_view)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
-
- return web_view->priv->web_extension_proxy;
-}
-
static void
web_view_update_actions (EWebView *web_view)
{
@@ -1875,7 +1821,7 @@ web_view_update_actions (EWebView *web_view)
g_return_if_fail (E_IS_WEB_VIEW (web_view));
uri = e_web_view_get_selected_uri (web_view);
- can_copy = (e_web_view_get_clipboard_flags (web_view) & E_CLIPBOARD_CAN_COPY) != 0;
+ can_copy = e_web_view_has_selection (web_view);
cursor_image_src = e_web_view_get_cursor_image_src (web_view);
/* Parse the URI early so we know if the actions will work. */
@@ -2088,7 +2034,7 @@ web_view_selectable_update_actions (ESelectable *selectable,
web_view = E_WEB_VIEW (selectable);
- can_copy = (e_web_view_get_clipboard_flags (web_view) & E_CLIPBOARD_CAN_COPY) != 0;
+ can_copy = e_web_view_has_selection (web_view);
action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
gtk_action_set_sensitive (action, can_copy);
@@ -2243,6 +2189,7 @@ e_web_view_class_init (EWebViewClass *class)
class->load_string = web_view_load_string;
class->load_uri = web_view_load_uri;
class->suggest_filename = web_view_suggest_filename;
+ class->before_popup_event = web_view_before_popup_event;
class->popup_event = web_view_popup_event;
class->stop_loading = web_view_stop_loading;
class->update_actions = web_view_update_actions;
@@ -2257,17 +2204,6 @@ e_web_view_class_init (EWebViewClass *class)
FALSE,
G_PARAM_READWRITE));
- g_object_class_install_property (
- object_class,
- PROP_CLIPBOARD_FLAGS,
- g_param_spec_uint (
- "clipboard-flags",
- "Clipboard Flags",
- NULL,
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
/* Inherited from ESelectableInterface; just a fake property here */
g_object_class_override_property (
object_class,
@@ -2312,6 +2248,16 @@ e_web_view_class_init (EWebViewClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_SELECTION,
+ g_param_spec_boolean (
+ "has-selection",
+ "Has Selection",
+ NULL,
+ FALSE,
+ G_PARAM_READABLE));
+
g_object_class_install_property (
object_class,
PROP_NEED_INPUT,
@@ -2319,9 +2265,8 @@ e_web_view_class_init (EWebViewClass *class)
"need-input",
"Need Input",
NULL,
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
+ FALSE,
+ G_PARAM_READABLE));
g_object_class_install_property (
object_class,
@@ -2363,16 +2308,6 @@ e_web_view_class_init (EWebViewClass *class)
NULL,
G_PARAM_READWRITE));
- g_object_class_install_property (
- object_class,
- PROP_WEB_EXTENSION_PROXY,
- g_param_spec_object (
- "web-extension-proxy",
- "Web Extension Proxy",
- NULL,
- G_TYPE_DBUS_PROXY,
- G_PARAM_READABLE));
-
signals[NEW_ACTIVITY] = g_signal_new (
"new-activity",
G_TYPE_FROM_CLASS (class),
@@ -2392,6 +2327,15 @@ e_web_view_class_init (EWebViewClass *class)
NULL,
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+ signals[BEFORE_POPUP_EVENT] = g_signal_new (
+ "before-popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, before_popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
signals[STATUS_MESSAGE] = g_signal_new (
"status-message",
G_TYPE_FROM_CLASS (class),
@@ -2440,6 +2384,14 @@ e_web_view_class_init (EWebViewClass *class)
G_STRUCT_OFFSET (EWebViewClass, uri_requested),
NULL, NULL, NULL,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
+
+ signals[CONTENT_LOADED] = g_signal_new (
+ "content-loaded",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EWebViewClass, content_loaded),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
@@ -2473,12 +2425,8 @@ e_web_view_init (EWebView *web_view)
web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view);
- web_view->priv->container = e_web_extension_container_new (E_WEB_EXTENSION_OBJECT_PATH,
E_WEB_EXTENSION_INTERFACE);
web_view->priv->old_settings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_variant_unref);
- g_signal_connect_object (web_view->priv->container, "page-proxy-changed",
- G_CALLBACK (e_web_view_page_proxy_changed_cb), web_view, 0);
-
g_signal_connect (
web_view, "context-menu",
G_CALLBACK (web_view_context_menu_cb), NULL);
@@ -2647,7 +2595,7 @@ e_web_view_init (EWebView *web_view)
web_view->priv->element_clicked_cbs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_ptr_array_unref);
- web_view->priv->load_cancellable = NULL;
+ web_view->priv->cancellable = NULL;
}
GtkWidget *
@@ -2758,117 +2706,6 @@ e_web_view_reload (EWebView *web_view)
webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
}
-static void
-get_document_content_html_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task = user_data;
- GVariant *result_variant;
- gchar *html_content = NULL;
- GError *error = NULL;
-
- g_return_if_fail (G_IS_DBUS_PROXY (source_object));
- g_return_if_fail (G_IS_TASK (task));
-
- web_extension = G_DBUS_PROXY (source_object);
-
- result_variant = g_dbus_proxy_call_finish (web_extension, result, &error);
- if (result_variant)
- g_variant_get (result_variant, "(s)", &html_content);
- g_variant_unref (result_variant);
-
- g_task_return_pointer (task, html_content, g_free);
- g_object_unref (task);
-
- if (error)
- g_dbus_error_strip_remote_error (error);
-
- e_util_claim_dbus_proxy_call_error (web_extension, "GetDocumentContentHTML", error);
- g_clear_error (&error);
-}
-
-void
-e_web_view_get_content_html (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- task = g_task_new (web_view, cancellable, callback, user_data);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- g_dbus_proxy_call (
- web_extension,
- "GetDocumentContentHTML",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- get_document_content_html_cb,
- g_object_ref (task));
- } else
- g_task_return_pointer (task, NULL, NULL);
-}
-
-gchar *
-e_web_view_get_content_html_finish (EWebView *web_view,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
- g_return_val_if_fail (g_task_is_valid (result, web_view), FALSE);
-
- return g_task_propagate_pointer (G_TASK (result), error);
-}
-
-gchar *
-e_web_view_get_content_html_sync (EWebView *web_view,
- GCancellable *cancellable,
- GError **error)
-{
- GDBusProxy *web_extension;
-
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetDocumentContentHTML",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
-
- if (result) {
- gchar *html_content = NULL;
-
- g_variant_get (result, "(s)", &html_content);
- g_variant_unref (result);
-
- return html_content;
- }
- }
-
- return NULL;
-}
-
gboolean
e_web_view_get_caret_mode (EWebView *web_view)
{
@@ -2963,28 +2800,6 @@ e_web_view_set_editable (EWebView *web_view,
webkit_web_view_set_editable (WEBKIT_WEB_VIEW (web_view), editable);
}
-guint32
-e_web_view_get_clipboard_flags (EWebView *web_view)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), 0);
-
- return web_view->priv->clipboard_flags;
-}
-
-void
-e_web_view_set_clipboard_flags (EWebView *web_view,
- guint32 clipboard_flags)
-{
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if (web_view->priv->clipboard_flags == clipboard_flags)
- return;
-
- web_view->priv->clipboard_flags = clipboard_flags;
-
- g_object_notify (G_OBJECT (web_view), "clipboard-flags");
-}
-
gboolean
e_web_view_get_need_input (EWebView *web_view)
{
@@ -2993,20 +2808,6 @@ e_web_view_get_need_input (EWebView *web_view)
return web_view->priv->need_input;
}
-void
-e_web_view_set_need_input (EWebView *web_view,
- gboolean need_input)
-{
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- if ((!web_view->priv->need_input) == (!need_input))
- return;
-
- web_view->priv->need_input = need_input;
-
- g_object_notify (G_OBJECT (web_view), "need-input");
-}
-
const gchar *
e_web_view_get_selected_uri (EWebView *web_view)
{
@@ -3154,6 +2955,28 @@ e_web_view_set_save_as_proxy (EWebView *web_view,
g_object_notify (G_OBJECT (web_view), "save-as-proxy");
}
+void
+e_web_view_get_last_popup_place (EWebView *web_view,
+ gchar **out_iframe_src,
+ gchar **out_iframe_id,
+ gchar **out_element_id,
+ gchar **out_link_uri)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if (out_iframe_src)
+ *out_iframe_src = g_strdup (web_view->priv->last_popup_iframe_src);
+
+ if (out_iframe_id)
+ *out_iframe_id = g_strdup (web_view->priv->last_popup_iframe_id);
+
+ if (out_element_id)
+ *out_element_id = g_strdup (web_view->priv->last_popup_element_id);
+
+ if (out_link_uri)
+ *out_link_uri = g_strdup (web_view->priv->last_popup_link_uri);
+}
+
void
e_web_view_add_highlight (EWebView *web_view,
const gchar *highlight)
@@ -3238,35 +3061,11 @@ e_web_view_cut_clipboard (EWebView *web_view)
}
gboolean
-e_web_view_is_selection_active (EWebView *web_view)
+e_web_view_has_selection (EWebView *web_view)
{
- GDBusProxy *web_extension;
-
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- web_extension,
- "DocumentHasSelection",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- NULL);
-
- if (result) {
- gboolean value = FALSE;
-
- g_variant_get (result, "(b)", &value);
- g_variant_unref (result);
- return value;
- }
- }
-
- return FALSE;
+ return web_view->priv->has_selection;
}
void
@@ -3476,226 +3275,6 @@ e_web_view_update_actions (EWebView *web_view)
g_signal_emit (web_view, signals[UPDATE_ACTIONS], 0);
}
-static void
-get_selection_content_html_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task = user_data;
- GVariant *result_variant;
- gchar *html_content = NULL;
- GError *error = NULL;
-
- g_return_if_fail (G_IS_DBUS_PROXY (source_object));
- g_return_if_fail (G_IS_TASK (task));
-
- web_extension = G_DBUS_PROXY (source_object);
-
- result_variant = g_dbus_proxy_call_finish (web_extension, result, &error);
- if (result_variant)
- g_variant_get (result_variant, "(s)", &html_content);
- g_variant_unref (result_variant);
-
- g_task_return_pointer (task, html_content, g_free);
- g_object_unref (task);
-
- if (error)
- g_dbus_error_strip_remote_error (error);
-
- e_util_claim_dbus_proxy_call_error (web_extension, "GetSelectionContentHTML", error);
- g_clear_error (&error);
-}
-
-void
-e_web_view_get_selection_content_html (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- task = g_task_new (web_view, cancellable, callback, user_data);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- g_dbus_proxy_call (
- web_extension,
- "GetSelectionContentHTML",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- get_selection_content_html_cb,
- g_object_ref (task));
- } else
- g_task_return_pointer (task, NULL, NULL);
-}
-
-gchar *
-e_web_view_get_selection_content_html_finish (EWebView *web_view,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
- g_return_val_if_fail (g_task_is_valid (result, web_view), FALSE);
-
- return g_task_propagate_pointer (G_TASK (result), error);
-}
-
-gchar *
-e_web_view_get_selection_content_html_sync (EWebView *web_view,
- GCancellable *cancellable,
- GError **error)
-{
- GDBusProxy *web_extension;
-
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetSelectionContentHTML",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
-
- if (result) {
- gchar *html_content = NULL;
-
- g_variant_get (result, "(s)", &html_content);
- g_variant_unref (result);
- return html_content;
- }
- }
-
- return NULL;
-}
-
-static void
-get_selection_content_text_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task = user_data;
- GVariant *result_variant;
- gchar *text_content = NULL;
- GError *error = NULL;
-
- g_return_if_fail (G_IS_DBUS_PROXY (source_object));
- g_return_if_fail (G_IS_TASK (task));
-
- web_extension = G_DBUS_PROXY (source_object);
-
- result_variant = g_dbus_proxy_call_finish (web_extension, result, &error);
- if (result_variant)
- g_variant_get (result_variant, "(s)", &text_content);
- g_variant_unref (result_variant);
-
- g_task_return_pointer (task, text_content, g_free);
- g_object_unref (task);
-
- if (error)
- g_dbus_error_strip_remote_error (error);
-
- e_util_claim_dbus_proxy_call_error (web_extension, "GetSelectionContentText", error);
- g_clear_error (&error);
-}
-
-void
-e_web_view_get_selection_content_text (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- GTask *task;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- task = g_task_new (web_view, cancellable, callback, user_data);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- g_dbus_proxy_call (
- web_extension,
- "GetSelectionContentText",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- get_selection_content_text_cb,
- g_object_ref (task));
- } else
- g_task_return_pointer (task, NULL, NULL);
-}
-
-gchar *
-e_web_view_get_selection_content_text_finish (EWebView *web_view,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
- g_return_val_if_fail (g_task_is_valid (result, web_view), FALSE);
-
- return g_task_propagate_pointer (G_TASK (result), error);
-}
-
-gchar *
-e_web_view_get_selection_content_text_sync (EWebView *web_view,
- GCancellable *cancellable,
- GError **error)
-{
- GDBusProxy *web_extension;
-
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetSelectionContentText",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (web_view))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
-
- if (result) {
- gchar *text_content = NULL;
-
- g_variant_get (result, "(s)", &text_content);
- g_variant_unref (result);
- return text_content;
- }
- }
-
- return NULL;
-}
-
const gchar *
e_web_view_get_citation_color_for_level (gint level)
{
@@ -4013,6 +3592,8 @@ e_web_view_update_fonts_settings (GSettings *font_settings,
pango_font_description_free (ms);
if (clean_vw)
pango_font_description_free (vw);
+
+ e_web_view_update_styles (E_WEB_VIEW (view_widget), "*");
}
WebKitSettings *
@@ -4025,7 +3606,8 @@ e_web_view_get_default_webkit_settings (void)
"enable-dns-prefetching", FALSE,
"enable-html5-local-storage", FALSE,
"enable-java", FALSE,
- "enable-javascript", FALSE,
+ "enable-javascript", TRUE, /* Needed for JavaScriptCore API to work */
+ "enable-javascript-markup", FALSE, /* Discards user-provided javascript in HTML */
"enable-offline-web-application-cache", FALSE,
"enable-page-cache", FALSE,
"enable-plugins", FALSE,
@@ -4034,6 +3616,14 @@ e_web_view_get_default_webkit_settings (void)
NULL);
}
+GCancellable *
+e_web_view_get_cancellable (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ return web_view->priv->cancellable;
+}
+
void
e_web_view_update_fonts (EWebView *web_view)
{
@@ -4584,131 +4174,10 @@ e_web_view_request_finish (EWebView *web_view,
}
/**
- * e_web_view_create_and_add_css_style_sheet:
- * @web_view: an #EWebView
- * @style_sheet_id: CSS style sheet's id
- *
- * Creates new CSS style sheet with given @style_sheel_id and inserts
- * it into given @web_view document.
- **/
-void
-e_web_view_create_and_add_css_style_sheet (EWebView *web_view,
- const gchar *style_sheet_id)
-{
- guint64 page_id;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
- g_return_if_fail (style_sheet_id && *style_sheet_id);
-
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "CreateAndAddCSSStyleSheet",
- g_variant_new ("(ts)", page_id, style_sheet_id));
-}
-
-/**
- * e_web_view_add_css_rule_into_style_sheet:
- * @web_view: an #EWebView
- * @style_sheet_id: CSS style sheet's id
- * @selector: CSS selector
- * @style: style for given selector
- *
- * Insert new CSS rule (defined with @selector and @style) into CSS style sheet
- * with given @style_sheet_id. If style sheet doesn't exist, it's created.
- *
- * The rule is inserted to every DOM document that is in page. That means also
- * into DOM documents inside iframe elements.
- **/
-void
-e_web_view_add_css_rule_into_style_sheet (EWebView *web_view,
- const gchar *style_sheet_id,
- const gchar *selector,
- const gchar *style)
-{
- guint64 page_id;
-
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
- g_return_if_fail (style_sheet_id && *style_sheet_id);
- g_return_if_fail (selector && *selector);
- g_return_if_fail (style && *style);
-
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "AddCSSRuleIntoStyleSheet",
- g_variant_new ("(tsss)", page_id, style_sheet_id, selector, style));
-}
-
-/**
- * e_web_view_get_document_uri_from_point:
- * @web_view: an #EWebView
- * @x: x-coordinate
- * @y: y-coordinate
- *
- * Returns: A document URI which is under the @x, @y coordinates or %NULL,
- * if there is none. Free the returned pointer with g_free() when done with it.
- *
- * Since: 3.22
- **/
-gchar *
-e_web_view_get_document_uri_from_point (EWebView *web_view,
- gint32 x,
- gint32 y)
-{
- GDBusProxy *web_extension;
- GVariant *result;
- GError *local_error = NULL;
-
- g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (!web_extension)
- return NULL;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetDocumentURIFromPoint",
- g_variant_new (
- "(tii)",
- webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)),
- x,
- y),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &local_error);
-
- if (local_error)
- g_dbus_error_strip_remote_error (local_error);
-
- e_util_claim_dbus_proxy_call_error (web_extension, "GetDocumentURIFromPoint", local_error);
- g_clear_error (&local_error);
-
- if (result) {
- gchar *uri = NULL;
-
- g_variant_get (result, "(s)", &uri);
- g_variant_unref (result);
-
- if (g_strcmp0 (uri, "") == 0) {
- g_free (uri);
- uri = NULL;
- }
-
- return uri;
- }
-
- return NULL;
-}
-
-/**
- * e_web_view_set_document_iframe_src:
+ * e_web_view_set_iframe_src:
* @web_view: an #EWebView
* @document_uri: a document URI for whose IFrame change the source
- * @new_iframe_src: the source to change the IFrame to
+ * @src_uri: the source to change the IFrame to
*
* Change IFrame source for the given @document_uri IFrame
* to the @new_iframe_src.
@@ -4716,29 +4185,22 @@ e_web_view_get_document_uri_from_point (EWebView *web_view,
* Since: 3.22
**/
void
-e_web_view_set_document_iframe_src (EWebView *web_view,
- const gchar *document_uri,
- const gchar *new_iframe_src)
+e_web_view_set_iframe_src (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *src_uri)
{
- guint64 page_id;
-
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- /* Cannot call this synchronously, blocking the local main loop, because the reload
- can on the WebProcess side can be asking for a redirection policy, waiting
- for a response which may be waiting in the blocked main loop. */
-
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "SetDocumentIFrameSrc",
- g_variant_new ("(tss)", page_id, document_uri, new_iframe_src));
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), web_view->priv->cancellable,
+ "Evo.SetIFrameSrc(%s, %s);",
+ iframe_id, src_uri);
}
/**
* EWebViewElementClickedFunc:
* @web_view: an #EWebView
+ * @iframe_id: an iframe ID in which the click happened; empty string for the main frame
+ * @element_id: an element ID
* @element_class: an element class, as set on the element which had been clicked
* @element_value: a 'value' attribute content of the clicked element
* @element_position: a #GtkAllocation with the position of the clicked element
@@ -4790,7 +4252,7 @@ e_web_view_register_element_clicked (EWebView *web_view,
if (ecd && ecd->callback == callback && ecd->user_data == user_data) {
/* Callback is already registered, but re-register it, in case the page
was changed dynamically and new elements with the given call are added. */
- web_view_register_element_clicked_hfunc ((gpointer) element_class, cbs,
web_view);
+ web_view_call_register_element_clicked (web_view, "*", element_class);
return;
}
}
@@ -4810,7 +4272,7 @@ e_web_view_register_element_clicked (EWebView *web_view,
}
/* Dynamically changing page can call this multiple times; re-register all classes */
- g_hash_table_foreach (web_view->priv->element_clicked_cbs, web_view_register_element_clicked_hfunc,
web_view);
+ web_view_call_register_element_clicked (web_view, "*", NULL);
}
/**
@@ -4862,38 +4324,27 @@ e_web_view_set_element_hidden (EWebView *web_view,
const gchar *element_id,
gboolean hidden)
{
- guint64 page_id;
-
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (element_id && *element_id);
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "SetElementHidden",
- g_variant_new ("(tsb)", page_id, element_id, hidden));
+ e_web_view_jsc_set_element_hidden (WEBKIT_WEB_VIEW (web_view),
+ "*", element_id, hidden,
+ web_view->priv->cancellable);
}
void
e_web_view_set_element_style_property (EWebView *web_view,
const gchar *element_id,
const gchar *property_name,
- const gchar *value,
- const gchar *priority)
+ const gchar *value)
{
- guint64 page_id;
-
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (element_id && *element_id);
g_return_if_fail (property_name && *property_name);
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "SetElementStyleProperty",
- g_variant_new ("(tssss)", page_id, element_id, property_name, value ? value : "", priority ?
priority : ""));
+ e_web_view_jsc_set_element_style_property (WEBKIT_WEB_VIEW (web_view),
+ "*", element_id, property_name, value,
+ web_view->priv->cancellable);
}
void
@@ -4903,16 +4354,11 @@ e_web_view_set_element_attribute (EWebView *web_view,
const gchar *qualified_name,
const gchar *value)
{
- guint64 page_id;
-
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (element_id && *element_id);
g_return_if_fail (qualified_name && *qualified_name);
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
-
- e_web_extension_container_call_simple (web_view->priv->container,
- page_id, web_view->priv->stamp,
- "SetElementAttribute",
- g_variant_new ("(tssss)", page_id, element_id, namespace_uri ? namespace_uri : "",
qualified_name, value ? value : ""));
+ e_web_view_jsc_set_element_attribute (WEBKIT_WEB_VIEW (web_view),
+ "*", element_id, namespace_uri, qualified_name, value,
+ web_view->priv->cancellable);
}
diff --git a/src/e-util/e-web-view.h b/src/e-util/e-web-view.h
index 474140dfb6..8f403df411 100644
--- a/src/e-util/e-web-view.h
+++ b/src/e-util/e-web-view.h
@@ -67,6 +67,8 @@ typedef enum {
} EURIScheme;
typedef void (*EWebViewElementClickedFunc) (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
const gchar *element_class,
const gchar *element_value,
const GtkAllocation *element_position,
@@ -111,6 +113,13 @@ struct _EWebViewClass {
void (*uri_requested) (EWebView *web_view,
const gchar *uri,
gchar **redirect_to_uri);
+ void (*content_loaded) (EWebView *web_view,
+ const gchar *frame_id);
+ void (*before_popup_event) (EWebView *web_view,
+ const gchar *uri);
+
+ /* Padding for future expansion */
+ gpointer reserved[15];
};
GType e_web_view_get_type (void) G_GNUC_CONST;
@@ -118,6 +127,7 @@ GtkWidget * e_web_view_new (void);
WebKitSettings *
e_web_view_get_default_webkit_settings
(void);
+GCancellable * e_web_view_get_cancellable (EWebView *web_view);
void e_web_view_register_content_request_for_scheme
(EWebView *web_view,
const gchar *scheme,
@@ -136,20 +146,6 @@ void e_web_view_load_uri (EWebView *web_view,
gchar * e_web_view_suggest_filename (EWebView *web_view,
const gchar *uri);
void e_web_view_reload (EWebView *web_view);
-void e_web_view_get_content_html (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gchar * e_web_view_get_content_html_finish
- (EWebView *web_view,
- GAsyncResult *result,
- GError **error);
-gchar * e_web_view_get_content_html_sync
- (EWebView *web_view,
- GCancellable *cancellable,
- GError **error);
-GDBusProxy * e_web_view_get_web_extension_proxy
- (EWebView *web_view);
gboolean e_web_view_get_caret_mode (EWebView *web_view);
void e_web_view_set_caret_mode (EWebView *web_view,
gboolean caret_mode);
@@ -165,12 +161,7 @@ void e_web_view_set_disable_save_to_disk
gboolean e_web_view_get_editable (EWebView *web_view);
void e_web_view_set_editable (EWebView *web_view,
gboolean editable);
-guint32 e_web_view_get_clipboard_flags (EWebView *web_view);
-void e_web_view_set_clipboard_flags (EWebView *web_view,
- guint32 clipboard_flags);
gboolean e_web_view_get_need_input (EWebView *web_view);
-void e_web_view_set_need_input (EWebView *web_view,
- gboolean need_input);
gboolean e_web_view_get_inline_spelling (EWebView *web_view);
void e_web_view_set_inline_spelling (EWebView *web_view,
gboolean inline_spelling);
@@ -197,6 +188,11 @@ void e_web_view_set_print_proxy (EWebView *web_view,
GtkAction * e_web_view_get_save_as_proxy (EWebView *web_view);
void e_web_view_set_save_as_proxy (EWebView *web_view,
GtkAction *save_as_proxy);
+void e_web_view_get_last_popup_place (EWebView *web_view,
+ gchar **out_iframe_src,
+ gchar **out_iframe_id,
+ gchar **out_element_id,
+ gchar **out_link_uri);
void e_web_view_add_highlight (EWebView *web_view,
const gchar *highlight);
void e_web_view_clear_highlights (EWebView *web_view);
@@ -207,7 +203,7 @@ GtkActionGroup *e_web_view_get_action_group (EWebView *web_view,
const gchar *group_name);
void e_web_view_copy_clipboard (EWebView *web_view);
void e_web_view_cut_clipboard (EWebView *web_view);
-gboolean e_web_view_is_selection_active (EWebView *web_view);
+gboolean e_web_view_has_selection (EWebView *web_view);
void e_web_view_paste_clipboard (EWebView *web_view);
gboolean e_web_view_scroll_forward (EWebView *web_view);
gboolean e_web_view_scroll_backward (EWebView *web_view);
@@ -225,32 +221,6 @@ void e_web_view_status_message (EWebView *web_view,
const gchar *status_message);
void e_web_view_stop_loading (EWebView *web_view);
void e_web_view_update_actions (EWebView *web_view);
-void e_web_view_get_selection_content_html
- (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gchar * e_web_view_get_selection_content_html_finish
- (EWebView *web_view,
- GAsyncResult *result,
- GError **error);
-gchar * e_web_view_get_selection_content_html_sync
- (EWebView *web_view,
- GCancellable *cancellable,
- GError **error);
-void e_web_view_get_selection_content_text
- (EWebView *web_view,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gchar * e_web_view_get_selection_content_text_finish
- (EWebView *web_view,
- GAsyncResult *result,
- GError **error);
-gchar * e_web_view_get_selection_content_text_sync
- (EWebView *web_view,
- GCancellable *cancellable,
- GError **error);
void e_web_view_update_fonts (EWebView *web_view);
void e_web_view_cursor_image_copy (EWebView *web_view);
void e_web_view_cursor_image_save (EWebView *web_view);
@@ -265,24 +235,11 @@ GInputStream * e_web_view_request_finish (EWebView *web_view,
void e_web_view_install_request_handler
(EWebView *web_view,
GType handler_type);
-void e_web_view_create_and_add_css_style_sheet
- (EWebView *web_view,
- const gchar *style_sheet_id);
-void e_web_view_add_css_rule_into_style_sheet
- (EWebView *web_view,
- const gchar *style_sheet_id,
- const gchar *selector,
- const gchar *style);
const gchar * e_web_view_get_citation_color_for_level
(gint level);
-gchar * e_web_view_get_document_uri_from_point
- (EWebView *web_view,
- gint32 x,
- gint32 y);
-void e_web_view_set_document_iframe_src
- (EWebView *web_view,
- const gchar *document_uri,
- const gchar *new_iframe_src);
+void e_web_view_set_iframe_src (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *new_src);
void e_web_view_register_element_clicked
(EWebView *web_view,
const gchar *element_class,
@@ -300,8 +257,7 @@ void e_web_view_set_element_style_property
(EWebView *web_view,
const gchar *element_id,
const gchar *property_name,
- const gchar *value,
- const gchar *priority);
+ const gchar *value);
void e_web_view_set_element_attribute
(EWebView *web_view,
const gchar *element_id,
diff --git a/src/e-util/e-win32-reloc.c b/src/e-util/e-win32-reloc.c
index 9a729058b8..dbc7434b06 100644
--- a/src/e-util/e-win32-reloc.c
+++ b/src/e-util/e-win32-reloc.c
@@ -52,6 +52,7 @@ static const gchar *sounddir;
static const gchar *sysconfdir;
static const gchar *toolsdir;
static const gchar *uidir;
+static const gchar *webkitdatadir;
static HMODULE hmodule;
G_LOCK_DEFINE_STATIC (mutex);
@@ -130,6 +131,11 @@ setup (void)
imagesdir = g_getenv ("EVOLUTION_IMAGESDIR");
else
imagesdir = replace_prefix (full_prefix, EVOLUTION_IMAGESDIR);
+ if (g_getenv ("EVOLUTION_WEBKITDATADIR") &&
+ g_file_test (g_getenv ("EVOLUTION_WEBKITDATADIR"), G_FILE_TEST_IS_DIR))
+ webkitdatadir = g_getenv ("EVOLUTION_WEBKITDATADIR");
+ else
+ webkitdatadir = replace_prefix (full_prefix, EVOLUTION_WEBKITDATADIR);
libdir = replace_prefix (full_prefix, EVOLUTION_LIBDIR);
libexecdir = replace_prefix (full_prefix, EVOLUTION_LIBEXECDIR);
moduledir = replace_prefix (full_prefix, EVOLUTION_MODULEDIR);
@@ -176,6 +182,7 @@ GETTER(sounddir)
GETTER(sysconfdir)
GETTER(toolsdir)
GETTER(uidir)
+GETTER(webkitdatadir)
gpointer _e_get_dll_hmodule (void)
{
diff --git a/src/e-util/test-web-view-jsc.c b/src/e-util/test-web-view-jsc.c
new file mode 100644
index 0000000000..f5dbdc43ca
--- /dev/null
+++ b/src/e-util/test-web-view-jsc.c
@@ -0,0 +1,1955 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2019 Red Hat (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-config.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <locale.h>
+#include <e-util/e-util.h>
+
+enum {
+ LOAD_ALL = -1,
+ LOAD_MAIN = 0,
+ LOAD_FRM1 = 1,
+ LOAD_FRM1_1 = 2,
+ LOAD_FRM2 = 3
+};
+
+typedef struct _TestFlagClass {
+ GObjectClass parent_class;
+} TestFlagClass;
+
+typedef struct _TestFlag {
+ GObject parent;
+ gboolean is_set;
+} TestFlag;
+
+GType test_flag_get_type (void);
+
+G_DEFINE_TYPE (TestFlag, test_flag, G_TYPE_OBJECT)
+
+enum {
+ FLAGGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+test_flag_class_init (TestFlagClass *klass)
+{
+ signals[FLAGGED] = g_signal_new (
+ "flagged",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0,
+ G_TYPE_NONE);
+}
+
+static void
+test_flag_init (TestFlag *flag)
+{
+ flag->is_set = FALSE;
+}
+
+static void
+test_flag_set (TestFlag *flag)
+{
+ flag->is_set = TRUE;
+
+ g_signal_emit (flag, signals[FLAGGED], 0, NULL);
+}
+
+typedef struct _TestFixture {
+ GtkWidget *window;
+ WebKitWebView *web_view;
+
+ TestFlag *flag;
+} TestFixture;
+
+typedef void (* ETestFixtureSimpleFunc) (TestFixture *fixture);
+
+/* The tests do not use the 'user_data' argument, thus the functions avoid them and the typecast is needed.
*/
+typedef void (* ETestFixtureFunc) (TestFixture *fixture, gconstpointer user_data);
+
+static gboolean
+window_key_press_event_cb (GtkWindow *window,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ WebKitWebView *web_view = user_data;
+ WebKitWebInspector *inspector;
+ gboolean handled = FALSE;
+
+ inspector = webkit_web_view_get_inspector (web_view);
+
+ if ((event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == (GDK_CONTROL_MASK | GDK_SHIFT_MASK) &&
+ event->keyval == GDK_KEY_I) {
+ webkit_web_inspector_show (inspector);
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+static gboolean
+window_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ TestFixture *fixture = user_data;
+
+ gtk_widget_destroy (fixture->window);
+ fixture->window = NULL;
+ fixture->web_view = NULL;
+
+ test_flag_set (fixture->flag);
+
+ return TRUE;
+}
+
+static void
+test_utils_fixture_set_up (TestFixture *fixture,
+ gconstpointer user_data)
+{
+ WebKitSettings *settings;
+
+ fixture->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_default_size (GTK_WINDOW (fixture->window), 320, 240);
+
+ fixture->web_view = WEBKIT_WEB_VIEW (e_web_view_new ());
+ g_object_set (G_OBJECT (fixture->web_view),
+ "halign", GTK_ALIGN_FILL,
+ "hexpand", TRUE,
+ "valign", GTK_ALIGN_FILL,
+ "vexpand", TRUE,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (fixture->window), GTK_WIDGET (fixture->web_view));
+
+ settings = webkit_web_view_get_settings (fixture->web_view);
+ webkit_settings_set_enable_developer_extras (settings, TRUE);
+
+ g_signal_connect (
+ fixture->window, "key-press-event",
+ G_CALLBACK (window_key_press_event_cb), fixture->web_view);
+
+ g_signal_connect (
+ fixture->window, "delete-event",
+ G_CALLBACK (window_delete_event_cb), fixture);
+
+ gtk_widget_show_all (fixture->window);
+
+ fixture->flag = g_object_new (test_flag_get_type (), NULL);
+}
+
+static void
+test_utils_fixture_tear_down (TestFixture *fixture,
+ gconstpointer user_data)
+{
+ if (fixture->window) {
+ gtk_widget_destroy (fixture->window);
+ fixture->web_view = NULL;
+ }
+
+ g_clear_object (&fixture->flag);
+}
+
+static void
+test_utils_add_test (const gchar *name,
+ ETestFixtureSimpleFunc func)
+{
+ g_test_add (name, TestFixture, NULL,
+ test_utils_fixture_set_up, (ETestFixtureFunc) func, test_utils_fixture_tear_down);
+}
+
+static void
+test_utils_wait (TestFixture *fixture)
+{
+ GMainLoop *loop;
+ gulong handler_id;
+
+ g_return_if_fail (fixture != NULL);
+ g_return_if_fail (fixture->window != NULL);
+ g_return_if_fail (fixture->flag != NULL);
+
+ if (fixture->flag->is_set) {
+ fixture->flag->is_set = FALSE;
+ return;
+ }
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ handler_id = g_signal_connect_swapped (fixture->flag, "flagged", G_CALLBACK (g_main_loop_quit), loop);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+
+ g_signal_handler_disconnect (fixture->flag, handler_id);
+
+ fixture->flag->is_set = FALSE;
+}
+
+static void
+test_utils_jsc_call_done_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ gchar *script = user_data;
+ WebKitJavascriptResult *js_result;
+ GError *error = NULL;
+
+ g_return_if_fail (script != NULL);
+
+ js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (source_object), result, &error);
+
+ if (error) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ (!g_error_matches (error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED)
||
+ /* WebKit can return empty error message, thus ignore those. */
+ (error->message && *(error->message))))
+ g_warning ("Failed to call '%s' function: %s", script, error->message);
+ g_clear_error (&error);
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception)
+ g_warning ("Failed to call '%s': %s", script, jsc_exception_get_message (exception));
+
+ webkit_javascript_result_unref (js_result);
+ }
+
+ g_free (script);
+}
+
+typedef struct _JSCCallData {
+ TestFixture *fixture;
+ const gchar *script;
+ JSCValue **out_result;
+} JSCCallData;
+
+static void
+test_utils_jsc_call_sync_done_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ JSCCallData *jcd = user_data;
+ WebKitJavascriptResult *js_result;
+ GError *error = NULL;
+
+ g_return_if_fail (jcd != NULL);
+
+ js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (source_object), result, &error);
+
+ if (error) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ (!g_error_matches (error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED)
||
+ /* WebKit can return empty error message, thus ignore those. */
+ (error->message && *(error->message))))
+ g_warning ("Failed to call '%s': %s", jcd->script, error->message);
+ g_clear_error (&error);
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception)
+ g_warning ("Failed to call '%s': %s", jcd->script, jsc_exception_get_message
(exception));
+ else if (jcd->out_result)
+ *(jcd->out_result) = value ? g_object_ref (value) : NULL;
+
+ webkit_javascript_result_unref (js_result);
+ }
+
+ test_flag_set (jcd->fixture->flag);
+}
+
+static void
+test_utils_jsc_call (TestFixture *fixture,
+ const gchar *script)
+{
+ g_return_if_fail (fixture != NULL);
+ g_return_if_fail (fixture->web_view != NULL);
+ g_return_if_fail (script != NULL);
+
+ webkit_web_view_run_javascript (fixture->web_view, script, NULL, test_utils_jsc_call_done_cb,
g_strdup (script));
+}
+
+static void
+test_utils_jsc_call_sync (TestFixture *fixture,
+ const gchar *script,
+ JSCValue **out_result)
+{
+ JSCCallData jcd;
+
+ g_return_if_fail (fixture != NULL);
+ g_return_if_fail (fixture->web_view != NULL);
+ g_return_if_fail (script != NULL);
+
+ if (out_result)
+ *out_result = NULL;
+
+ jcd.fixture = fixture;
+ jcd.script = script;
+ jcd.out_result = out_result;
+
+ webkit_web_view_run_javascript (fixture->web_view, script, NULL, test_utils_jsc_call_sync_done_cb,
&jcd);
+
+ test_utils_wait (fixture);
+}
+
+static gboolean
+test_utils_jsc_call_bool_sync (TestFixture *fixture,
+ const gchar *script)
+{
+ JSCValue *result = NULL;
+ gboolean res;
+
+ test_utils_jsc_call_sync (fixture, script, &result);
+
+ g_assert_nonnull (result);
+ g_assert (jsc_value_is_boolean (result));
+
+ res = jsc_value_to_boolean (result);
+
+ g_clear_object (&result);
+
+ 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)
+{
+ JSCValue *result = NULL;
+ gchar *res;
+
+ test_utils_jsc_call_sync (fixture, script, &result);
+
+ g_assert_nonnull (result);
+ g_assert (jsc_value_is_null (result) || jsc_value_is_string (result));
+
+ if (jsc_value_is_null (result))
+ res = NULL;
+ else
+ res = jsc_value_to_string (result);
+
+ g_clear_object (&result);
+
+ return res;
+}
+
+static void
+test_utils_jsc_call_string_and_verify (TestFixture *fixture,
+ const gchar *script,
+ const gchar *expected_value)
+{
+ gchar *value;
+
+ value = test_utils_jsc_call_string_sync (fixture, script);
+
+ g_assert_cmpstr (value, ==, expected_value);
+
+ g_free (value);
+}
+
+static void
+test_utils_wait_noop (TestFixture *fixture)
+{
+ test_utils_jsc_call_sync (fixture, "javascript:void(0);", NULL);
+}
+
+static void
+test_utils_iframe_loaded_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ gpointer user_data)
+{
+ TestFixture *fixture = user_data;
+
+ g_return_if_fail (fixture != NULL);
+
+ test_flag_set (fixture->flag);
+}
+
+static void
+test_utils_load_iframe_content (TestFixture *fixture,
+ const gchar *iframe_id,
+ const gchar *content)
+{
+ gchar *script;
+ gulong handler_id;
+
+ handler_id = g_signal_connect (fixture->web_view, "content-loaded",
+ G_CALLBACK (test_utils_iframe_loaded_cb), fixture);
+
+ script = e_web_view_jsc_printf_script ("Evo.SetIFrameContent(%s,%s)", iframe_id, content);
+
+ test_utils_jsc_call (fixture, script);
+
+ g_free (script);
+
+ test_utils_wait (fixture);
+
+ g_signal_handler_disconnect (fixture->web_view, handler_id);
+
+ test_utils_wait_noop (fixture);
+}
+
+static void
+load_changed_cb (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
+{
+ TestFixture *fixture = user_data;
+
+ g_return_if_fail (fixture != NULL);
+
+ if (load_event == WEBKIT_LOAD_FINISHED)
+ test_flag_set (fixture->flag);
+}
+
+static void
+test_utils_load_string (TestFixture *fixture,
+ const gchar *content)
+{
+ gulong handler_id;
+
+ handler_id = g_signal_connect (fixture->web_view, "load-changed",
+ G_CALLBACK (load_changed_cb), fixture);
+
+ e_web_view_load_string (E_WEB_VIEW (fixture->web_view), content);
+
+ test_utils_wait (fixture);
+
+ g_signal_handler_disconnect (fixture->web_view, handler_id);
+
+ test_utils_wait_noop (fixture);
+}
+
+static void
+test_utils_load_body (TestFixture *fixture,
+ gint index)
+{
+ if (index == LOAD_MAIN || index == LOAD_ALL) {
+ test_utils_load_string (fixture,
+ "<html><body>"
+ "Top<br>"
+ "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\"><br>"
+ "<input id=\"chk1\" class=\"cchk1\" type=\"checkbox\" value=\"Check1\">"
+ "<iframe id=\"frm1\" src=\"empty:///frm1\"></iframe><br>"
+ "<iframe id=\"frm2\" src=\"empty:///frm2\"></iframe><br>"
+ "<input id=\"btn3\" class=\"cbtn3\" type=\"button\" value=\"Button3\">"
+ "<a name=\"dots\" id=\"dots1\" class=\"cdots\">...</a>"
+ "</body></html>");
+ }
+
+ if (index == LOAD_FRM1 || index == LOAD_ALL) {
+ test_utils_load_iframe_content (fixture, "frm1",
+ "<html><body>"
+ "frm1<br>"
+ "<iframe id=\"frm1_1\" src=\"empty:///frm1_1\"></iframe><br>"
+ "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+ "</body></html>");
+ }
+
+ if (index == LOAD_FRM1_1 || index == LOAD_ALL) {
+ test_utils_load_iframe_content (fixture, "frm1_1",
+ "<html><body>"
+ "frm1_1<br>"
+ "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+ "<input id=\"chk1\" class=\"cchk1\" type=\"checkbox\" value=\"Check1\">"
+ "<a name=\"dots\" id=\"dots2\" class=\"cdots\">...</a>"
+ "<input id=\"btn2\" class=\"cbtn2\" type=\"button\" value=\"Button2\">"
+ "</body></html>");
+ }
+
+ if (index == LOAD_FRM2 || index == LOAD_ALL) {
+ test_utils_load_iframe_content (fixture, "frm2",
+ "<html><body>"
+ "frm2<br>"
+ "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\">"
+ "<input id=\"btn2\" class=\"cbtn2\" type=\"button\" value=\"Button2\">"
+ "<input id=\"chk2\" class=\"cchk2\" type=\"checkbox\" value=\"Check2\">"
+ "</body></html>");
+ }
+}
+
+static void
+test_jsc_object_properties (TestFixture *fixture)
+{
+ JSCValue *jsc_object = NULL;
+ gchar *str;
+
+ str = e_web_view_jsc_printf_script (
+ "test_obj_props = function()\n"
+ "{\n"
+ " var arrobj = [];\n"
+ " arrobj[\"btrue\"] = true;\n"
+ " arrobj[\"bfalse\"] = false;\n"
+ " arrobj[\"i2\"] = 2;\n"
+ " arrobj[\"i67890\"] = 67890;\n"
+ " arrobj[\"i-12345\"] = -12345;\n"
+ " arrobj[\"d-54.32\"] = -54.32;\n"
+ " arrobj[\"d67.89\"] = 67.89;\n"
+ " arrobj[\"s-it\"] = \"it\";\n"
+ " arrobj[\"s-Is\"] = \"Is\";\n"
+ " return arrobj;\n"
+ "}\n"
+ "test_obj_props();\n");
+
+ test_utils_jsc_call_sync (fixture, str, &jsc_object);
+
+ g_free (str);
+
+ g_assert_nonnull (jsc_object);
+ g_assert (jsc_value_is_object (jsc_object));
+
+ g_assert (e_web_view_jsc_get_object_property_boolean (jsc_object, "btrue", FALSE));
+ g_assert (!e_web_view_jsc_get_object_property_boolean (jsc_object, "bfalse", TRUE));
+ g_assert (!e_web_view_jsc_get_object_property_boolean (jsc_object, "budenfined", FALSE));
+ g_assert (e_web_view_jsc_get_object_property_boolean (jsc_object, "budenfined", TRUE));
+ g_assert_cmpint (e_web_view_jsc_get_object_property_int32 (jsc_object, "i2", 0), ==, 2);
+ g_assert_cmpint (e_web_view_jsc_get_object_property_int32 (jsc_object, "i67890", 0), ==, 67890);
+ g_assert_cmpint (e_web_view_jsc_get_object_property_int32 (jsc_object, "i-12345", 0), ==, -12345);
+ g_assert_cmpint (e_web_view_jsc_get_object_property_int32 (jsc_object, "iundefined", 333), ==, 333);
+ g_assert_cmpfloat (e_web_view_jsc_get_object_property_double (jsc_object, "d-54.32", 0.0), ==,
-54.32);
+ g_assert_cmpfloat (e_web_view_jsc_get_object_property_double (jsc_object, "d67.89", 0.0), ==, 67.89);
+ g_assert_cmpfloat (e_web_view_jsc_get_object_property_double (jsc_object, "dundefined", 123.456), ==,
123.456);
+
+ str = e_web_view_jsc_get_object_property_string (jsc_object, "s-it", NULL);
+ g_assert_cmpstr (str, ==, "it");
+ g_free (str);
+
+ str = e_web_view_jsc_get_object_property_string (jsc_object, "s-Is", NULL);
+ g_assert_cmpstr (str, ==, "Is");
+ g_free (str);
+
+ str = e_web_view_jsc_get_object_property_string (jsc_object, "sundefined", "xxx");
+ g_assert_cmpstr (str, ==, "xxx");
+ g_free (str);
+
+ str = e_web_view_jsc_get_object_property_string (jsc_object, "sundefined", NULL);
+ g_assert_null (str);
+
+ g_clear_object (&jsc_object);
+}
+
+static void
+test_set_element_hidden (TestFixture *fixture)
+{
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "", "btn1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "frm1_1", "btn1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "frm2", "btn2", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "frm2", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+
+ e_web_view_jsc_set_element_hidden (fixture->web_view, "frm1_1", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").hidden"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").hidden"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").hidden"));
+}
+
+static void
+test_set_element_disabled (TestFixture *fixture)
+{
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "", "btn1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "frm1_1", "btn1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "frm2", "btn2", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "frm2", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+
+ e_web_view_jsc_set_element_disabled (fixture->web_view, "frm1_1", "btn1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"btn3\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"btn1\").disabled"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn1\").disabled"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"btn2\").disabled"));
+}
+
+static void
+test_set_element_checked (TestFixture *fixture)
+{
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "", "chk1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "frm1_1", "chk1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "", "chk1", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "frm2", "chk2", FALSE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "", "chk1", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+
+ e_web_view_jsc_set_element_checked (fixture->web_view, "frm1_1", "chk1", FALSE, NULL);
+ e_web_view_jsc_set_element_checked (fixture->web_view, "frm2", "chk2", TRUE, NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"\", \"chk1\").checked"));
+ g_assert (!test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm1_1\", \"chk1\").checked"));
+ g_assert (test_utils_jsc_call_bool_sync (fixture, "Evo.findElement(\"frm2\", \"chk2\").checked"));
+}
+
+static void
+test_set_element_style_property (TestFixture *fixture)
+{
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn3\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").style.getPropertyValue(\"color\")", "");
+
+ e_web_view_jsc_set_element_style_property (fixture->web_view, "", "btn1", "color", "blue", NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn1\").style.getPropertyValue(\"color\")", "blue");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn3\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").style.getPropertyValue(\"color\")", "");
+
+ e_web_view_jsc_set_element_style_property (fixture->web_view, "frm2", "btn1", "color", "green", NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn1\").style.getPropertyValue(\"color\")", "blue");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn3\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").style.getPropertyValue(\"color\")", "green");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").style.getPropertyValue(\"color\")", "");
+
+ e_web_view_jsc_set_element_style_property (fixture->web_view, "frm2", "btn1", "color", NULL, NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn1\").style.getPropertyValue(\"color\")", "blue");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\",
\"btn3\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").style.getPropertyValue(\"color\")", "");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").style.getPropertyValue(\"color\")", "");
+}
+
+static void
+test_set_element_attribute (TestFixture *fixture)
+{
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn1\").getAttributeNS(\"\",
\"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn3\").getAttributeNS(\"\",
\"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").getAttributeNS(\"\", \"myattr\")", NULL);
+
+ e_web_view_jsc_set_element_attribute (fixture->web_view, "", "btn1", NULL, "myattr", "val1", NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn1\").getAttributeNS(\"\",
\"myattr\")", "val1");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn3\").getAttributeNS(\"\",
\"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").getAttributeNS(\"\", \"myattr\")", NULL);
+
+ e_web_view_jsc_set_element_attribute (fixture->web_view, "frm2", "btn1", NULL, "myattr", "val2",
NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn1\").getAttributeNS(\"\",
\"myattr\")", "val1");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn3\").getAttributeNS(\"\",
\"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", "val2");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn2\").getAttributeNS(\"\", \"myattr\")", NULL);
+
+ e_web_view_jsc_set_element_attribute (fixture->web_view, "frm2", "btn1", NULL, "myattr", NULL, NULL);
+ test_utils_wait_noop (fixture);
+
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn1\").getAttributeNS(\"\",
\"myattr\")", "val1");
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"\", \"btn3\").getAttributeNS(\"\",
\"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm1_1\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Evo.findElement(\"frm2\",
\"btn1\").getAttributeNS(\"\", \"myattr\")", NULL);
+ 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, LOAD_ALL);
+
+ 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.hasStyle = function(iframe_id, style_sheet_id)\n"
+ "{\n"
+ " var doc = Evo.findIFrameDocument(iframe_id);\n"
+ " var styles = doc.head.getElementsByTagName(\"style\"), ii;\n"
+ "\n"
+ " for (ii = styles.length - 1; ii >= 0; ii--) {\n"
+ " if (styles[ii].id == style_sheet_id) {\n"
+ " return true;\n"
+ " }\n"
+ " }\n"
+ " return false;\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"
+ " var value =
styles.cssRules[ii].style.getPropertyValue(property_name);\n"
+ " return (!value || value == \"\") ? null : value;\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 (1, ==, 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\")", NULL);
+
+ e_web_view_jsc_create_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 (1, ==, 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\", \"input\",
\"background-color\")", NULL);
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"table\",
\"color\")", NULL);
+
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheet2", "input",
"background-color:black;", NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheet2", "table",
"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 (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\", \"input\",
\"background-color\")", "black");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"table\",
\"color\")", "green");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"table\",
\"background-color\")", NULL);
+ 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_rule_into_style_sheet (fixture->web_view, "*", "sheet3", "body", "color:orange;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheet2", "table", "color:red;
background-color:white;", 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 (3, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (2, ==, 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\", \"input\",
\"background-color\")", "black");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"table\",
\"color\")", "red");
+ test_utils_jsc_call_string_and_verify (fixture, "Test.getStyle(\"frm1_1\", \"sheet2\", \"table\",
\"background-color\")", "white");
+ 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");
+
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"\", \"sheetA\")") ?
1 : 0);
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1_1\",
\"sheetA\")") ? 1 : 0);
+
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "", "sheetA", "body", "color:blue;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1", "sheetA", "body", "color:blue;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheetA", "body",
"color:blue;", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (1, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"\", \"sheetA\")") ?
1 : 0);
+ g_assert_cmpint (1, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (1, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1_1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (3, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1\")"));
+ g_assert_cmpint (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_remove_style_sheet (fixture->web_view, "frm1", "sheetA", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (1, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"\", \"sheetA\")") ?
1 : 0);
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (1, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1_1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (4, ==, 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 (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_remove_style_sheet (fixture->web_view, "*", "sheetA", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"\", \"sheetA\")") ?
1 : 0);
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1\",
\"sheetA\")") ? 1 : 0);
+ g_assert_cmpint (0, ==, test_utils_jsc_call_bool_sync (fixture, "Test.hasStyle(\"frm1_1\",
\"sheetA\")") ? 1 : 0);
+ 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 (3, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_remove_style_sheet (fixture->web_view, "frm1_1", "*", 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 (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm1_1\")"));
+ g_assert_cmpint (2, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "", "sheetB", "body", "color:green;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1", "sheetD", "body", "color:blue;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheetB", "body",
"color:green;", NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm1_1", "sheetC", "body",
"color:yellow;", NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm2", "sheetD", "body", "color:blue;",
NULL);
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "frm2", "sheetE", "body",
"color:orange;", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (3, ==, 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 (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_remove_style_sheet (fixture->web_view, "", "*", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (3, ==, 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 (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_add_rule_into_style_sheet (fixture->web_view, "", "sheetC", "body", "color:yellow;",
NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (1, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (3, ==, 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 (4, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"frm2\")"));
+
+ e_web_view_jsc_remove_style_sheet (fixture->web_view, "*", "*", NULL);
+ test_utils_wait_noop (fixture);
+
+ g_assert_cmpint (0, ==, test_utils_jsc_call_int32_sync (fixture, "Test.nStyles(\"\")"));
+ g_assert_cmpint (0, ==, 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\")"));
+}
+
+typedef struct _ElementClickedData {
+ TestFixture *fixture;
+ const gchar *iframe_id;
+ const gchar *element_id;
+ const gchar *element_class;
+ const gchar *element_value;
+} ElementClickedData;
+
+static void
+test_verify_element_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *element_class,
+ const gchar *element_value,
+ const GtkAllocation *element_position,
+ gpointer user_data)
+{
+ ElementClickedData *expects = user_data;
+
+ g_assert_nonnull (expects);
+ g_assert_cmpstr (iframe_id, ==, expects->iframe_id);
+ g_assert_cmpstr (element_id, ==, expects->element_id);
+ g_assert_cmpstr (element_class, ==, expects->element_class);
+ g_assert_cmpstr (element_value, ==, expects->element_value);
+ g_assert_cmpint (element_position->x, >, 0);
+ g_assert_cmpint (element_position->y, >, 0);
+ g_assert_cmpint (element_position->width, >, 0);
+ g_assert_cmpint (element_position->height, >, 0);
+
+ test_flag_set (expects->fixture->flag);
+}
+
+static void
+test_verify_element_clicked (TestFixture *fixture,
+ ElementClickedData *expects,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *element_class,
+ const gchar *element_value,
+ gboolean wait_response)
+{
+ gchar *script;
+
+ expects->iframe_id = iframe_id;
+ expects->element_id = element_id;
+ expects->element_class = element_class;
+ expects->element_value = element_value;
+
+ script = e_web_view_jsc_printf_script ("Evo.findIFrameDocument(%s).getElementById(%s).click();",
+ iframe_id, element_id);
+
+ test_utils_jsc_call (fixture, script);
+
+ g_free (script);
+
+ if (wait_response)
+ test_utils_wait (fixture);
+}
+
+static void
+test_element_clicked (TestFixture *fixture)
+{
+ ElementClickedData expects;
+
+ test_utils_load_body (fixture, LOAD_MAIN);
+
+ expects.fixture = fixture;
+
+ e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn1",
test_verify_element_clicked_cb, &expects);
+
+ test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+
+ test_utils_load_body (fixture, LOAD_FRM1);
+
+ test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", TRUE);
+
+ test_utils_load_body (fixture, LOAD_FRM1_1);
+
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", FALSE);
+
+ e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn2",
test_verify_element_clicked_cb, &expects);
+
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+
+ test_utils_load_body (fixture, LOAD_FRM2);
+
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+
+ e_web_view_register_element_clicked (E_WEB_VIEW (fixture->web_view), "cdots",
test_verify_element_clicked_cb, &expects);
+
+ test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, TRUE);
+ test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, TRUE);
+
+ e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn1",
test_verify_element_clicked_cb, &expects);
+
+ test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", TRUE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, TRUE);
+
+ e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cbtn2",
test_verify_element_clicked_cb, &expects);
+ e_web_view_unregister_element_clicked (E_WEB_VIEW (fixture->web_view), "cdots",
test_verify_element_clicked_cb, &expects);
+
+ test_verify_element_clicked (fixture, &expects, "", "btn3", "cbtn3", "Button3", FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "dots1", "cdots", NULL, FALSE);
+ test_verify_element_clicked (fixture, &expects, "", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "btn2", "cbtn2", "Button2", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn1", "cbtn1", "Button1", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm2", "btn2", "cbtn2", "Button2", FALSE);
+ test_verify_element_clicked (fixture, &expects, "frm1_1", "dots2", "cdots", NULL, FALSE);
+
+ test_utils_wait_noop (fixture);
+}
+
+typedef struct _NeedInputData {
+ TestFixture *fixture;
+ gboolean expects;
+} NeedInputData;
+
+static void
+test_verify_need_input_cb (GObject *object,
+ GParamSpec *param,
+ gpointer user_data)
+{
+ NeedInputData *nid = user_data;
+
+ g_assert_nonnull (nid);
+ g_assert_cmpint ((e_web_view_get_need_input (E_WEB_VIEW (nid->fixture->web_view)) ? 1 : 0), ==,
(nid->expects ? 1 : 0));
+
+ test_flag_set (nid->fixture->flag);
+}
+
+static void
+test_verify_need_input (TestFixture *fixture,
+ NeedInputData *nid,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean expects)
+{
+ nid->expects = expects;
+
+ if (iframe_id) {
+ gchar *script;
+
+ script = e_web_view_jsc_printf_script
("Evo.findIFrameDocument(%s).getElementById(%s).focus();",
+ iframe_id, element_id);
+
+ test_utils_jsc_call (fixture, script);
+
+ g_free (script);
+ } else {
+ test_utils_jsc_call (fixture, "document.activeElement.blur();");
+ }
+
+ test_utils_wait (fixture);
+}
+
+static void
+test_need_input_changed (TestFixture *fixture)
+{
+ gulong handler_id;
+ NeedInputData nid;
+
+ test_utils_load_string (fixture,
+ "<html><body>"
+ "Top<br>"
+ "<input id=\"btn1\" class=\"cbtn1\" type=\"button\" value=\"Button1\"><br>"
+ "<iframe id=\"frm1_1\" src=\"empty:///\"></iframe><br>"
+ "<input id=\"btn3\" class=\"cbtn3\" type=\"button\" value=\"Button3\">"
+ "<a name=\"dots\" id=\"dots1\" class=\"cdots\">...</a>"
+ "<label for=\"inptrdo\" id=\"lblradio\">Radio</label>"
+ "<input type=\"radio\" name=\"rdo\" id=\"inptrdo\" value=\"rdoval\"><br>"
+ "<textarea id=\"txt\" rows=\"3\" cols=\"20\">Text area text</textarea><br>"
+ "<select id=\"slct\">"
+ " <option value=\"opt1\">opt1</option>"
+ " <option value=\"opt2\">opt2</option>"
+ " <option value=\"opt3\">opt3</option>"
+ "</select><br>"
+ "<button id=\"bbtn\" type=\"button\">Button</button>"
+ "</body></html>");
+
+ test_utils_load_body (fixture, LOAD_FRM1_1);
+
+ g_assert (!e_web_view_get_need_input (E_WEB_VIEW (fixture->web_view)));
+
+ nid.fixture = fixture;
+ nid.expects = FALSE;
+
+ handler_id = g_signal_connect (fixture->web_view, "notify::need-input",
+ G_CALLBACK (test_verify_need_input_cb), &nid);
+
+ test_verify_need_input (fixture, &nid, "", "btn1", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "frm1_1", "btn2", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "btn3", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "lblradio", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "inptrdo", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "inptrdo", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "txt", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "slct", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+ test_verify_need_input (fixture, &nid, "", "bbtn", TRUE);
+ test_verify_need_input (fixture, &nid, NULL, NULL, FALSE);
+
+ g_signal_handler_disconnect (fixture->web_view, handler_id);
+
+ g_assert (!e_web_view_get_need_input (E_WEB_VIEW (fixture->web_view)));
+}
+
+static void
+test_selection_select_in_iframe (TestFixture *fixture,
+ const gchar *iframe_id,
+ const gchar *start_elem_id,
+ const gchar *end_elem_id)
+{
+ gchar *script;
+
+ script = e_web_view_jsc_printf_script (
+ /* Clean selection in both places first, otherwise the previous selection
+ can stay when changing it only in one of them. */
+ "Evo.findIFrameDocument(\"\").defaultView.getSelection().empty();\n"
+ "Evo.findIFrameDocument(\"frm1\").defaultView.getSelection().empty();\n"
+ "\n"
+ "var doc, range;\n"
+ "doc = Evo.findIFrameDocument(%s);\n"
+ "range = doc.createRange();\n"
+ "range.selectNodeContents(doc.getElementById(%s));"
+ "doc.defaultView.getSelection().addRange(range);\n"
+ "doc.defaultView.getSelection().extend(doc.getElementById(%s));\n",
+ iframe_id, start_elem_id, end_elem_id);
+
+ test_utils_jsc_call_sync (fixture, script, NULL);
+
+ g_free (script);
+
+ /* Wait for the notification from JS about changed selection
+ to be propagated into EWebView's has-selection. */
+ test_utils_wait_noop (fixture);
+}
+
+typedef struct _GetContentData {
+ TestFixture *fixture;
+ const gchar *expect_plain;
+ const gchar *expect_html;
+} GetContentData;
+
+static void
+test_verify_get_content_data (GetContentData *gcd,
+ const GSList *texts)
+{
+ g_assert_nonnull (gcd);
+
+ if (gcd->expect_plain && gcd->expect_html) {
+ g_assert_cmpint (g_slist_length ((GSList *) texts), ==, 2);
+ g_assert_cmpstr (texts->data, ==, gcd->expect_plain);
+ g_assert_cmpstr (texts->next->data, ==, gcd->expect_html);
+ } else if (gcd->expect_plain) {
+ g_assert_cmpint (g_slist_length ((GSList *) texts), ==, 1);
+ g_assert_cmpstr (texts->data, ==, gcd->expect_plain);
+ } else if (gcd->expect_html) {
+ g_assert_cmpint (g_slist_length ((GSList *) texts), ==, 1);
+ g_assert_cmpstr (texts->data, ==, gcd->expect_html);
+ } else {
+ g_assert_cmpint (g_slist_length ((GSList *) texts), ==, 0);
+ }
+}
+
+static void
+test_selection_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GetContentData *gcd = user_data;
+ GSList *texts = NULL;
+ gboolean success;
+ GError *error = NULL;
+
+ g_assert (WEBKIT_IS_WEB_VIEW (source_object));
+ g_assert_nonnull (gcd);
+
+ success = e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source_object), result, &texts,
&error);
+
+ g_assert_no_error (error);
+ g_assert (success);
+
+ test_verify_get_content_data (gcd, texts);
+
+ g_slist_free_full (texts, g_free);
+
+ test_flag_set (gcd->fixture->flag);
+}
+
+static void
+test_selection_verify (TestFixture *fixture,
+ const gchar *expect_plain,
+ const gchar *expect_html)
+{
+ ETextFormat format;
+ GetContentData gcd;
+
+ if (expect_plain && expect_html)
+ format = E_TEXT_FORMAT_BOTH;
+ else if (expect_html)
+ format = E_TEXT_FORMAT_HTML;
+ else
+ format = E_TEXT_FORMAT_PLAIN;
+
+ gcd.fixture = fixture;
+ gcd.expect_plain = expect_plain;
+ gcd.expect_html = expect_html;
+
+ e_web_view_jsc_get_selection (fixture->web_view, format, NULL, test_selection_ready_cb, &gcd);
+
+ test_utils_wait (fixture);
+}
+
+static void
+test_selection (TestFixture *fixture)
+{
+ test_utils_load_string (fixture,
+ "<html><body>"
+ "<pre id=\"pr\">Out<span id=\"pr1\"></span>er text\nin PR<span id=\"pr2\"></span>E</pre><br
id=\"br1\">"
+ "o<font color=\"orange\">rang</font>e; <b>bold</b><i>italic</i><br id=\"br2\">"
+ "<iframe id=\"frm1\" src=\"empty:///\"></iframe><br>"
+ "</body></html>");
+
+ test_utils_load_iframe_content (fixture, "frm1",
+ "<html><body>"
+ "frm1<br>"
+ "<div id=\"plain\">unformatted text</div><br>"
+ "<div id=\"rgb\">"
+ "<font color=\"red\">R</font>"
+ "<font color=\"green\">G</font>"
+ "<font color=\"blue\">B</font>"
+ "</div>"
+ "<div id=\"styled\">"
+ "<span style=\"color:blue;\">bb</span>"
+ "<span style=\"color:green;\">gg</span>"
+ "<span style=\"color:red;\">rr</span>"
+ "</div>"
+ "<div id=\"end\"></div>"
+ "</body></html>");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 0);
+ test_selection_verify (fixture, NULL, NULL);
+
+ test_selection_select_in_iframe (fixture, "", "pr1", "pr2");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 1);
+ test_selection_verify (fixture, "er text\nin PR", NULL);
+ test_selection_verify (fixture, NULL, "<pre>er text\nin PR</pre>");
+ test_selection_verify (fixture, "er text\nin PR", "<pre>er text\nin PR</pre>");
+
+ test_selection_select_in_iframe (fixture, "", "br1", "br2");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 1);
+ test_selection_verify (fixture, "\norange; bolditalic", NULL);
+ test_selection_verify (fixture, NULL, "<br id=\"br1\">o<font color=\"orange\">rang</font>e;
<b>bold</b><i>italic</i>");
+ test_selection_verify (fixture, "\norange; bolditalic", "<br id=\"br1\">o<font
color=\"orange\">rang</font>e; <b>bold</b><i>italic</i>");
+
+ test_selection_select_in_iframe (fixture, "frm1", "plain", "rgb");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 1);
+ test_selection_verify (fixture, "unformatted text\n", NULL);
+ test_selection_verify (fixture, NULL, "<div id=\"plain\">unformatted text</div><br><div
id=\"rgb\"></div>");
+ test_selection_verify (fixture, "unformatted text\n", "<div id=\"plain\">unformatted
text</div><br><div id=\"rgb\"></div>");
+
+ test_selection_select_in_iframe (fixture, "frm1", "rgb", "styled");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 1);
+ test_selection_verify (fixture, "RGB", NULL);
+ test_selection_verify (fixture, NULL, "<div id=\"rgb\"><font color=\"red\">R</font><font
color=\"green\">G</font><font color=\"blue\">B</font></div><div id=\"styled\"></div>");
+ test_selection_verify (fixture, "RGB", "<div id=\"rgb\"><font color=\"red\">R</font><font
color=\"green\">G</font><font color=\"blue\">B</font></div><div id=\"styled\"></div>");
+
+ test_selection_select_in_iframe (fixture, "frm1", "styled", "end");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 1);
+ test_selection_verify (fixture, "bbggrr", NULL);
+ test_selection_verify (fixture, NULL, "<span style=\"color:blue;\">bb</span><span
style=\"color:green;\">gg</span><span style=\"color:red;\">rr</span>");
+ test_selection_verify (fixture, "bbggrr", "<span style=\"color:blue;\">bb</span><span
style=\"color:green;\">gg</span><span style=\"color:red;\">rr</span>");
+
+ test_selection_select_in_iframe (fixture, "frm1", "end", "end");
+
+ g_assert_cmpint (e_web_view_has_selection (E_WEB_VIEW (fixture->web_view)) ? 1 : 0, ==, 0);
+ test_selection_verify (fixture, NULL, NULL);
+}
+
+static void
+test_get_document_content_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GetContentData *gcd = user_data;
+ GSList *texts = NULL;
+ gboolean success;
+ GError *error = NULL;
+
+ g_assert (WEBKIT_IS_WEB_VIEW (source_object));
+ g_assert_nonnull (gcd);
+
+ success = e_web_view_jsc_get_document_content_finish (WEBKIT_WEB_VIEW (source_object), result,
&texts, &error);
+
+ g_assert_no_error (error);
+ g_assert (success);
+
+ test_verify_get_content_data (gcd, texts);
+
+ g_slist_free_full (texts, g_free);
+
+ test_flag_set (gcd->fixture->flag);
+}
+
+static void
+test_get_document_content_verify (TestFixture *fixture,
+ const gchar *iframe_id,
+ const gchar *expect_plain,
+ const gchar *expect_html)
+{
+ ETextFormat format;
+ GetContentData gcd;
+
+ if (expect_plain && expect_html)
+ format = E_TEXT_FORMAT_BOTH;
+ else if (expect_html)
+ format = E_TEXT_FORMAT_HTML;
+ else
+ format = E_TEXT_FORMAT_PLAIN;
+
+ gcd.fixture = fixture;
+ gcd.expect_plain = expect_plain;
+ gcd.expect_html = expect_html;
+
+ e_web_view_jsc_get_document_content (fixture->web_view, iframe_id, format, NULL,
test_get_document_content_ready_cb, &gcd);
+
+ test_utils_wait (fixture);
+}
+
+static void
+test_get_element_content_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GetContentData *gcd = user_data;
+ GSList *texts = NULL;
+ gboolean success;
+ GError *error = NULL;
+
+ g_assert (WEBKIT_IS_WEB_VIEW (source_object));
+ g_assert_nonnull (gcd);
+
+ success = e_web_view_jsc_get_element_content_finish (WEBKIT_WEB_VIEW (source_object), result, &texts,
&error);
+
+ g_assert_no_error (error);
+ g_assert (success);
+
+ test_verify_get_content_data (gcd, texts);
+
+ g_slist_free_full (texts, g_free);
+
+ test_flag_set (gcd->fixture->flag);
+}
+
+static void
+test_get_element_content_verify (TestFixture *fixture,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ gboolean use_outer_html,
+ const gchar *expect_plain,
+ const gchar *expect_html)
+{
+ ETextFormat format;
+ GetContentData gcd;
+
+ if (expect_plain && expect_html)
+ format = E_TEXT_FORMAT_BOTH;
+ else if (expect_html)
+ format = E_TEXT_FORMAT_HTML;
+ else
+ format = E_TEXT_FORMAT_PLAIN;
+
+ gcd.fixture = fixture;
+ gcd.expect_plain = expect_plain;
+ gcd.expect_html = expect_html;
+
+ e_web_view_jsc_get_element_content (fixture->web_view, iframe_id, element_id, format, use_outer_html,
NULL, test_get_element_content_ready_cb, &gcd);
+
+ test_utils_wait (fixture);
+}
+
+static void
+test_get_content (TestFixture *fixture)
+{
+ const gchar *html_main =
+ "<html style=\"\"><head><meta charset=\"utf-8\"></head><body>"
+ "<div id=\"frst\">first div</div>"
+ "<div id=\"scnd\">second div</div>"
+ "<iframe id=\"frm1\" src=\"empty:///\"></iframe>"
+ "</body></html>";
+ const gchar *html_frm1 =
+ "<html style=\"\"><head><meta name=\"keywords\" value=\"test\"></head><body>"
+ "<span id=\"frm1p\">"
+ "<div id=\"frst\">frm1 div</div>"
+ "</span>"
+ "</body></html>";
+ const gchar *expect_html, *expect_plain;
+
+ test_utils_load_string (fixture, html_main);
+ test_utils_load_iframe_content (fixture, "frm1", html_frm1);
+
+ /* Clean up styles added by EWebView */
+ test_utils_jsc_call_sync (fixture, "Evo.SetElementStyleProperty(\"\",\"*html\",\"color\",null);",
NULL);
+ test_utils_jsc_call_sync (fixture,
"Evo.SetElementStyleProperty(\"\",\"*html\",\"background-color\",null);", NULL);
+ test_utils_jsc_call_sync (fixture, "Evo.SetElementAttribute(\"\",\"*body\",\"\",\"class\",null);",
NULL);
+ test_utils_jsc_call_sync (fixture, "Evo.SetElementStyleProperty(\"frm1\",\"*html\",\"color\",null);",
NULL);
+ test_utils_jsc_call_sync (fixture,
"Evo.SetElementStyleProperty(\"frm1\",\"*html\",\"background-color\",null);", NULL);
+ test_utils_jsc_call_sync (fixture,
"Evo.SetElementAttribute(\"frm1\",\"*body\",\"\",\"class\",null);", NULL);
+ test_utils_jsc_call_sync (fixture, "Evo.RemoveStyleSheet(\"*\",\"*\");", NULL);
+
+ expect_plain = "first div\nsecond div\n";
+ expect_html = html_main;
+
+ test_get_document_content_verify (fixture, "", expect_plain, NULL);
+ test_get_document_content_verify (fixture, "", NULL, expect_html);
+ test_get_document_content_verify (fixture, "", expect_plain, expect_html);
+
+ expect_plain = "frm1 div";
+ expect_html = html_frm1;
+ test_get_document_content_verify (fixture, "frm1", expect_plain, NULL);
+ test_get_document_content_verify (fixture, "frm1", NULL, expect_html);
+ test_get_document_content_verify (fixture, "frm1", expect_plain, expect_html);
+
+ expect_plain = "";
+ expect_html = "<meta charset=\"utf-8\">";
+ test_get_element_content_verify (fixture, "", "*head", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "*head", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "*head", FALSE, expect_plain, expect_html);
+
+ expect_html = "<head><meta charset=\"utf-8\"></head>";
+ test_get_element_content_verify (fixture, "", "*head", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "*head", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "*head", TRUE, expect_plain, expect_html);
+
+ expect_html = "<meta name=\"keywords\" value=\"test\">";
+ test_get_element_content_verify (fixture, "frm1", "*head", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "*head", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "*head", FALSE, expect_plain, expect_html);
+
+ expect_html = "<head><meta name=\"keywords\" value=\"test\"></head>";
+ test_get_element_content_verify (fixture, "frm1", "*head", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "*head", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "*head", TRUE, expect_plain, expect_html);
+
+ expect_plain = "first div\nsecond div\n";
+ expect_html =
+ "<div id=\"frst\">first div</div>"
+ "<div id=\"scnd\">second div</div>"
+ "<iframe id=\"frm1\" src=\"empty:///\"></iframe>";
+ test_get_element_content_verify (fixture, "", "*body", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "*body", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "*body", FALSE, expect_plain, expect_html);
+
+ expect_html = "<body>"
+ "<div id=\"frst\">first div</div>"
+ "<div id=\"scnd\">second div</div>"
+ "<iframe id=\"frm1\" src=\"empty:///\"></iframe></body>";
+ test_get_element_content_verify (fixture, "", "*body", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "*body", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "*body", TRUE, expect_plain, expect_html);
+
+ expect_plain = "frm1 div";
+ expect_html ="<span id=\"frm1p\"><div id=\"frst\">frm1 div</div></span>";
+ test_get_element_content_verify (fixture, "frm1", "*body", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "*body", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "*body", FALSE, expect_plain, expect_html);
+
+ expect_html = "<body><span id=\"frm1p\"><div id=\"frst\">frm1 div</div></span></body>";
+ test_get_element_content_verify (fixture, "frm1", "*body", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "*body", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "*body", TRUE, expect_plain, expect_html);
+
+ expect_plain = "first div";
+ expect_html = "first div";
+ test_get_element_content_verify (fixture, "", "frst", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "frst", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "frst", FALSE, expect_plain, expect_html);
+
+ expect_html = "<div id=\"frst\">first div</div>";
+ test_get_element_content_verify (fixture, "", "frst", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "", "frst", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "", "frst", TRUE, expect_plain, expect_html);
+
+ expect_plain = "frm1 div";
+ expect_html = "frm1 div";
+ test_get_element_content_verify (fixture, "frm1", "frst", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "frst", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "frst", FALSE, expect_plain, expect_html);
+
+ expect_html = "<div id=\"frst\">frm1 div</div>";
+ test_get_element_content_verify (fixture, "frm1", "frst", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "frst", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "frst", TRUE, expect_plain, expect_html);
+
+ test_get_element_content_verify (fixture, "frm1", "frm1p", FALSE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "frm1p", FALSE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "frm1p", FALSE, expect_plain, expect_html);
+
+ expect_html = "<span id=\"frm1p\"><div id=\"frst\">frm1 div</div></span>";
+ test_get_element_content_verify (fixture, "frm1", "frm1p", TRUE, expect_plain, NULL);
+ test_get_element_content_verify (fixture, "frm1", "frm1p", TRUE, NULL, expect_html);
+ test_get_element_content_verify (fixture, "frm1", "frm1p", TRUE, expect_plain, expect_html);
+}
+
+typedef struct _GetElementFromPoint {
+ TestFixture *fixture;
+ const gchar *expect_iframe_src;
+ const gchar *expect_iframe_id;
+ const gchar *expect_element_id;
+} GetElementFromPoint;
+
+static void
+test_get_element_from_point_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GetElementFromPoint *gefp = user_data;
+ gchar *iframe_src = NULL, *iframe_id = NULL, *element_id = NULL;
+ gboolean success;
+ GError *error = NULL;
+
+ g_assert (WEBKIT_IS_WEB_VIEW (source_object));
+ g_assert_nonnull (gefp);
+
+ success = e_web_view_jsc_get_element_from_point_finish (WEBKIT_WEB_VIEW (source_object), result,
&iframe_src, &iframe_id, &element_id, &error);
+
+ g_assert_no_error (error);
+ g_assert (success);
+
+ g_assert_cmpstr (iframe_src, ==, gefp->expect_iframe_src);
+ g_assert_cmpstr (iframe_id, ==, gefp->expect_iframe_id);
+ g_assert_cmpstr (element_id, ==, gefp->expect_element_id);
+
+ g_free (iframe_src);
+ g_free (iframe_id);
+ g_free (element_id);
+
+ test_flag_set (gefp->fixture->flag);
+}
+
+static void
+test_utils_verify_get_element_from_point (TestFixture *fixture,
+ gint xx,
+ gint yy,
+ const gchar *expect_iframe_src,
+ const gchar *expect_iframe_id,
+ const gchar *expect_element_id)
+{
+ GetElementFromPoint gefp;
+
+ gefp.fixture = fixture;
+ gefp.expect_iframe_src = expect_iframe_src;
+ gefp.expect_iframe_id = expect_iframe_id;
+ gefp.expect_element_id = expect_element_id;
+
+ e_web_view_jsc_get_element_from_point (fixture->web_view, xx, yy, NULL,
test_get_element_from_point_ready_cb, &gefp);
+
+ test_utils_wait (fixture);
+}
+
+static void
+window_size_allocated_cb (GtkWidget *widget,
+ GdkRectangle *allocation,
+ gpointer user_data)
+{
+ TestFixture *fixture = user_data;
+
+ test_flag_set (fixture->flag);
+}
+
+static void
+test_get_element_from_point (TestFixture *fixture)
+{
+ struct _elems {
+ const gchar *iframe_src;
+ const gchar *iframe_id;
+ const gchar *elem_id;
+ } elems[] = {
+ { NULL, "", "btn1" },
+ { NULL, "", "btn3" },
+ { NULL, "", "dots1" },
+ { "empty:///frm1", "frm1", "btn1" },
+ { "empty:///frm1_1", "frm1_1", "btn1" },
+ { "empty:///frm1_1", "frm1_1", "dots2" },
+ { "empty:///frm1_1", "frm1_1", "btn2" },
+ { "empty:///frm2", "frm2", "btn1" },
+ { "empty:///frm2", "frm2", "btn2" }
+ };
+ gchar *script;
+ gint ii, scroll_x, scroll_y, client_width, client_height, tested;
+
+ test_utils_load_body (fixture, LOAD_ALL);
+
+ ii = test_utils_jsc_call_int32_sync (fixture,
+ "function TestGetPosition(iframe_id, elem_id)\n"
+ "{\n"
+ " var elem = Evo.findElement(iframe_id, elem_id);\n"
+ " var xx = 0, yy = 0, off_elem, check_elem;\n"
+ " for (check_elem = elem; check_elem; check_elem =
check_elem.ownerDocument.defaultView.frameElement) {\n"
+ " for (ii = check_elem; ii; ii = ii.parentOffset) {\n"
+ " xx += ii.offsetLeft - ii.scrollLeft;\n"
+ " yy += ii.offsetTop - ii.scrollTop;\n"
+ " }\n"
+ " }\n"
+ " var res = [];\n"
+ " res[\"left\"] = xx + (elem.offsetWidth / 2) - window.scrollX;\n"
+ " res[\"right\"] = xx + elem.offsetWidth - 2 - window.scrollX;\n"
+ " res[\"top\"] = yy + (elem.offsetHeight / 2) - window.scrollY;\n"
+ " return res;"
+ "}\n"
+ "\n"
+ /* To not scroll in the frm1 */
+ "document.getElementById(\"frm1\").height =
document.getElementById(\"frm1\").contentDocument.getElementById(\"btn1\").offsetTop +"
+ " 2 *
document.getElementById(\"frm1\").contentDocument.getElementById(\"btn1\").offsetHeight;\n"
+ "\n"
+ "document.body.scrollHeight;\n");
+
+ /* To not scroll in the overall document */
+ gtk_widget_set_size_request (fixture->window, -1, ii);
+
+ /* Window/widget resize is done asynchronously, thus wait for it */
+ g_signal_connect (fixture->window, "size-allocate",
+ G_CALLBACK (window_size_allocated_cb), fixture);
+
+ test_utils_wait (fixture);
+
+ g_signal_handlers_disconnect_by_func (fixture->window, G_CALLBACK (window_size_allocated_cb),
fixture);
+
+ for (ii = 0; ii < G_N_ELEMENTS (elems); ii++) {
+ const gchar *iframe_src;
+ gchar *script;
+ JSCValue *value;
+ gint xx, yy;
+
+ script = e_web_view_jsc_printf_script ("TestGetPosition(%s, %s);", elems[ii].iframe_id,
elems[ii].elem_id);
+
+ test_utils_jsc_call_sync (fixture, script, &value);
+
+ g_assert_nonnull (value);
+ g_assert (jsc_value_is_object (value));
+
+ xx = e_web_view_jsc_get_object_property_int32 (value, "left", -1);
+ yy = e_web_view_jsc_get_object_property_int32 (value, "top", -1);
+
+ g_assert_cmpint (xx, >, -1);
+ g_assert_cmpint (yy, >, -1);
+
+ g_clear_object (&value);
+ g_free (script);
+
+ iframe_src = elems[ii].iframe_src;
+
+ if (!iframe_src)
+ iframe_src = webkit_web_view_get_uri (fixture->web_view);
+
+ test_utils_verify_get_element_from_point (fixture, xx, yy, iframe_src, elems[ii].iframe_id,
elems[ii].elem_id);
+ }
+
+ test_utils_verify_get_element_from_point (fixture, -1, -1, webkit_web_view_get_uri
(fixture->web_view), "", "");
+
+ test_utils_jsc_call_sync (fixture, "Evo.findIFrameDocument(\"\").getElementById(\"btn3\").focus();",
NULL);
+
+ test_utils_verify_get_element_from_point (fixture, -1, -1, webkit_web_view_get_uri
(fixture->web_view), "", "btn3");
+
+ scroll_x = test_utils_jsc_call_int32_sync (fixture, "document.body.scrollWidth;") / 2;
+ scroll_y = test_utils_jsc_call_int32_sync (fixture, "document.body.scrollHeight;") / 2;
+
+ /* To scroll in the overall document */
+ gtk_widget_set_size_request (fixture->window, -1, -1);
+ gtk_window_resize (GTK_WINDOW (fixture->window), scroll_x, scroll_y);
+
+ /* Window/widget resize is done asynchronously, thus wait for it */
+ g_signal_connect (fixture->window, "size-allocate",
+ G_CALLBACK (window_size_allocated_cb), fixture);
+
+ test_utils_wait (fixture);
+
+ g_signal_handlers_disconnect_by_func (fixture->window, G_CALLBACK (window_size_allocated_cb),
fixture);
+
+ /* Scroll by some value */
+ scroll_x /= 2;
+ scroll_y /= 2;
+ script = e_web_view_jsc_printf_script ("window.scrollBy(%d,%d);", scroll_x, scroll_y);
+ test_utils_jsc_call_sync (fixture, script, NULL);
+ g_free (script);
+
+ test_utils_wait_noop (fixture);
+
+ scroll_x = test_utils_jsc_call_int32_sync (fixture, "window.scrollX;");
+ scroll_y = test_utils_jsc_call_int32_sync (fixture, "window.scrollY;");
+ client_width = test_utils_jsc_call_int32_sync (fixture, "document.body.clientWidth;");
+ client_height = test_utils_jsc_call_int32_sync (fixture, "document.body.clientHeight;");
+
+ tested = 0;
+
+ for (ii = 0; ii < G_N_ELEMENTS (elems); ii++) {
+ const gchar *iframe_src;
+ gchar *script;
+ JSCValue *value;
+ gint xx, yy;
+
+ script = e_web_view_jsc_printf_script ("TestGetPosition(%s, %s);", elems[ii].iframe_id,
elems[ii].elem_id);
+
+ test_utils_jsc_call_sync (fixture, script, &value);
+
+ g_assert_nonnull (value);
+ g_assert (jsc_value_is_object (value));
+
+ xx = e_web_view_jsc_get_object_property_int32 (value, "right", -1);
+ yy = e_web_view_jsc_get_object_property_int32 (value, "top", -1);
+
+ g_clear_object (&value);
+ g_free (script);
+
+ if (xx >= 0 && xx < client_width && yy >= 0 && yy < client_height) {
+ iframe_src = elems[ii].iframe_src;
+
+ if (!iframe_src)
+ iframe_src = webkit_web_view_get_uri (fixture->web_view);
+
+ test_utils_verify_get_element_from_point (fixture, xx, yy, iframe_src,
elems[ii].iframe_id, elems[ii].elem_id);
+
+ tested++;
+ }
+ }
+
+ g_assert_cmpint (tested, >, 0);
+}
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ gint res;
+
+ setlocale (LC_ALL, "");
+
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("https://gitlab.gnome.org/GNOME/evolution/issues/");
+
+ gtk_init (&argc, &argv);
+
+ e_util_init_main_thread (NULL);
+ e_passwords_init ();
+
+ test_utils_add_test ("/EWebView/JSCObjectProperties", test_jsc_object_properties);
+ test_utils_add_test ("/EWebView/SetElementHidden", test_set_element_hidden);
+ test_utils_add_test ("/EWebView/SetElementDisabled", test_set_element_disabled);
+ test_utils_add_test ("/EWebView/SetElementChecked", test_set_element_checked);
+ 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);
+ test_utils_add_test ("/EWebView/ElementClicked", test_element_clicked);
+ test_utils_add_test ("/EWebView/NeedInputChanged", test_need_input_changed);
+ test_utils_add_test ("/EWebView/Selection", test_selection);
+ test_utils_add_test ("/EWebView/GetContent", test_get_content);
+ test_utils_add_test ("/EWebView/GetElementFromPoint", test_get_element_from_point);
+
+ res = g_test_run ();
+
+ e_misc_util_free_global_memory ();
+
+ return res;
+}
diff --git a/src/em-format/CMakeLists.txt b/src/em-format/CMakeLists.txt
index 7b6a3d9b21..4a88b8cf95 100644
--- a/src/em-format/CMakeLists.txt
+++ b/src/em-format/CMakeLists.txt
@@ -113,7 +113,6 @@ add_dependencies(evolution-mail-formatter
target_compile_definitions(evolution-mail-formatter PRIVATE
-DG_LOG_DOMAIN=\"evolution-mail-formatter\"
-DEVOLUTION_IMAGESDIR=\"${imagesdir}\"
- -DEVOLUTION_PRIVDATADIR=\"${privdatadir}\"
)
target_compile_options(evolution-mail-formatter PUBLIC
diff --git a/src/em-format/e-mail-formatter-print.c b/src/em-format/e-mail-formatter-print.c
index 1f6cff2721..d302b17a5e 100644
--- a/src/em-format/e-mail-formatter-print.c
+++ b/src/em-format/e-mail-formatter-print.c
@@ -25,8 +25,7 @@
#include <gdk/gdk.h>
#include <glib/gi18n.h>
-#define STYLESHEET_URI \
- "evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview-print.css"
+#define STYLESHEET_URI "evo-file://$EVOLUTION_WEBKITDATADIR/webview-print.css"
/* internal formatter extensions */
GType e_mail_formatter_print_headers_get_type (void);
diff --git a/src/em-format/e-mail-formatter.c b/src/em-format/e-mail-formatter.c
index ce738a85e2..fb88f875ff 100644
--- a/src/em-format/e-mail-formatter.c
+++ b/src/em-format/e-mail-formatter.c
@@ -36,8 +36,7 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_MAIL_FORMATTER, EMailFormatterPrivate))
-#define STYLESHEET_URI \
- "evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css"
+#define STYLESHEET_URI "evo-file://$EVOLUTION_WEBKITDATADIR/webview.css"
typedef struct _AsyncContext AsyncContext;
diff --git a/src/em-format/e-mail-part-headers.c b/src/em-format/e-mail-part-headers.c
index 7f5a9b2a62..a08730bed1 100644
--- a/src/em-format/e-mail-part-headers.c
+++ b/src/em-format/e-mail-part-headers.c
@@ -207,28 +207,10 @@ mail_part_headers_constructed (GObject *object)
e_mail_part_set_mime_type (part, E_MAIL_PART_HEADERS_MIME_TYPE);
}
-static void
-mail_part_headers_bind_dom_element (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id)
-{
- GDBusProxy *web_extension = e_web_view_get_web_extension_proxy (web_view);
-
- if (web_extension) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- web_extension,
- "EMailPartHeadersBindDOMElement",
- g_variant_new ("(ts)", page_id, element_id),
- NULL);
- }
-}
-
static void
e_mail_part_headers_class_init (EMailPartHeadersClass *class)
{
GObjectClass *object_class;
- EMailPartClass *mail_part_class;
g_type_class_add_private (class, sizeof (EMailPartHeadersPrivate));
@@ -239,9 +221,6 @@ e_mail_part_headers_class_init (EMailPartHeadersClass *class)
object_class->finalize = mail_part_headers_finalize;
object_class->constructed = mail_part_headers_constructed;
- mail_part_class = E_MAIL_PART_CLASS (class);
- mail_part_class->bind_dom_element = mail_part_headers_bind_dom_element;
-
g_object_class_install_property (
object_class,
PROP_DEFAULT_HEADERS,
diff --git a/src/em-format/e-mail-part-secure-button.c b/src/em-format/e-mail-part-secure-button.c
index 4719448e16..a224376257 100644
--- a/src/em-format/e-mail-part-secure-button.c
+++ b/src/em-format/e-mail-part-secure-button.c
@@ -324,6 +324,8 @@ secure_button_show_validity_dialog (EWebView *web_view,
static void
secure_button_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
const gchar *element_class,
const gchar *element_value,
const GtkAllocation *element_position,
@@ -364,8 +366,8 @@ secure_button_clicked_cb (EWebView *web_view,
}
static void
-mail_part_secure_button_web_view_loaded (EMailPart *mail_part,
- EWebView *web_view)
+mail_part_secure_button_content_loaded (EMailPart *mail_part,
+ EWebView *web_view)
{
g_return_if_fail (E_IS_MAIL_PART_SECURE_BUTTON (mail_part));
g_return_if_fail (E_IS_WEB_VIEW (web_view));
@@ -379,7 +381,7 @@ e_mail_part_secure_button_class_init (EMailPartSecureButtonClass *class)
EMailPartClass *mail_part_class;
mail_part_class = E_MAIL_PART_CLASS (class);
- mail_part_class->web_view_loaded = mail_part_secure_button_web_view_loaded;
+ mail_part_class->content_loaded = mail_part_secure_button_content_loaded;
}
static void
diff --git a/src/em-format/e-mail-part.c b/src/em-format/e-mail-part.c
index 4fccd77168..9a2e1ae179 100644
--- a/src/em-format/e-mail-part.c
+++ b/src/em-format/e-mail-part.c
@@ -631,39 +631,19 @@ e_mail_part_set_is_printable (EMailPart *part,
}
void
-e_mail_part_bind_dom_element (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id)
+e_mail_part_content_loaded (EMailPart *part,
+ EWebView *web_view)
{
EMailPartClass *class;
g_return_if_fail (E_IS_MAIL_PART (part));
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- g_return_if_fail (page_id != 0);
- g_return_if_fail (element_id && *element_id);
class = E_MAIL_PART_GET_CLASS (part);
g_return_if_fail (class != NULL);
- if (class->bind_dom_element != NULL)
- class->bind_dom_element (part, web_view, page_id, element_id);
-}
-
-void
-e_mail_part_web_view_loaded (EMailPart *part,
- EWebView *web_view)
-{
- EMailPartClass *klass;
-
- g_return_if_fail (E_IS_MAIL_PART (part));
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- klass = E_MAIL_PART_GET_CLASS (part);
- g_return_if_fail (klass != NULL);
-
- if (klass->web_view_loaded)
- klass->web_view_loaded (part, web_view);
+ if (class->content_loaded)
+ class->content_loaded (part, web_view);
}
static EMailPartValidityPair *
diff --git a/src/em-format/e-mail-part.h b/src/em-format/e-mail-part.h
index b872119979..8d2c8122c1 100644
--- a/src/em-format/e-mail-part.h
+++ b/src/em-format/e-mail-part.h
@@ -85,11 +85,7 @@ struct _EMailPart {
struct _EMailPartClass {
GObjectClass parent_class;
- void (*bind_dom_element) (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id);
- void (*web_view_loaded) (EMailPart *part,
+ void (*content_loaded) (EMailPart *part,
EWebView *web_view);
};
@@ -126,11 +122,7 @@ void e_mail_part_set_is_attachment (EMailPart *part,
gboolean e_mail_part_get_is_printable (EMailPart *part);
void e_mail_part_set_is_printable (EMailPart *part,
gboolean is_printable);
-void e_mail_part_bind_dom_element (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id);
-void e_mail_part_web_view_loaded (EMailPart *part,
+void e_mail_part_content_loaded (EMailPart *part,
EWebView *web_view);
void e_mail_part_update_validity (EMailPart *part,
CamelCipherValidity *validity,
diff --git a/src/mail/e-mail-display-popup-extension.c b/src/mail/e-mail-display-popup-extension.c
index 2f9e91948e..b199f4f249 100644
--- a/src/mail/e-mail-display-popup-extension.c
+++ b/src/mail/e-mail-display-popup-extension.c
@@ -33,14 +33,16 @@ e_mail_display_popup_extension_default_init (EMailDisplayPopupExtensionInterface
* e_mail_display_popup_extension_update_actions:
*
* @extension: An object derived from #EMailDisplayPopupExtension
- * @popup_document_uri: Document URI on top of which the popup menu had been invoked
+ * @popup_iframe_src: iframe source URI on top of which the popup menu had been invoked
+ * @popup_iframe_id: iframe ID on top of which the popup menu had been invoked
*
* When #EMailDisplay is about to display a popup menu, it calls this function
* on every extension so that they can add their items to the menu.
*/
void
e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *extension,
- const gchar *popup_document_uri)
+ const gchar *popup_iframe_src,
+ const gchar *popup_iframe_id)
{
EMailDisplayPopupExtensionInterface *iface;
@@ -49,5 +51,5 @@ e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *exten
iface = E_MAIL_DISPLAY_POPUP_EXTENSION_GET_INTERFACE (extension);
g_return_if_fail (iface->update_actions != NULL);
- iface->update_actions (extension, popup_document_uri);
+ iface->update_actions (extension, popup_iframe_src, popup_iframe_id);
}
diff --git a/src/mail/e-mail-display-popup-extension.h b/src/mail/e-mail-display-popup-extension.h
index bedd23ed7d..3ea5b1d3c5 100644
--- a/src/mail/e-mail-display-popup-extension.h
+++ b/src/mail/e-mail-display-popup-extension.h
@@ -48,14 +48,16 @@ struct _EMailDisplayPopupExtensionInterface {
GTypeInterface parent_interface;
void (*update_actions) (EMailDisplayPopupExtension *extension,
- const gchar *popup_document_uri);
+ const gchar *popup_iframe_src,
+ const gchar *popup_iframe_id);
};
GType e_mail_display_popup_extension_get_type (void);
void e_mail_display_popup_extension_update_actions
(EMailDisplayPopupExtension *extension,
- const gchar *popup_document_uri);
+ const gchar *popup_iframe_src,
+ const gchar *popup_iframe_id);
G_END_DECLS
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index 76e2c9189a..c343f32ddd 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -44,8 +44,6 @@
#include "em-composer-utils.h"
#include "em-utils.h"
-#include "web-extensions/e-web-extension-names.h"
-
#include "e-mail-display.h"
#define d(x)
@@ -59,6 +57,11 @@ typedef enum {
E_ATTACHMENT_FLAG_ZOOMED_TO_100 = (1 << 1)
} EAttachmentFlags;
+typedef enum {
+ E_MAGIC_SPACEBAR_CAN_GO_BOTTOM = (1 << 0),
+ E_MAGIC_SPACEBAR_CAN_GO_TOP = (1 << 1)
+} EMagicSpacebarFlags;
+
struct _EMailDisplayPrivate {
EAttachmentStore *attachment_store;
EAttachmentView *attachment_view;
@@ -85,9 +88,7 @@ struct _EMailDisplayPrivate {
EMailRemoteContent *remote_content;
GHashTable *skipped_remote_content_sites;
- GDBusConnection *web_extension_connection;
- guint web_extension_headers_collapsed_signal_id;
- guint web_extension_mail_part_appeared_signal_id;
+ guint32 magic_spacebar_state; /* bit-or of EMagicSpacebarFlags */
};
enum {
@@ -399,9 +400,10 @@ decide_policy_cb (WebKitWebView *web_view,
}
static void
-add_color_css_rule_for_web_view (EWebView *view,
- const gchar *color_name,
- const gchar *color_value)
+add_color_css_rule_for_web_view (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *color_name,
+ const gchar *color_value)
{
gchar *selector;
gchar *style;
@@ -419,18 +421,21 @@ add_color_css_rule_for_web_view (EWebView *view,
"background-color: ", color_value, " !important;", NULL);
}
- e_web_view_add_css_rule_into_style_sheet (
- view,
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (web_view),
+ iframe_id,
"-e-mail-formatter-style-sheet",
selector,
- style);
+ style,
+ e_web_view_get_cancellable (web_view));
g_free (style);
g_free (selector);
}
static void
-initialize_web_view_colors (EMailDisplay *display)
+initialize_web_view_colors (EMailDisplay *display,
+ const gchar *iframe_id)
{
EMailFormatter *formatter;
GtkTextDirection direction;
@@ -456,6 +461,7 @@ initialize_web_view_colors (EMailDisplay *display)
add_color_css_rule_for_web_view (
E_WEB_VIEW (display),
+ iframe_id,
color_names[ii],
color_value);
@@ -463,11 +469,13 @@ initialize_web_view_colors (EMailDisplay *display)
g_free (color_value);
}
- e_web_view_add_css_rule_into_style_sheet (
- E_WEB_VIEW (display),
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (display),
+ iframe_id,
"-e-mail-formatter-style-sheet",
".-e-mail-formatter-frame-security-none",
- "border-width: 1px; border-style: solid");
+ "border-width: 1px; border-style: solid",
+ e_web_view_get_cancellable (E_WEB_VIEW (display)));
/* the rgba values below were copied from e-formatter-secure-button */
direction = gtk_widget_get_default_direction ();
@@ -476,168 +484,49 @@ initialize_web_view_colors (EMailDisplay *display)
style = "border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgba(53%, 73%,
53%, 1.0)";
else
style = "border-width: 1px 4px 1px 1px; border-style: solid; border-color: rgba(53%, 73%,
53%, 1.0)";
- e_web_view_add_css_rule_into_style_sheet (
- E_WEB_VIEW (display),
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (display),
+ iframe_id,
"-e-mail-formatter-style-sheet",
".-e-mail-formatter-frame-security-good",
- style);
+ style,
+ e_web_view_get_cancellable (E_WEB_VIEW (display)));
if (direction == GTK_TEXT_DIR_RTL)
style = "border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgba(73%, 53%,
53%, 1.0)";
else
style = "border-width: 1px 4px 1px 1px; border-style: solid; border-color: rgba(73%, 53%,
53%, 1.0)";
- e_web_view_add_css_rule_into_style_sheet (
- E_WEB_VIEW (display),
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (display),
+ iframe_id,
"-e-mail-formatter-style-sheet",
".-e-mail-formatter-frame-security-bad",
- style);
+ style,
+ e_web_view_get_cancellable (E_WEB_VIEW (display)));
if (direction == GTK_TEXT_DIR_RTL)
style = "border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgba(91%, 82%,
13%, 1.0)";
else
style = "border-width: 1px 4px 1px 1px; border-style: solid; border-color: rgba(91%, 82%,
13%, 1.0)";
- e_web_view_add_css_rule_into_style_sheet (
- E_WEB_VIEW (display),
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (display),
+ iframe_id,
"-e-mail-formatter-style-sheet",
".-e-mail-formatter-frame-security-unknown",
- style);
+ style,
+ e_web_view_get_cancellable (E_WEB_VIEW (display)));
if (direction == GTK_TEXT_DIR_RTL)
style = "border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgba(91%, 82%,
13%, 1.0)";
else
style = "border-width: 1px 4px 1px 1px; border-style: solid; border-color: rgba(91%, 82%,
13%, 1.0)";
- e_web_view_add_css_rule_into_style_sheet (
- E_WEB_VIEW (display),
+ e_web_view_jsc_add_rule_into_style_sheet (
+ WEBKIT_WEB_VIEW (display),
+ iframe_id,
"-e-mail-formatter-style-sheet",
".-e-mail-formatter-frame-security-need-key",
- style);
-}
-
-static void
-headers_collapsed_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- EMailDisplay *display)
-{
- gboolean collapsed = FALSE;
-
- if (g_strcmp0 (signal_name, "HeadersCollapsed") != 0)
- return;
-
- if (parameters)
- g_variant_get (parameters, "(b)", &collapsed);
-
- e_mail_display_set_headers_collapsed (display, collapsed);
-}
-
-static void
-mail_display_mail_part_appeared_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- EMailDisplay *display = user_data;
- GDBusProxy *web_extension;
- const gchar *part_id = NULL;
- guint64 page_id = 0;
- EMailPart *part;
-
- if (g_strcmp0 (signal_name, "MailPartAppeared") != 0)
- return;
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- if (!parameters || !display->priv->part_list)
- return;
-
- g_variant_get (parameters, "(t&s)", &page_id, &part_id);
-
- if (!part_id || !*part_id || page_id != webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display)))
- return;
-
- part = e_mail_part_list_ref_part (display->priv->part_list, part_id);
- if (part && g_strcmp0 (e_mail_part_get_id (part), part_id) == 0) {
- e_mail_part_bind_dom_element (part, E_WEB_VIEW (display), page_id, part_id);
- }
-
- g_clear_object (&part);
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
- if (web_extension) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- web_extension,
- "EMailDisplayBindDOM",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display))),
- NULL);
- }
-}
-
-static void
-setup_dom_bindings (EMailDisplay *display)
-{
- GDBusProxy *web_extension;
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
-
- if (display->priv->web_extension_connection) {
- if (display->priv->web_extension_headers_collapsed_signal_id) {
- g_dbus_connection_signal_unsubscribe (display->priv->web_extension_connection,
display->priv->web_extension_headers_collapsed_signal_id);
- display->priv->web_extension_headers_collapsed_signal_id = 0;
- }
-
- if (display->priv->web_extension_mail_part_appeared_signal_id) {
- g_dbus_connection_signal_unsubscribe (display->priv->web_extension_connection,
display->priv->web_extension_mail_part_appeared_signal_id);
- display->priv->web_extension_mail_part_appeared_signal_id = 0;
- }
-
- g_clear_object (&display->priv->web_extension_connection);
- }
-
- if (web_extension) {
- display->priv->web_extension_connection = g_object_ref (g_dbus_proxy_get_connection
(web_extension));
-
- display->priv->web_extension_headers_collapsed_signal_id =
- g_dbus_connection_signal_subscribe (
- display->priv->web_extension_connection,
- g_dbus_proxy_get_name (web_extension),
- E_WEB_EXTENSION_INTERFACE,
- "HeadersCollapsed",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback) headers_collapsed_signal_cb,
- display,
- NULL);
-
- display->priv->web_extension_mail_part_appeared_signal_id =
- g_dbus_connection_signal_subscribe (
- display->priv->web_extension_connection,
- g_dbus_proxy_get_name (web_extension),
- E_WEB_EXTENSION_INTERFACE,
- "MailPartAppeared",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- mail_display_mail_part_appeared_signal_cb,
- display,
- NULL);
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- web_extension,
- "EMailDisplayBindDOM",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display))),
- NULL);
- }
+ style,
+ e_web_view_get_cancellable (E_WEB_VIEW (display)));
}
static void
@@ -668,7 +557,9 @@ mail_display_change_one_attachment_visibility (EMailDisplay *display,
g_hash_table_insert (display->priv->attachment_flags, attachment, GUINT_TO_POINTER (flags));
element_id = g_strdup_printf ("attachment-wrapper-%p", attachment);
- e_web_view_set_element_hidden (E_WEB_VIEW (display), element_id, !show);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (display), e_web_view_get_cancellable (E_WEB_VIEW
(display)),
+ "Evo.MailDisplayShowAttachment(%s,%x);",
+ element_id, show);
g_free (element_id);
element_id = g_strdup_printf ("attachment-expander-img-%p", attachment);
@@ -749,7 +640,7 @@ mail_attachment_change_zoom (EMailDisplay *display,
element_id = g_strdup_printf ("attachment-wrapper-%p::child", attachment);
- e_web_view_set_element_style_property (E_WEB_VIEW (display), element_id, "max-width",
max_width, "");
+ e_web_view_set_element_style_property (E_WEB_VIEW (display), element_id, "max-width",
max_width);
g_free (element_id);
}
@@ -916,6 +807,8 @@ call_attachment_save_handle_error (GObject *source_object,
static void
mail_display_attachment_expander_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
const gchar *element_class,
const gchar *element_value,
const GtkAllocation *element_position,
@@ -1099,6 +992,8 @@ mail_display_attachment_select_path (EAttachmentView *view,
static void
mail_display_attachment_menu_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
const gchar *element_class,
const gchar *element_value,
const GtkAllocation *element_position,
@@ -1181,154 +1076,74 @@ mail_display_attachment_removed_cb (EAttachmentStore *store,
g_hash_table_remove (display->priv->attachment_flags, attachment);
}
-typedef struct _MailElementExistsData {
- EWebView *web_view;
- EMailPart *part;
-} MailElementExistsData;
-
static void
-mail_element_exists_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GDBusProxy *web_extension;
- MailElementExistsData *meed = user_data;
- gboolean element_exists = FALSE;
- GVariant *result_variant;
- guint64 page_id;
- GError *error = NULL;
-
- g_return_if_fail (G_IS_DBUS_PROXY (source_object));
- g_return_if_fail (meed != NULL);
-
- web_extension = G_DBUS_PROXY (source_object);
-
- result_variant = g_dbus_proxy_call_finish (web_extension, result, &error);
- if (result_variant) {
- g_variant_get (result_variant, "(bt)", &element_exists, &page_id);
- g_variant_unref (result_variant);
- }
-
- if (element_exists)
- e_mail_part_bind_dom_element (
- meed->part,
- meed->web_view,
- page_id,
- e_mail_part_get_id (meed->part));
+mail_display_load_changed_cb (WebKitWebView *wk_web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
+{
+ EMailDisplay *display;
- g_object_unref (meed->web_view);
- g_object_unref (meed->part);
- g_free (meed);
+ g_return_if_fail (E_IS_MAIL_DISPLAY (wk_web_view));
- if (error)
- g_dbus_error_strip_remote_error (error);
+ display = E_MAIL_DISPLAY (wk_web_view);
- e_util_claim_dbus_proxy_call_error (web_extension, "ElementExists", error);
- g_clear_error (&error);
+ if (load_event == WEBKIT_LOAD_STARTED) {
+ display->priv->magic_spacebar_state = 0;
+ e_mail_display_cleanup_skipped_uris (display);
+ e_attachment_store_remove_all (display->priv->attachment_store);
+ }
}
static void
-mail_parts_bind_dom (EMailDisplay *display)
+mail_display_content_loaded_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ gpointer user_data)
{
- EWebView *web_view;
- GQueue queue = G_QUEUE_INIT;
- GList *head, *link;
- GDBusProxy *web_extension;
- gboolean has_attachment = FALSE;
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+ EMailDisplay *mail_display;
- if (display->priv->part_list == NULL)
- return;
-
- initialize_web_view_colors (display);
-
- web_view = E_WEB_VIEW (display);
-
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (!web_extension)
- return;
-
- e_mail_part_list_queue_parts (display->priv->part_list, NULL, &queue);
- head = g_queue_peek_head_link (&queue);
-
- for (link = head; link != NULL; link = g_list_next (link)) {
- MailElementExistsData *meed;
- EMailPart *part = E_MAIL_PART (link->data);
- const gchar *part_id;
-
- part_id = e_mail_part_get_id (part);
-
- has_attachment = has_attachment || E_IS_MAIL_PART_ATTACHMENT (part);
+ g_return_if_fail (E_IS_MAIL_DISPLAY (web_view));
- e_mail_part_web_view_loaded (part, web_view);
+ mail_display = E_MAIL_DISPLAY (web_view);
- meed = g_new0 (MailElementExistsData, 1);
- meed->web_view = g_object_ref (web_view);
- meed->part = g_object_ref (part);
+ initialize_web_view_colors (mail_display, iframe_id);
- g_dbus_proxy_call (
- web_extension,
- "ElementExists",
- g_variant_new (
- "(ts)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (display)),
- part_id),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- mail_element_exists_cb,
- meed);
- }
-
- while (!g_queue_is_empty (&queue))
- g_object_unref (g_queue_pop_head (&queue));
-
- if (has_attachment) {
+ if (!iframe_id || !*iframe_id) {
e_web_view_register_element_clicked (web_view, "attachment-expander",
mail_display_attachment_expander_clicked_cb, NULL);
e_web_view_register_element_clicked (web_view, "attachment-menu",
mail_display_attachment_menu_clicked_cb, NULL);
}
-}
-static void
-mail_display_load_changed_cb (WebKitWebView *wk_web_view,
- WebKitLoadEvent load_event,
- gpointer user_data)
-{
- EMailDisplay *display;
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "Evo.MailDisplayBindDOM(%s);", iframe_id);
- g_return_if_fail (E_IS_MAIL_DISPLAY (wk_web_view));
+ if (mail_display->priv->part_list) {
+ if (!iframe_id || !*iframe_id) {
+ GQueue queue = G_QUEUE_INIT;
+ GList *head, *link;
- display = E_MAIL_DISPLAY (wk_web_view);
+ e_mail_part_list_queue_parts (mail_display->priv->part_list, NULL, &queue);
+ head = g_queue_peek_head_link (&queue);
- if (load_event == WEBKIT_LOAD_STARTED) {
- e_mail_display_cleanup_skipped_uris (display);
- e_attachment_store_remove_all (display->priv->attachment_store);
- return;
- }
+ for (link = head; link; link = g_list_next (link)) {
+ EMailPart *part = E_MAIL_PART (link->data);
- if (load_event == WEBKIT_LOAD_FINISHED) {
- setup_dom_bindings (display);
- mail_parts_bind_dom (display);
- }
-}
+ e_mail_part_content_loaded (part, web_view);
+ }
-static void
-mail_display_web_extension_proxy_notify_cb (GObject *object,
- GParamSpec *param,
- gpointer user_data)
-{
- EMailDisplay *display;
+ while (!g_queue_is_empty (&queue))
+ g_object_unref (g_queue_pop_head (&queue));
+ } else {
+ EMailPart *part;
- g_return_if_fail (E_IS_MAIL_DISPLAY (object));
+ part = e_mail_part_list_ref_part (mail_display->priv->part_list, iframe_id);
- display = E_MAIL_DISPLAY (object);
+ if (part)
+ e_mail_part_content_loaded (part, web_view);
- setup_dom_bindings (display);
- mail_parts_bind_dom (display);
+ g_clear_object (&part);
+ }
+ }
}
static void
@@ -1457,20 +1272,6 @@ mail_display_dispose (GObject *object)
0, 0, NULL, NULL, object);
}
- if (priv->web_extension_connection) {
- if (priv->web_extension_headers_collapsed_signal_id) {
- g_dbus_connection_signal_unsubscribe (priv->web_extension_connection,
priv->web_extension_headers_collapsed_signal_id);
- priv->web_extension_headers_collapsed_signal_id = 0;
- }
-
- if (priv->web_extension_mail_part_appeared_signal_id) {
- g_dbus_connection_signal_unsubscribe (priv->web_extension_connection,
priv->web_extension_mail_part_appeared_signal_id);
- priv->web_extension_mail_part_appeared_signal_id = 0;
- }
-
- g_clear_object (&priv->web_extension_connection);
- }
-
if (priv->attachment_store) {
/* To have called the mail_display_attachment_removed_cb() before it's disconnected */
e_attachment_store_remove_all (priv->attachment_store);
@@ -1562,31 +1363,54 @@ mail_display_set_fonts (EWebView *web_view,
}
static void
-mail_display_web_view_initialize (WebKitWebView *web_view)
+mail_display_headers_collapsed_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
{
- WebKitSettings *webkit_settings;
+ EMailDisplay *mail_display = user_data;
+ JSCValue *jsc_value;
- webkit_settings = webkit_web_view_get_settings (web_view);
+ g_return_if_fail (mail_display != NULL);
+ g_return_if_fail (js_result != NULL);
- g_object_set (webkit_settings,
- "enable-frame-flattening", TRUE,
- NULL);
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_boolean (jsc_value));
+
+ e_mail_display_set_headers_collapsed (mail_display, jsc_value_to_boolean (jsc_value));
+}
+
+static void
+mail_display_magic_spacebar_state_changed_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ EMailDisplay *mail_display = user_data;
+ JSCValue *jsc_value;
+
+ g_return_if_fail (mail_display != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_number (jsc_value));
+
+ mail_display->priv->magic_spacebar_state = jsc_value_to_int32 (jsc_value);
}
static void
mail_display_constructed (GObject *object)
{
EContentRequest *content_request;
+ WebKitUserContentManager *manager;
EWebView *web_view;
EMailDisplay *display;
GtkUIManager *ui_manager;
- e_extensible_load_extensions (E_EXTENSIBLE (object));
-
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_display_parent_class)->constructed (object);
- mail_display_web_view_initialize (WEBKIT_WEB_VIEW (object));
+ g_object_set (webkit_web_view_get_settings (WEBKIT_WEB_VIEW (object)),
+ "enable-frame-flattening", TRUE,
+ NULL);
display = E_MAIL_DISPLAY (object);
web_view = E_WEB_VIEW (object);
@@ -1625,6 +1449,19 @@ mail_display_constructed (GObject *object)
g_clear_error (&error);
}
}
+
+ manager = webkit_web_view_get_user_content_manager (WEBKIT_WEB_VIEW (object));
+
+ g_signal_connect_object (manager, "script-message-received::mailDisplayHeadersCollapsed",
+ G_CALLBACK (mail_display_headers_collapsed_cb), display, 0);
+
+ g_signal_connect_object (manager, "script-message-received::mailDisplayMagicSpacebarStateChanged",
+ G_CALLBACK (mail_display_magic_spacebar_state_changed_cb), display, 0);
+
+ webkit_user_content_manager_register_script_message_handler (manager, "mailDisplayHeadersCollapsed");
+ webkit_user_content_manager_register_script_message_handler (manager,
"mailDisplayMagicSpacebarStateChanged");
+
+ e_extensible_load_extensions (E_EXTENSIBLE (object));
}
static void
@@ -1648,38 +1485,33 @@ mail_display_style_updated (GtkWidget *widget)
style_updated (widget);
}
-static gboolean
-mail_display_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+mail_display_before_popup_event (EWebView *web_view,
+ const gchar *uri)
{
- if (event->button == 3) {
- EWebView *web_view = E_WEB_VIEW (widget);
- gchar *popup_document_uri;
- GList *list, *link;
+ gchar *popup_iframe_src = NULL, *popup_iframe_id = NULL;
+ GList *list, *link;
- popup_document_uri = e_web_view_get_document_uri_from_point (web_view, event->x, event->y);
+ e_web_view_get_last_popup_place (web_view, &popup_iframe_src, &popup_iframe_id, NULL, NULL);
- list = e_extensible_list_extensions (
- E_EXTENSIBLE (web_view), E_TYPE_EXTENSION);
- for (link = list; link != NULL; link = g_list_next (link)) {
- EExtension *extension = link->data;
+ list = e_extensible_list_extensions (E_EXTENSIBLE (web_view), E_TYPE_EXTENSION);
- if (!E_IS_MAIL_DISPLAY_POPUP_EXTENSION (extension))
- continue;
+ for (link = list; link; link = g_list_next (link)) {
+ EExtension *extension = link->data;
- e_mail_display_popup_extension_update_actions (
- E_MAIL_DISPLAY_POPUP_EXTENSION (extension), popup_document_uri);
- }
+ if (!E_IS_MAIL_DISPLAY_POPUP_EXTENSION (extension))
+ continue;
- g_list_free (list);
- g_free (popup_document_uri);
+ e_mail_display_popup_extension_update_actions (E_MAIL_DISPLAY_POPUP_EXTENSION (extension),
popup_iframe_src, popup_iframe_id);
}
- /* Chain up to parent's button_press_event() method. */
- return GTK_WIDGET_CLASS (e_mail_display_parent_class)->
- button_press_event (widget, event);
-}
+ g_free (popup_iframe_src);
+ g_free (popup_iframe_id);
+ g_list_free (list);
+ /* Chain up to parent's method. */
+ E_WEB_VIEW_CLASS (e_mail_display_parent_class)->before_popup_event (web_view, uri);
+}
static gboolean
mail_display_image_exists_in_cache (const gchar *image_uri)
@@ -2127,11 +1959,11 @@ e_mail_display_class_init (EMailDisplayClass *class)
widget_class = GTK_WIDGET_CLASS (class);
widget_class->realize = mail_display_realize;
widget_class->style_updated = mail_display_style_updated;
- widget_class->button_press_event = mail_display_button_press_event;
web_view_class = E_WEB_VIEW_CLASS (class);
web_view_class->suggest_filename = mail_display_suggest_filename;
web_view_class->set_fonts = mail_display_set_fonts;
+ web_view_class->before_popup_event = mail_display_before_popup_event;
g_object_class_install_property (
object_class,
@@ -2283,6 +2115,10 @@ e_mail_display_init (EMailDisplay *display)
display, "load-changed",
G_CALLBACK (mail_display_load_changed_cb), NULL);
+ g_signal_connect (
+ display, "content-loaded",
+ G_CALLBACK (mail_display_content_loaded_cb), NULL);
+
actions = e_web_view_get_action_group (E_WEB_VIEW (display), "mailto");
gtk_action_group_add_actions (
actions, mailto_entries,
@@ -2316,9 +2152,6 @@ e_mail_display_init (EMailDisplay *display)
g_clear_error (&error);
}
}
-
- g_signal_connect (display, "notify::web-extension-proxy",
- G_CALLBACK (mail_display_web_extension_proxy_notify_cb), NULL);
}
static void
@@ -2338,6 +2171,7 @@ e_mail_display_update_colors (EMailDisplay *display,
add_color_css_rule_for_web_view (
E_WEB_VIEW (display),
+ "*",
param_spec->name,
color_value);
@@ -2762,90 +2596,6 @@ e_mail_display_set_status (EMailDisplay *display,
g_free (str);
}
-gchar *
-e_mail_display_get_selection_content_multipart_sync (EMailDisplay *display,
- gboolean *is_html,
- GCancellable *cancellable,
- GError **error)
-{
- GDBusProxy *web_extension;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- if (!e_web_view_is_selection_active (E_WEB_VIEW (display)))
- return NULL;
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetSelectionContentMultipart",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (display))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
-
- if (result) {
- gchar *content = NULL;
- gboolean text_html = FALSE;
-
- g_variant_get (result, "(sb)", &content, &text_html);
- g_variant_unref (result);
- if (is_html)
- *is_html = text_html;
- return content;
- }
- }
-
- return NULL;
-}
-
-gchar *
-e_mail_display_get_selection_plain_text_sync (EMailDisplay *display,
- GCancellable *cancellable,
- GError **error)
-{
- GDBusProxy *web_extension;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- if (!e_web_view_is_selection_active (E_WEB_VIEW (display)))
- return NULL;
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
- if (web_extension) {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "GetSelectionContentText",
- g_variant_new (
- "(t)",
- webkit_web_view_get_page_id (
- WEBKIT_WEB_VIEW (display))),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
-
- if (result) {
- gchar *text;
-
- g_variant_get (result, "(s)", &text);
- g_variant_unref (result);
- return text;
- }
- }
-
- return NULL;
-}
-
void
e_mail_display_load_images (EMailDisplay *display)
{
@@ -2947,36 +2697,15 @@ gboolean
e_mail_display_process_magic_spacebar (EMailDisplay *display,
gboolean towards_bottom)
{
- GDBusProxy *web_extension;
- GVariant *result;
- GError *local_error = NULL;
- gboolean processed = FALSE;
-
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
- if (!web_extension)
+ if ((towards_bottom && !(display->priv->magic_spacebar_state & E_MAGIC_SPACEBAR_CAN_GO_BOTTOM)) ||
+ (!towards_bottom && !(display->priv->magic_spacebar_state & E_MAGIC_SPACEBAR_CAN_GO_TOP)))
return FALSE;
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
- web_extension,
- "ProcessMagicSpacebar",
- g_variant_new ("(tb)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display)),
towards_bottom),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &local_error);
-
- if (local_error)
- g_dbus_error_strip_remote_error (local_error);
-
- e_util_claim_dbus_proxy_call_error (web_extension, "ProcessMagicSpacebar", local_error);
- g_clear_error (&local_error);
-
- if (result) {
- g_variant_get (result, "(b)", &processed);
- g_variant_unref (result);
- }
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (display), e_web_view_get_cancellable (E_WEB_VIEW
(display)),
+ "Evo.MailDisplayProcessMagicSpacebar(%x);",
+ towards_bottom);
- return processed;
+ return TRUE;
}
diff --git a/src/mail/e-mail-display.h b/src/mail/e-mail-display.h
index ed02f189e5..cacf64e2d5 100644
--- a/src/mail/e-mail-display.h
+++ b/src/mail/e-mail-display.h
@@ -94,15 +94,6 @@ GtkAction * e_mail_display_get_action (EMailDisplay *display,
const gchar *action_name);
void e_mail_display_set_status (EMailDisplay *display,
const gchar *status);
-gchar * e_mail_display_get_selection_content_multipart_sync
- (EMailDisplay *display,
- gboolean *is_html,
- GCancellable *cancellable,
- GError **error);
-gchar * e_mail_display_get_selection_plain_text_sync
- (EMailDisplay *display,
- GCancellable *cancellable,
- GError **error);
void e_mail_display_load_images (EMailDisplay *display);
void e_mail_display_set_force_load_images
(EMailDisplay *display,
diff --git a/src/mail/e-mail-reader-utils.c b/src/mail/e-mail-reader-utils.c
index 997bc93570..8b0c95aab7 100644
--- a/src/mail/e-mail-reader-utils.c
+++ b/src/mail/e-mail-reader-utils.c
@@ -2615,10 +2615,12 @@ mail_reader_reply_to_message_composer_created_cb (GObject *source_object,
create_composer_data_free (ccd);
}
-void
-e_mail_reader_reply_to_message (EMailReader *reader,
- CamelMimeMessage *src_message,
- EMailReplyType reply_type)
+static void
+e_mail_reader_reply_to_message_with_selection (EMailReader *reader,
+ CamelMimeMessage *src_message,
+ EMailReplyType reply_type,
+ const gchar *selection,
+ gboolean selection_is_html)
{
EShell *shell;
EMailBackend *backend;
@@ -2626,17 +2628,14 @@ e_mail_reader_reply_to_message (EMailReader *reader,
EMailDisplay *display;
EMailPartList *part_list = NULL;
GtkWidget *message_list;
- CamelContentType *content_type;
CamelMimeMessage *new_message;
CamelInternetAddress *address = NULL;
CamelFolder *folder;
EMailReplyStyle reply_style;
EWebView *web_view;
- gboolean src_is_text_html = FALSE;
const CamelNameValueArray *headers;
guint ii, len;
const gchar *uid;
- gchar *selection = NULL;
gint length;
gchar *mail_uri;
CamelObjectBag *registry;
@@ -2734,34 +2733,17 @@ e_mail_reader_reply_to_message (EMailReader *reader,
g_clear_object (&part_list);
- if (!e_web_view_is_selection_active (web_view))
+ if (!e_web_view_has_selection (web_view))
goto whole_message;
- content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (src_message));
-
- if (camel_content_type_is (content_type, "text", "plain")) {
- selection = e_mail_display_get_selection_plain_text_sync (display, NULL, NULL);
- src_is_text_html = FALSE;
- } else if (camel_content_type_is (content_type, "text", "html")) {
- selection = e_web_view_get_selection_content_html_sync (E_WEB_VIEW (display), NULL, NULL);
- src_is_text_html = TRUE;
- } else {
- selection = e_mail_display_get_selection_content_multipart_sync (display, &src_is_text_html,
NULL, NULL);
- }
-
if (selection == NULL || *selection == '\0')
goto whole_message;
length = strlen (selection);
- if ((src_is_text_html && !html_contains_nonwhitespace (selection, length)) ||
- (!src_is_text_html && !plaintext_contains_nonwhitespace (selection, length)))
+ if ((selection_is_html && !html_contains_nonwhitespace (selection, length)) ||
+ (!selection_is_html && !plaintext_contains_nonwhitespace (selection, length)))
goto whole_message;
- if (!src_is_text_html) {
- maybe_mangle_plaintext_signature_delimiter (&selection);
- length = strlen (selection);
- }
-
new_message = camel_mime_message_new ();
/* Filter out "content-*" headers. */
@@ -2789,7 +2771,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
CAMEL_MIME_PART (new_message),
selection,
length,
- src_is_text_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
+ selection_is_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
ccd = g_new0 (CreateComposerData, 1);
ccd->reader = g_object_ref (reader);
@@ -2853,11 +2835,121 @@ whole_message:
}
exit:
- g_free (selection);
g_clear_object (&address);
g_clear_object (&folder);
}
+typedef struct _GetSelectionData {
+ EMailReader *reader;
+ CamelMimeMessage *src_message;
+ EMailReplyType reply_type;
+ gboolean selection_is_html;
+} GetSelectionData;
+
+static void
+reply_got_message_selection_jsc_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GetSelectionData *gsd = user_data;
+ gchar *selection;
+ GSList *texts = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (gsd != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW (source_object));
+
+ if (!e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source_object), result, &texts, &error)) {
+ texts = NULL;
+ g_warning ("%s: Failed to get view selection: %s", G_STRFUNC, error ? error->message :
"Unknown error");
+ }
+
+ selection = texts ? texts->data : NULL;
+
+ if (selection && !gsd->selection_is_html) {
+ maybe_mangle_plaintext_signature_delimiter (&selection);
+ texts->data = selection;
+ }
+
+ e_mail_reader_reply_to_message_with_selection (gsd->reader, gsd->src_message, gsd->reply_type,
selection, gsd->selection_is_html);
+
+ g_slist_free_full (texts, g_free);
+ g_clear_error (&error);
+ g_clear_object (&gsd->reader);
+ g_clear_object (&gsd->src_message);
+ g_slice_free (GetSelectionData, gsd);
+}
+
+void
+e_mail_reader_reply_to_message (EMailReader *reader,
+ CamelMimeMessage *src_message,
+ EMailReplyType reply_type)
+{
+ CamelContentType *ct;
+ GetSelectionData *gsd;
+ EMailDisplay *mail_display;
+ EMailPartList *part_list = NULL;
+ EWebView *web_view;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ mail_display = e_mail_reader_get_mail_display (reader);
+ g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
+
+ web_view = E_WEB_VIEW (mail_display);
+
+ if (!gtk_widget_get_visible (GTK_WIDGET (web_view)) ||
+ !e_web_view_has_selection (web_view)) {
+ e_mail_reader_reply_to_message_with_selection (reader, src_message, reply_type, NULL, FALSE);
+ return;
+ }
+
+ if (!src_message) {
+ CamelFolder *folder;
+ GtkWidget *message_list;
+ const gchar *uid;
+ gchar *mail_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ uid = MESSAGE_LIST (message_list)->cursor_uid;
+ g_return_if_fail (uid != NULL);
+
+ folder = e_mail_reader_ref_folder (reader);
+ mail_uri = e_mail_part_build_uri (folder, uid, NULL, NULL);
+ part_list = camel_object_bag_get (e_mail_part_list_get_registry (), mail_uri);
+ g_clear_object (&folder);
+ g_free (mail_uri);
+
+ src_message = part_list ? e_mail_part_list_get_message (part_list) : NULL;
+
+ if (!src_message) {
+ e_mail_reader_reply_to_message_with_selection (reader, src_message, reply_type, NULL,
FALSE);
+ g_clear_object (&part_list);
+ return;
+ }
+ }
+
+ gsd = g_slice_new0 (GetSelectionData);
+ gsd->reader = g_object_ref (reader);
+ gsd->src_message = src_message ? g_object_ref (src_message) : NULL;
+ gsd->reply_type = reply_type;
+
+ ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (src_message));
+
+ if (camel_content_type_is (ct, "text", "plain")) {
+ gsd->selection_is_html = FALSE;
+ e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_PLAIN, NULL,
+ reply_got_message_selection_jsc_cb, gsd);
+ } else {
+ gsd->selection_is_html = TRUE;
+ e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_HTML, NULL,
+ reply_got_message_selection_jsc_cb, gsd);
+ }
+
+ g_clear_object (&part_list);
+}
+
static void
mail_reader_save_messages_cb (GObject *source_object,
GAsyncResult *result,
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index 9898602880..e9edcd857e 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -4831,7 +4831,7 @@ mail_reader_update_actions (EMailReader *reader,
action = e_mail_reader_get_action (reader, "mail-search-web");
gtk_action_set_sensitive (action, single_message_selected &&
- mail_display && e_web_view_is_selection_active (E_WEB_VIEW (mail_display)));
+ mail_display && e_web_view_has_selection (E_WEB_VIEW (mail_display)));
mail_reader_update_labels_menu (reader);
}
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index 9e326d99e5..88fefb2f49 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -58,35 +58,6 @@ macro(add_evolution_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdi
add_simple_module(${_name} ${_sourcesvar} ${_depsvar} ${_defsvar} ${_cflagsvar} ${_incdirsvar}
${_ldflagsvar} ${moduledir})
endmacro(add_evolution_module)
-macro(add_simple_webextension_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdirsvar _ldflagsvar
_destdir)
- set(wex_deps
- ${${_depsvar}}
- edomutils
- )
- set(wex_cflags
- ${${_cflagsvar}}
- ${WEB_EXTENSIONS_CFLAGS}
- )
- set(wex_incdirs
- ${${_incdirsvar}}
- ${WEB_EXTENSIONS_INCLUDE_DIRS}
- )
- set(wex_ldflags
- ${${_ldflagsvar}}
- ${WEB_EXTENSIONS_LDFLAGS}
- )
-
- add_simple_module(${_name} ${_sourcesvar} wex_deps ${_defsvar} wex_cflags wex_incdirs wex_ldflags
${_destdir})
-endmacro(add_simple_webextension_module)
-
-macro(add_webextension_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdirsvar _ldflagsvar)
- add_simple_webextension_module(${_name} ${_sourcesvar} ${_depsvar} ${_defsvar} ${_cflagsvar}
${_incdirsvar} ${_ldflagsvar} "${webextensionsdir}")
-endmacro(add_webextension_module)
-
-macro(add_webextension_editor_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdirsvar _ldflagsvar)
- add_simple_webextension_module(${_name} ${_sourcesvar} ${_depsvar} ${_defsvar} ${_cflagsvar}
${_incdirsvar} ${_ldflagsvar} "${webextensionswebkiteditordir}")
-endmacro(add_webextension_editor_module)
-
add_subdirectory(addressbook)
add_subdirectory(calendar)
add_subdirectory(mail)
diff --git a/src/modules/itip-formatter/e-mail-part-itip.c b/src/modules/itip-formatter/e-mail-part-itip.c
index 03672cc1db..eabdbd7621 100644
--- a/src/modules/itip-formatter/e-mail-part-itip.c
+++ b/src/modules/itip-formatter/e-mail-part-itip.c
@@ -70,23 +70,34 @@ mail_part_itip_finalize (GObject *object)
}
static void
-mail_part_itip_bind_dom_element (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id)
+mail_part_itip_content_loaded (EMailPart *part,
+ EWebView *web_view)
{
EMailPartItip *pitip;
- ItipView *itip_view;
g_return_if_fail (E_IS_MAIL_PART_ITIP (part));
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- if (g_strcmp0 (element_id, e_mail_part_get_id (part)) != 0)
- return;
-
pitip = E_MAIL_PART_ITIP (part);
if (pitip->folder && pitip->message_uid && pitip->message) {
+ ItipView *itip_view;
+ GSList *link;
+
+ for (link = pitip->priv->views; link; link = g_slist_next (link)) {
+ EWebView *used_web_view;
+
+ itip_view = link->data;
+ used_web_view = itip_view_ref_web_view (itip_view);
+
+ if (used_web_view == web_view) {
+ g_clear_object (&used_web_view);
+ return;
+ }
+
+ g_clear_object (&used_web_view);
+ }
+
itip_view = itip_view_new (
e_mail_part_get_id (part),
pitip,
@@ -116,7 +127,7 @@ e_mail_part_itip_class_init (EMailPartItipClass *class)
object_class->finalize = mail_part_itip_finalize;
mail_part_class = E_MAIL_PART_CLASS (class);
- mail_part_class->bind_dom_element = mail_part_itip_bind_dom_element;
+ mail_part_class->content_loaded = mail_part_itip_content_loaded;
}
static void
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index 52e694c15c..66ecb63ddc 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -32,8 +32,6 @@
#include "calendar/gui/comp-util.h"
#include "calendar/gui/itip-utils.h"
-#include "web-extensions/e-web-extension-names.h"
-
#include <mail/em-config.h>
#include <mail/em-utils.h>
#include <em-format/e-mail-formatter-utils.h>
@@ -110,11 +108,8 @@ struct _ItipViewPrivate {
gpointer itip_part_ptr; /* not referenced, only for a "reference" to which part this belongs */
- GDBusConnection *dbus_connection;
- guint web_extension_source_changed_cb_signal_id;
- guint web_extension_recur_toggled_signal_id;
-
gchar *part_id;
+ gchar *selected_source_uid;
gchar *error;
GWeakRef *web_view_weakref;
@@ -183,6 +178,15 @@ struct _ItipViewPrivate {
guint update_item_error_info_id;
ItipViewResponse update_item_response;
GHashTable *real_comps; /* ESource's UID -> ECalComponent stored on the server */
+
+ gchar *state_rsvp_comment;
+ gboolean state_rsvp_check;
+ gboolean state_update_check;
+ gboolean state_recur_check;
+ gboolean state_free_time_check;
+ gboolean state_keep_alarm_check;
+ gboolean state_inherit_alarm_check;
+ gint state_response_id;
};
enum {
@@ -199,27 +203,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-static GDBusProxy *
-itip_view_ref_web_extension_proxy (ItipView *view)
-{
- EWebView *web_view;
- GDBusProxy *proxy = NULL;
-
- g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
-
- web_view = g_weak_ref_get (view->priv->web_view_weakref);
- if (!web_view)
- return NULL;
-
- proxy = e_web_view_get_web_extension_proxy (web_view);
- if (proxy)
- g_object_ref (proxy);
-
- g_object_unref (web_view);
-
- return proxy;
-}
-
static void
format_date_and_time_x (struct tm *date_tm,
struct tm *current_tm,
@@ -663,60 +646,19 @@ set_journal_sender_text (ItipView *view)
return sender;
}
-static guint64
-itip_view_get_page_id (ItipView *view)
-{
- EWebView *web_view;
- guint64 page_id = 0;
-
- web_view = g_weak_ref_get (view->priv->web_view_weakref);
- if (web_view) {
- page_id = webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view));
- g_object_unref (web_view);
- }
-
- return page_id;
-}
-
static void
enable_button (ItipView *view,
const gchar *button_id,
gboolean enable)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipEnableButton",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id, button_id,
enable),
- NULL);
-
- g_object_unref (proxy);
-}
-
-static void
-show_button (ItipView *view,
- const gchar *id)
-{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipShowButton",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, id),
- NULL);
+ EWebView *web_view;
- g_object_unref (proxy);
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_set_element_disabled (WEBKIT_WEB_VIEW (web_view), view->priv->part_id,
button_id, !enable,
+ e_web_view_get_cancellable (web_view));
+ g_object_unref (web_view);
+ }
}
static void
@@ -724,72 +666,32 @@ hide_element (ItipView *view,
const gchar *element_id,
gboolean hide)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipHideElement",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id, element_id, hide),
- NULL);
-
- g_object_unref (proxy);
-}
-
-static gboolean
-element_is_hidden (ItipView *view,
- const gchar *element_id)
-{
- GVariant *result;
- gboolean hidden;
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return FALSE;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- proxy,
- "ItipElementIsHidden",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id,
element_id),
- NULL);
+ EWebView *web_view;
- if (result) {
- g_variant_get (result, "(b)", &hidden);
- g_variant_unref (result);
- g_object_unref (proxy);
- return hidden;
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_set_element_hidden (WEBKIT_WEB_VIEW (web_view), view->priv->part_id,
element_id, hide,
+ e_web_view_get_cancellable (web_view));
+ g_object_unref (web_view);
}
-
- g_object_unref (proxy);
-
- return FALSE;
}
+#define show_button(_view, _id) hide_element(_view, _id, FALSE)
+
static void
set_inner_html (ItipView *view,
const gchar *element_id,
const gchar *inner_html)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipElementSetInnerHTML",
- g_variant_new ("(tsss)", itip_view_get_page_id (view), view->priv->part_id, element_id,
inner_html),
- NULL);
+ EWebView *web_view;
- g_object_unref (proxy);
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetElementInnerHTML(%s, %s, %s);",
+ view->priv->part_id, element_id, inner_html);
+ g_object_unref (web_view);
+ }
}
static void
@@ -797,73 +699,31 @@ input_set_checked (ItipView *view,
const gchar *input_id,
gboolean checked)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipInputSetChecked",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id, input_id,
checked),
- NULL);
-
- g_object_unref (proxy);
-}
-
-static gboolean
-input_is_checked (ItipView *view,
- const gchar *input_id)
-{
- GVariant *result;
- gboolean checked;
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return FALSE;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- proxy,
- "ItipInputIsChecked",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, input_id),
- NULL);
+ EWebView *web_view;
- if (result) {
- g_variant_get (result, "(b)", &checked);
- g_variant_unref (result);
- g_object_unref (proxy);
- return checked;
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_set_element_checked (WEBKIT_WEB_VIEW (web_view), view->priv->part_id,
input_id, checked,
+ e_web_view_get_cancellable (web_view));
+ g_object_unref (web_view);
}
-
- g_object_unref (proxy);
-
- return FALSE;
}
static void
show_checkbox (ItipView *view,
- const gchar *id,
+ const gchar *element_id,
gboolean show,
gboolean update_second)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipShowCheckbox",
- g_variant_new ("(tssbb)", itip_view_get_page_id (view), view->priv->part_id, id, show,
update_second),
- NULL);
+ EWebView *web_view;
- g_object_unref (proxy);
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetShowCheckbox(%s, %s, %x, %x);",
+ view->priv->part_id, element_id, show, update_second);
+ g_object_unref (web_view);
+ }
}
static void
@@ -871,20 +731,15 @@ set_area_text (ItipView *view,
const gchar *id,
const gchar *text)
{
- GDBusProxy *proxy;
-
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipSetAreaText",
- g_variant_new ("(tsss)", itip_view_get_page_id (view), view->priv->part_id, id, text ? text :
""),
- NULL);
+ EWebView *web_view;
- g_object_unref (proxy);
+ web_view = itip_view_ref_web_view (view);
+ if (web_view) {
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetAreaText(%s, %s, %s);",
+ view->priv->part_id, id, text);
+ g_object_unref (web_view);
+ }
}
static void
@@ -919,7 +774,7 @@ static void
update_start_end_times (ItipView *view)
{
ItipViewPrivate *priv;
- GDBusProxy *proxy;
+ EWebView *web_view;
gchar buffer[256];
time_t now;
struct tm *now_tm;
@@ -964,46 +819,98 @@ update_start_end_times (ItipView *view)
}
#undef is_same
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
if (priv->start_header && priv->start_label) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipUpdateTimes",
- g_variant_new (
- "(tssss)",
- itip_view_get_page_id (view),
- view->priv->part_id,
- TABLE_ROW_START_DATE,
- priv->start_header,
- priv->start_label),
- NULL);
- } else
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.UpdateTimes(%s, %s, %s, %s);",
+ view->priv->part_id,
+ TABLE_ROW_START_DATE,
+ priv->start_header,
+ priv->start_label);
+ } else {
hide_element (view, TABLE_ROW_START_DATE, TRUE);
+ }
if (priv->end_header && priv->end_label) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipUpdateTimes",
- g_variant_new (
- "(tssss)",
- itip_view_get_page_id (view),
- view->priv->part_id,
- TABLE_ROW_END_DATE,
- priv->end_header,
- priv->end_label),
- NULL);
- } else
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.UpdateTimes(%s, %s, %s, %s);",
+ view->priv->part_id,
+ TABLE_ROW_END_DATE,
+ priv->end_header,
+ priv->end_label);
+ } else {
hide_element (view, TABLE_ROW_END_DATE, TRUE);
+ }
+
+ g_object_unref (web_view);
+}
+
+static void
+itip_view_get_state_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ ItipView *view;
+ GWeakRef *wkrf = user_data;
+
+ g_return_if_fail (E_IS_WEB_VIEW (source_object));
+ g_return_if_fail (wkrf != NULL);
+
+ view = g_weak_ref_get (wkrf);
+ if (view) {
+ WebKitJavascriptResult *js_result;
+ GError *error = NULL;
+
+ g_clear_pointer (&view->priv->state_rsvp_comment, g_free);
+
+ js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (source_object), result,
&error);
+
+ if (error) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ (!g_error_matches (error, WEBKIT_JAVASCRIPT_ERROR,
WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED) ||
+ /* WebKit can return empty error message, thus ignore those. */
+ (error->message && *(error->message))))
+ g_warning ("Failed to call 'ItipView.GetState()' function: %s:%d: %s",
g_quark_to_string (error->domain), error->code, error->message);
+ g_clear_error (&error);
+ }
+
+ if (js_result) {
+ JSCException *exception;
+ JSCValue *value;
+
+ value = webkit_javascript_result_get_js_value (js_result);
+ exception = jsc_context_get_exception (jsc_value_get_context (value));
+
+ if (exception)
+ g_warning ("Failed to call 'ItipView.GetState()': %s",
jsc_exception_get_message (exception));
+
+ view->priv->state_rsvp_comment = e_web_view_jsc_get_object_property_string (value,
"rsvp-comment", NULL);
+ view->priv->state_rsvp_check = e_web_view_jsc_get_object_property_boolean (value,
"rsvp-check", FALSE);
+ view->priv->state_update_check = e_web_view_jsc_get_object_property_boolean (value,
"update-check", FALSE);
+ view->priv->state_recur_check = e_web_view_jsc_get_object_property_boolean (value,
"recur-check", FALSE);
+ view->priv->state_free_time_check = e_web_view_jsc_get_object_property_boolean
(value, "free-time-check", FALSE);
+ view->priv->state_keep_alarm_check = e_web_view_jsc_get_object_property_boolean
(value, "keep-alarm-check", FALSE);
+ view->priv->state_inherit_alarm_check = e_web_view_jsc_get_object_property_boolean
(value, "inherit-alarm-check", FALSE);
- g_object_unref (proxy);
+ webkit_javascript_result_unref (js_result);
+
+ g_signal_emit (view, signals[RESPONSE], 0, view->priv->state_response_id);
+ }
+
+ g_object_unref (view);
+ }
+
+ e_weak_ref_free (wkrf);
}
static void
itip_view_itip_button_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
const gchar *element_class,
const gchar *element_value,
const GtkAllocation *element_position,
@@ -1026,8 +933,16 @@ itip_view_itip_button_clicked_cb (EWebView *web_view,
if (can_use) {
gint response = atoi (element_value);
+ gchar *script;
- g_signal_emit (view, signals[RESPONSE], 0, response);
+ view->priv->state_response_id = response;
+
+ script = e_web_view_jsc_printf_script ("EvoItip.GetState(%s);", view->priv->part_id);
+
+ webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (web_view),
+ script, e_web_view_get_cancellable (web_view), itip_view_get_state_cb, e_weak_ref_new
(view));
+
+ g_free (script);
}
}
@@ -1048,27 +963,13 @@ itip_view_register_clicked_listener (ItipView *view)
}
static void
-recur_toggled_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- ItipView *view)
+itip_set_selected_source_uid (ItipView *view,
+ const gchar *uid)
{
- guint64 page_id = 0;
- const gchar *part_id = NULL;
-
- g_return_if_fail (ITIP_IS_VIEW (view));
-
- if (g_strcmp0 (signal_name, "ItipRecurToggled") != 0)
- return;
-
- g_variant_get (parameters, "(t&s)", &page_id, &part_id);
-
- if (itip_view_get_page_id (view) == page_id &&
- g_strcmp0 (view->priv->part_id, part_id) == 0)
- itip_view_set_mode (view, view->priv->mode);
+ if (g_strcmp0 (view->priv->selected_source_uid, uid) != 0) {
+ g_free (view->priv->selected_source_uid);
+ view->priv->selected_source_uid = g_strdup (uid);
+ }
}
static void
@@ -1086,31 +987,6 @@ source_changed_cb (ItipView *view)
}
}
-static void
-source_changed_cb_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- ItipView *view = user_data;
- guint64 page_id = 0;
- const gchar *part_id = NULL;
-
- g_return_if_fail (ITIP_IS_VIEW (view));
-
- if (g_strcmp0 (signal_name, "ItipSourceChanged") != 0)
- return;
-
- g_variant_get (parameters, "(t&s)", &page_id, &part_id);
-
- if (itip_view_get_page_id (view) == page_id &&
- g_strcmp0 (view->priv->part_id, part_id) == 0)
- source_changed_cb (view);
-}
-
static void
append_checkbox_table_row (GString *buffer,
const gchar *name,
@@ -1177,13 +1053,13 @@ append_info_item_row (ItipView *view,
const gchar *table_id,
ItipViewInfoItem *item)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
const gchar *icon_name;
gchar *row_id;
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
switch (item->type) {
@@ -1207,20 +1083,15 @@ append_info_item_row (ItipView *view,
row_id = g_strdup_printf ("%s_row_%d", table_id, item->id);
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipAppendInfoItemRow",
- g_variant_new (
- "(tsssss)",
- itip_view_get_page_id (view),
- view->priv->part_id,
- table_id,
- row_id,
- icon_name,
- item->message),
- NULL);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.AppendInfoRow(%s, %s, %s, %s, %s);",
+ view->priv->part_id,
+ table_id,
+ row_id,
+ icon_name,
+ item->message);
- g_object_unref (proxy);
+ g_object_unref (web_view);
g_free (row_id);
d (printf ("Added row %s_row_%d ('%s')\n", table_id, item->id, item->message));
@@ -1231,23 +1102,22 @@ remove_info_item_row (ItipView *view,
const gchar *table_id,
guint id)
{
+ EWebView *web_view;
gchar *row_id;
- GDBusProxy *proxy;
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
row_id = g_strdup_printf ("%s_row_%d", table_id, id);
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipRemoveElement",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, row_id),
- NULL);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.RemoveInfoRow(%s, %s);",
+ view->priv->part_id,
+ row_id);
- g_object_unref (proxy);
+ g_object_unref (web_view);
g_free (row_id);
d (printf ("Removed row %s_row_%d\n", table_id, id));
@@ -1345,30 +1215,32 @@ static void
itip_view_rebuild_source_list (ItipView *view)
{
ESourceRegistry *registry;
- GDBusProxy *proxy;
+ EWebView *web_view;
GList *list, *link;
+ GString *script;
const gchar *extension_name;
d (printf ("Assigning a new source list!\n"));
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
registry = view->priv->registry;
extension_name = itip_view_get_extension_name (view);
if (!extension_name) {
- g_object_unref (proxy);
+ g_object_unref (web_view);
return;
}
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipElementRemoveChildNodes",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, SELECT_ESOURCE),
- NULL);
+ script = g_string_sized_new (1024);
+
+ e_web_view_jsc_printf_script_gstring (script,
+ "EvoItip.RemoveChildNodes(%s, %s);",
+ view->priv->part_id,
+ SELECT_ESOURCE);
list = e_source_registry_list_enabled (registry, extension_name);
@@ -1379,25 +1251,23 @@ itip_view_rebuild_source_list (ItipView *view)
parent = e_source_registry_ref_source (
registry, e_source_get_parent (source));
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipRebuildSourceList",
- g_variant_new (
- "(tsssssb)",
- itip_view_get_page_id (view),
- view->priv->part_id,
- e_source_get_uid (parent),
- e_source_get_display_name (parent),
- e_source_get_uid (source),
- e_source_get_display_name (source),
- e_source_get_writable (source)),
- NULL);
+ e_web_view_jsc_printf_script_gstring (script,
+ "EvoItip.AddToSourceList(%s, %s, %s, %s, %s, %x);",
+ view->priv->part_id,
+ e_source_get_uid (parent),
+ e_source_get_display_name (parent),
+ e_source_get_uid (source),
+ e_source_get_display_name (source),
+ e_source_get_writable (source));
g_object_unref (parent);
}
+ e_web_view_jsc_run_script_take (WEBKIT_WEB_VIEW (web_view), g_string_free (script, FALSE),
+ e_web_view_get_cancellable (web_view));
+
g_list_free_full (list, (GDestroyNotify) g_object_unref);
- g_object_unref (proxy);
+ g_object_unref (web_view);
source_changed_cb (view);
}
@@ -1438,25 +1308,6 @@ itip_view_source_removed_cb (ESourceRegistry *registry,
itip_view_rebuild_source_list (view);
}
-static void
-itip_view_unregister_dbus_signals (ItipView *view)
-{
- g_return_if_fail (ITIP_IS_VIEW (view));
-
- if (view->priv->dbus_connection && !g_dbus_connection_is_closed (view->priv->dbus_connection)) {
- if (view->priv->web_extension_recur_toggled_signal_id)
- g_dbus_connection_signal_unsubscribe (view->priv->dbus_connection,
view->priv->web_extension_recur_toggled_signal_id);
-
- if (view->priv->web_extension_source_changed_cb_signal_id)
- g_dbus_connection_signal_unsubscribe (view->priv->dbus_connection,
view->priv->web_extension_source_changed_cb_signal_id);
- }
-
- view->priv->web_extension_recur_toggled_signal_id = 0;
- view->priv->web_extension_source_changed_cb_signal_id = 0;
-
- g_clear_object (&view->priv->dbus_connection);
-}
-
static void
itip_view_set_client_cache (ItipView *view,
EClientCache *client_cache)
@@ -1536,11 +1387,8 @@ itip_view_dispose (GObject *object)
priv->source_removed_handler_id = 0;
}
- itip_view_unregister_dbus_signals (ITIP_VIEW (object));
-
g_clear_object (&priv->client_cache);
g_clear_object (&priv->registry);
- g_clear_object (&priv->dbus_connection);
g_clear_object (&priv->cancellable);
g_clear_object (&priv->comp);
@@ -1577,6 +1425,7 @@ itip_view_finalize (GObject *object)
g_free (priv->description);
g_free (priv->error);
g_free (priv->part_id);
+ g_free (priv->selected_source_uid);
for (iter = priv->lower_info_items; iter; iter = iter->next) {
ItipViewInfoItem *item = iter->data;
@@ -1606,6 +1455,7 @@ itip_view_finalize (GObject *object)
g_free (priv->delegator_name);
g_free (priv->my_address);
g_free (priv->message_uid);
+ g_free (priv->state_rsvp_comment);
g_clear_object (&priv->folder);
g_clear_object (&priv->message);
@@ -1919,65 +1769,6 @@ itip_view_write_for_printing (ItipView *view,
g_string_append (buffer, "</div>");
}
-static void
-itip_view_web_extension_proxy_notify_cb (GObject *web_view,
- GParamSpec *param,
- gpointer user_data)
-{
- ItipView *view = user_data;
- GDBusConnection *connection;
- GDBusProxy *proxy;
-
- if (!view)
- return;
-
- itip_view_unregister_dbus_signals (view);
-
- proxy = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
- if (!proxy)
- return;
-
- connection = g_dbus_proxy_get_connection (proxy);
- if (!connection || g_dbus_connection_is_closed (connection))
- return;
-
- view->priv->dbus_connection = g_object_ref (connection);
-
- view->priv->web_extension_source_changed_cb_signal_id =
- g_dbus_connection_signal_subscribe (
- view->priv->dbus_connection,
- g_dbus_proxy_get_name (proxy),
- E_WEB_EXTENSION_INTERFACE,
- "ItipSourceChanged",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- source_changed_cb_signal_cb,
- view,
- NULL);
-
- view->priv->web_extension_recur_toggled_signal_id =
- g_dbus_connection_signal_subscribe (
- view->priv->dbus_connection,
- g_dbus_proxy_get_name (proxy),
- E_WEB_EXTENSION_INTERFACE,
- "ItipRecurToggled",
- E_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback) recur_toggled_signal_cb,
- view,
- NULL);
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipCreateDOMBindings",
- g_variant_new ("(ts)", itip_view_get_page_id (view), view->priv->part_id),
- NULL);
-
- itip_view_init_view (view);
-}
-
static void
itip_view_init (ItipView *view)
{
@@ -2022,23 +1813,22 @@ void
itip_view_set_mode (ItipView *view,
ItipViewMode mode)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
g_return_if_fail (ITIP_IS_VIEW (view));
view->priv->mode = mode;
set_sender_text (view);
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipElementHideChildNodes",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, TABLE_ROW_BUTTONS),
- NULL);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.HideButtons(%s, %s);",
+ view->priv->part_id,
+ TABLE_ROW_BUTTONS);
view->priv->is_recur_set = itip_view_get_recur_check_state (view);
@@ -2083,7 +1873,7 @@ itip_view_set_mode (ItipView *view,
break;
}
- g_object_unref (proxy);
+ g_object_unref (web_view);
}
ItipViewMode
@@ -2098,16 +1888,16 @@ void
itip_view_set_item_type (ItipView *view,
ECalClientSourceType type)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
const gchar *header;
gchar *access_key, *html_label;
g_return_if_fail (ITIP_IS_VIEW (view));
view->priv->type = type;
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
switch (view->priv->type) {
@@ -2127,21 +1917,21 @@ itip_view_set_item_type (ItipView *view,
if (!header) {
set_sender_text (view);
- g_object_unref (proxy);
+ g_object_unref (web_view);
return;
}
html_label = e_mail_formatter_parse_html_mnemonics (header, &access_key);
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipElementSetAccessKey",
- g_variant_new ("(tsss)", itip_view_get_page_id (view), view->priv->part_id,
TABLE_ROW_ESCB_LABEL, access_key),
- NULL);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetElementAccessKey(%s, %s, %s);",
+ view->priv->part_id,
+ TABLE_ROW_ESCB_LABEL,
+ access_key);
set_inner_html (view, TABLE_ROW_ESCB_LABEL, html_label);
- g_object_unref (proxy);
+ g_object_unref (web_view);
g_free (html_label);
if (access_key)
@@ -2829,7 +2619,7 @@ itip_view_set_source (ItipView *view,
ESource *source)
{
ESource *selected_source;
- GDBusProxy *proxy;
+ EWebView *web_view;
g_return_if_fail (ITIP_IS_VIEW (view));
@@ -2852,110 +2642,56 @@ itip_view_set_source (ItipView *view,
if (selected_source != NULL)
g_object_unref (selected_source);
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipEnableSelect",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id, SELECT_ESOURCE,
TRUE),
- NULL);
+ e_web_view_jsc_set_element_disabled (WEBKIT_WEB_VIEW (web_view),
+ view->priv->part_id, SELECT_ESOURCE, FALSE,
+ e_web_view_get_cancellable (web_view));
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipSelectSetSelected",
- g_variant_new ("(tsss)", itip_view_get_page_id (view), view->priv->part_id, SELECT_ESOURCE,
e_source_get_uid (source)),
- NULL);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetSelectSelected(%s, %s, %s);",
+ view->priv->part_id,
+ SELECT_ESOURCE,
+ e_source_get_uid (source));
+
+ itip_set_selected_source_uid (view, e_source_get_uid (source));
source_changed_cb (view);
- g_object_unref (proxy);
+ g_object_unref (web_view);
}
ESource *
itip_view_ref_source (ItipView *view)
{
- ESource *source = NULL;
- gboolean disable = FALSE, enabled = FALSE;
- GDBusProxy *proxy;
- GVariant *result;
-
g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
+ if (!view->priv->selected_source_uid || !*view->priv->selected_source_uid)
return NULL;
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- proxy,
- "ItipSelectIsEnabled",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id,
SELECT_ESOURCE),
- NULL);
-
- if (result) {
- g_variant_get (result, "(b)", &enabled);
- g_variant_unref (result);
- }
-
- if (!enabled) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipEnableSelect",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id,
SELECT_ESOURCE, TRUE),
- NULL);
-
- disable = TRUE;
- }
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- proxy,
- "ItipSelectGetValue",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id, SELECT_ESOURCE),
- NULL);
-
- if (result) {
- const gchar *uid;
-
- g_variant_get (result, "(&s)", &uid);
- source = e_source_registry_ref_source (view->priv->registry, uid);
- g_variant_unref (result);
- }
-
- if (disable) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipEnableSelect",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id,
SELECT_ESOURCE, FALSE),
- NULL);
- }
-
- g_object_unref (proxy);
-
- return source;
+ return e_source_registry_ref_source (view->priv->registry, view->priv->selected_source_uid);
}
void
itip_view_set_rsvp (ItipView *view,
gboolean rsvp)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
input_set_checked (view, CHECKBOX_RSVP, rsvp);
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipEnableTextArea",
- g_variant_new ("(tssb)", itip_view_get_page_id (view), view->priv->part_id,
TEXTAREA_RSVP_COMMENT, !rsvp),
- NULL);
+ e_web_view_jsc_set_element_disabled (WEBKIT_WEB_VIEW (web_view),
+ view->priv->part_id, TEXTAREA_RSVP_COMMENT, rsvp,
+ e_web_view_get_cancellable (web_view));
- g_object_unref (proxy);
+ g_object_unref (web_view);
}
gboolean
@@ -2963,7 +2699,7 @@ itip_view_get_rsvp (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_RSVP);
+ return view->priv->state_rsvp_check;
}
void
@@ -2976,14 +2712,6 @@ itip_view_set_show_rsvp_check (ItipView *view,
hide_element (view, TABLE_ROW_RSVP_COMMENT, !show);
}
-gboolean
-itip_view_get_show_rsvp_check (ItipView *view)
-{
- g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
-
- return !element_is_hidden (view, CHECKBOX_RSVP);
-}
-
void
itip_view_set_update (ItipView *view,
gboolean update)
@@ -2998,7 +2726,7 @@ itip_view_get_update (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_UPDATE);
+ return view->priv->state_update_check;
}
void
@@ -3010,72 +2738,32 @@ itip_view_set_show_update_check (ItipView *view,
show_checkbox (view, CHECKBOX_UPDATE, show, FALSE);
}
-gboolean
-itip_view_get_show_update_check (ItipView *view)
-{
- g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
-
- return !element_is_hidden (view, CHECKBOX_UPDATE);
-}
-
void
itip_view_set_rsvp_comment (ItipView *view,
const gchar *comment)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
- proxy = itip_view_ref_web_extension_proxy (view);
+ web_view = itip_view_ref_web_view (view);
- if (!proxy)
+ if (!web_view)
return;
- if (comment) {
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipTextAreaSetValue",
- g_variant_new ("(tsss)", itip_view_get_page_id (view), view->priv->part_id,
TEXTAREA_RSVP_COMMENT, comment),
- NULL);
- }
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetAreaText(%s, %s, %s);",
+ view->priv->part_id,
+ TEXTAREA_RSVP_COMMENT,
+ comment);
- g_object_unref (proxy);
+ g_object_unref (web_view);
}
-gchar *
+const gchar *
itip_view_get_rsvp_comment (ItipView *view)
{
- GDBusProxy *proxy;
- GVariant *result;
-
g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
- proxy = itip_view_ref_web_extension_proxy (view);
-
- if (!proxy)
- return NULL;
-
- if (element_is_hidden (view, TEXTAREA_RSVP_COMMENT)) {
- g_object_unref (proxy);
- return NULL;
- }
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- proxy,
- "ItipTextAreaGetValue",
- g_variant_new ("(tss)", itip_view_get_page_id (view), view->priv->part_id,
TEXTAREA_RSVP_COMMENT),
- NULL);
-
- if (result) {
- gchar *value;
-
- g_variant_get (result, "(s)", &value);
- g_variant_unref (result);
- g_object_unref (proxy);
- return value;
- }
-
- g_object_unref (proxy);
-
- return NULL;
+ return view->priv->state_rsvp_comment;
}
void
@@ -3091,25 +2779,23 @@ void
itip_view_set_buttons_sensitive (ItipView *view,
gboolean sensitive)
{
- GDBusProxy *proxy;
+ EWebView *web_view;
g_return_if_fail (ITIP_IS_VIEW (view));
d (printf ("Settings buttons %s\n", sensitive ? "sensitive" : "insensitive"));
view->priv->buttons_sensitive = sensitive;
- proxy = itip_view_ref_web_extension_proxy (view);
- if (!proxy)
- return;
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- proxy,
- "ItipSetButtonsSensitive",
- g_variant_new ("(tsb)", itip_view_get_page_id (view), view->priv->part_id, sensitive),
- NULL);
+ web_view = itip_view_ref_web_view (view);
- g_object_unref (proxy);
+ if (web_view) {
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.SetButtonsDisabled(%s, %x);",
+ view->priv->part_id,
+ !sensitive);
+ g_object_unref (web_view);
+ }
}
gboolean
@@ -3125,7 +2811,7 @@ itip_view_get_recur_check_state (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_RECUR);
+ return view->priv->state_recur_check;
}
void
@@ -3151,7 +2837,7 @@ itip_view_get_free_time_check_state (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_FREE_TIME);
+ return view->priv->state_free_time_check;
}
void
@@ -3179,7 +2865,7 @@ itip_view_get_keep_alarm_check_state (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_KEEP_ALARM);
+ return view->priv->state_keep_alarm_check;
}
void
@@ -3196,7 +2882,7 @@ itip_view_get_inherit_alarm_check_state (ItipView *view)
{
g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
- return input_is_checked (view, CHECKBOX_INHERIT_ALARM);
+ return view->priv->state_inherit_alarm_check;
}
void
@@ -4926,7 +4612,7 @@ finish_message_delete_with_rsvp (ItipView *view,
ICalComponent *icomp;
ICalProperty *prop;
const gchar *attendee;
- gchar *comment;
+ const gchar *comment;
GSList *l, *list = NULL;
gboolean found;
@@ -4983,7 +4669,6 @@ finish_message_delete_with_rsvp (ItipView *view,
e_cal_component_set_comments (comp, &comments);
e_cal_component_text_free (text);
- g_free (comment);
}
if (itip_send_comp_sync (
@@ -6939,6 +6624,55 @@ itip_view_init_view (ItipView *view)
}
}
+static void
+itip_source_changed_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ ItipView *view = user_data;
+ JSCValue *jsc_value;
+ gchar *iframe_id, *source_uid;
+
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_object (jsc_value));
+
+ iframe_id = e_web_view_jsc_get_object_property_string (jsc_value, "iframe-id", NULL);
+ source_uid = e_web_view_jsc_get_object_property_string (jsc_value, "source-uid", NULL);
+
+ if (g_strcmp0 (iframe_id, view->priv->part_id) == 0) {
+ itip_set_selected_source_uid (view, source_uid);
+ source_changed_cb (view);
+ }
+
+ g_free (iframe_id);
+}
+
+static void
+itip_recur_toggled_cb (WebKitUserContentManager *manager,
+ WebKitJavascriptResult *js_result,
+ gpointer user_data)
+{
+ ItipView *view = user_data;
+ JSCValue *jsc_value;
+ gchar *iframe_id;
+
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (js_result != NULL);
+
+ jsc_value = webkit_javascript_result_get_js_value (js_result);
+ g_return_if_fail (jsc_value_is_string (jsc_value));
+
+ iframe_id = jsc_value_to_string (jsc_value);
+
+ if (g_strcmp0 (iframe_id, view->priv->part_id) == 0)
+ itip_view_set_mode (view, view->priv->mode);
+
+ g_free (iframe_id);
+}
+
void
itip_view_set_web_view (ItipView *view,
EWebView *web_view)
@@ -6950,13 +6684,24 @@ itip_view_set_web_view (ItipView *view,
g_weak_ref_set (view->priv->web_view_weakref, web_view);
if (web_view) {
- g_signal_connect_object (web_view, "notify::web-extension-proxy",
- G_CALLBACK (itip_view_web_extension_proxy_notify_cb), view, 0);
+ WebKitUserContentManager *manager;
- if (e_web_view_get_web_extension_proxy (web_view))
- itip_view_web_extension_proxy_notify_cb (G_OBJECT (web_view), NULL, view);
- } else {
- itip_view_unregister_dbus_signals (view);
+ manager = webkit_web_view_get_user_content_manager (WEBKIT_WEB_VIEW (web_view));
+
+ g_signal_connect_object (manager, "script-message-received::itipSourceChanged",
+ G_CALLBACK (itip_source_changed_cb), view, 0);
+
+ g_signal_connect_object (manager, "script-message-received::itipRecurToggled",
+ G_CALLBACK (itip_recur_toggled_cb), view, 0);
+
+ webkit_user_content_manager_register_script_message_handler (manager, "itipSourceChanged");
+ webkit_user_content_manager_register_script_message_handler (manager, "itipRecurToggled");
+
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+ "EvoItip.Initialize(%s);",
+ view->priv->part_id);
+
+ itip_view_init_view (view);
}
itip_view_register_clicked_listener (view);
diff --git a/src/modules/itip-formatter/itip-view.h b/src/modules/itip-formatter/itip-view.h
index 696f614d33..05e26f84a6 100644
--- a/src/modules/itip-formatter/itip-view.h
+++ b/src/modules/itip-formatter/itip-view.h
@@ -211,16 +211,14 @@ void itip_view_set_source (ItipView *view,
gboolean itip_view_get_rsvp (ItipView *view);
void itip_view_set_rsvp (ItipView *view,
gboolean rsvp);
-gboolean itip_view_get_show_rsvp_check (ItipView *view);
void itip_view_set_show_rsvp_check (ItipView *view,
gboolean show);
gboolean itip_view_get_update (ItipView *view);
void itip_view_set_update (ItipView *view,
gboolean update);
-gboolean itip_view_get_show_update_check (ItipView *view);
void itip_view_set_show_update_check (ItipView *view,
gboolean show);
-gchar * itip_view_get_rsvp_comment (ItipView *view);
+const gchar * itip_view_get_rsvp_comment (ItipView *view);
void itip_view_set_rsvp_comment (ItipView *view,
const gchar *comment);
gboolean itip_view_get_buttons_sensitive (ItipView *view);
diff --git a/src/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
b/src/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
index 4d6c360242..8b613fb546 100644
--- a/src/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
+++ b/src/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
@@ -35,7 +35,8 @@ struct _EMailDisplayPopupPreferPlain {
gchar *text_plain_id;
gchar *text_html_id;
- gchar *document_uri;
+ gchar *iframe_src;
+ gchar *iframe_id;
GtkActionGroup *action_group;
};
@@ -95,10 +96,10 @@ toggle_part (GtkAction *action,
GHashTable *query;
gchar *uri;
- if (!pp_extension->document_uri)
+ if (!pp_extension->iframe_src)
return;
- soup_uri = soup_uri_new (pp_extension->document_uri);
+ soup_uri = soup_uri_new (pp_extension->iframe_src);
if (!soup_uri || !soup_uri->query) {
if (soup_uri)
@@ -124,8 +125,8 @@ toggle_part (GtkAction *action,
uri = soup_uri_to_string (soup_uri, FALSE);
soup_uri_free (soup_uri);
- e_web_view_set_document_iframe_src (E_WEB_VIEW (e_extension_get_extensible (E_EXTENSION (extension))),
- pp_extension->document_uri, uri);
+ e_web_view_set_iframe_src (E_WEB_VIEW (e_extension_get_extensible (E_EXTENSION (extension))),
+ pp_extension->iframe_id, uri);
g_free (uri);
}
@@ -168,14 +169,19 @@ set_text_html_id (EMailDisplayPopupPreferPlain *extension,
}
static void
-set_document_uri (EMailDisplayPopupPreferPlain *extension,
- const gchar *document_uri)
+set_popup_place (EMailDisplayPopupPreferPlain *extension,
+ const gchar *iframe_src,
+ const gchar *iframe_id)
{
- if (extension->document_uri == document_uri)
- return;
+ if (g_strcmp0 (extension->iframe_src, iframe_src)) {
+ g_free (extension->iframe_src);
+ extension->iframe_src = g_strdup (iframe_src);
+ }
- g_free (extension->document_uri);
- extension->document_uri = g_strdup (document_uri);
+ if (g_strcmp0 (extension->iframe_id, iframe_id)) {
+ g_free (extension->iframe_id);
+ extension->iframe_id = g_strdup (iframe_id);
+ }
}
static GtkActionGroup *
@@ -227,7 +233,8 @@ create_group (EMailDisplayPopupExtension *extension)
static void
mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *extension,
- const gchar *popup_document_uri)
+ const gchar *popup_iframe_src,
+ const gchar *popup_iframe_id)
{
EMailDisplay *display;
EMailDisplayPopupPreferPlain *pp_extension;
@@ -249,10 +256,10 @@ mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *exte
if (!pp_extension->action_group)
pp_extension->action_group = create_group (extension);
- set_document_uri (pp_extension, popup_document_uri);
+ set_popup_place (pp_extension, popup_iframe_src, popup_iframe_id);
- if (pp_extension->document_uri)
- soup_uri = soup_uri_new (pp_extension->document_uri);
+ if (pp_extension->iframe_src)
+ soup_uri = soup_uri_new (pp_extension->iframe_src);
else
soup_uri = NULL;
@@ -383,7 +390,8 @@ e_mail_display_popup_prefer_plain_finalize (GObject *object)
g_free (extension->text_html_id);
g_free (extension->text_plain_id);
- g_free (extension->document_uri);
+ g_free (extension->iframe_src);
+ g_free (extension->iframe_id);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_mail_display_popup_prefer_plain_parent_class)->finalize (object);
@@ -420,5 +428,6 @@ e_mail_display_popup_prefer_plain_init (EMailDisplayPopupPreferPlain *extension)
extension->action_group = NULL;
extension->text_html_id = NULL;
extension->text_plain_id = NULL;
- extension->document_uri = NULL;
+ extension->iframe_src = NULL;
+ extension->iframe_id = NULL;
}
diff --git a/src/modules/text-highlight/e-mail-display-popup-text-highlight.c
b/src/modules/text-highlight/e-mail-display-popup-text-highlight.c
index cae12f12f1..51cd3acbe8 100644
--- a/src/modules/text-highlight/e-mail-display-popup-text-highlight.c
+++ b/src/modules/text-highlight/e-mail-display-popup-text-highlight.c
@@ -35,7 +35,8 @@ typedef struct _EMailDisplayPopupTextHighlight {
GtkActionGroup *action_group;
volatile gint updating;
- gchar *document_uri;
+ gchar *iframe_src;
+ gchar *iframe_id;
} EMailDisplayPopupTextHighlight;
typedef struct _EMailDisplayPopupTextHighlightClass {
@@ -106,14 +107,19 @@ static GtkActionEntry entries[] = {
};
static void
-set_document_uri (EMailDisplayPopupTextHighlight *extension,
- const gchar *document_uri)
+set_popup_place (EMailDisplayPopupTextHighlight *extension,
+ const gchar *iframe_src,
+ const gchar *iframe_id)
{
- if (extension->document_uri == document_uri)
- return;
+ if (g_strcmp0 (extension->iframe_src, iframe_src)) {
+ g_free (extension->iframe_src);
+ extension->iframe_src = g_strdup (iframe_src);
+ }
- g_free (extension->document_uri);
- extension->document_uri = g_strdup (document_uri);
+ if (g_strcmp0 (extension->iframe_id, iframe_id)) {
+ g_free (extension->iframe_id);
+ extension->iframe_id = g_strdup (iframe_id);
+ }
}
static void
@@ -131,8 +137,8 @@ reformat (GtkAction *old,
if (g_atomic_int_get (&th_extension->updating))
return;
- if (th_extension->document_uri)
- soup_uri = soup_uri_new (th_extension->document_uri);
+ if (th_extension->iframe_src)
+ soup_uri = soup_uri_new (th_extension->iframe_src);
else
soup_uri = NULL;
@@ -158,8 +164,8 @@ reformat (GtkAction *old,
uri = soup_uri_to_string (soup_uri, FALSE);
soup_uri_free (soup_uri);
- e_web_view_set_document_iframe_src (E_WEB_VIEW (e_extension_get_extensible (E_EXTENSION
(th_extension))),
- th_extension->document_uri, uri);
+ e_web_view_set_iframe_src (E_WEB_VIEW (e_extension_get_extensible (E_EXTENSION (th_extension))),
+ th_extension->iframe_id, uri);
g_free (uri);
}
@@ -293,7 +299,8 @@ emdp_text_highlight_is_enabled (void)
static void
update_actions (EMailDisplayPopupExtension *extension,
- const gchar *popup_document_uri)
+ const gchar *popup_iframe_src,
+ const gchar *popup_iframe_id)
{
EMailDisplayPopupTextHighlight *th_extension;
@@ -302,17 +309,17 @@ update_actions (EMailDisplayPopupExtension *extension,
if (!th_extension->action_group)
th_extension->action_group = create_group (extension);
- set_document_uri (th_extension, popup_document_uri);
+ set_popup_place (th_extension, popup_iframe_src, popup_iframe_id);
/* If the part below context menu was made by text-highlight formatter,
* then try to check what formatter it's using at the moment and set
* it as active in the popup menu */
- if (th_extension->document_uri && strstr (th_extension->document_uri, ".text-highlight") != NULL) {
+ if (th_extension->iframe_src && strstr (th_extension->iframe_src, ".text-highlight") != NULL) {
SoupURI *soup_uri;
gtk_action_group_set_visible (
th_extension->action_group, TRUE);
- soup_uri = soup_uri_new (th_extension->document_uri);
+ soup_uri = soup_uri_new (th_extension->iframe_src);
if (soup_uri && soup_uri->query) {
GHashTable *query = soup_form_decode (soup_uri->query);
const gchar *highlighter;
@@ -356,7 +363,8 @@ e_mail_display_popup_text_highlight_finalize (GObject *object)
extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (object);
g_clear_object (&extension->action_group);
- g_free (extension->document_uri);
+ g_free (extension->iframe_src);
+ g_free (extension->iframe_id);
/* Chain up to parent's method */
G_OBJECT_CLASS (e_mail_display_popup_text_highlight_parent_class)->finalize (object);
@@ -398,5 +406,6 @@ static void
e_mail_display_popup_text_highlight_init (EMailDisplayPopupTextHighlight *extension)
{
extension->action_group = NULL;
- extension->document_uri = NULL;
+ extension->iframe_src = NULL;
+ extension->iframe_id = NULL;
}
diff --git a/src/modules/vcard-inline/e-mail-formatter-vcard.c
b/src/modules/vcard-inline/e-mail-formatter-vcard.c
index a92ce37e44..d1affd4474 100644
--- a/src/modules/vcard-inline/e-mail-formatter-vcard.c
+++ b/src/modules/vcard-inline/e-mail-formatter-vcard.c
@@ -62,42 +62,58 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
GCancellable *cancellable)
{
EMailPartVCard *vcard_part;
+ const GSList *contacts;
g_return_val_if_fail (E_IS_MAIL_PART_VCARD (part), FALSE);
vcard_part = (EMailPartVCard *) part;
- g_return_val_if_fail (vcard_part->contact_list != NULL, FALSE);
+ contacts = e_mail_part_vcard_get_contacts (vcard_part);
+
+ if (!contacts)
+ return FALSE;
if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+ EABContactFormatter *vcard_formatter;
+ EABContactDisplayMode display_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
EContact *contact;
GString *buffer;
- contact = E_CONTACT (vcard_part->contact_list->data);
+ contact = E_CONTACT (contacts->data);
buffer = g_string_sized_new (1024);
- eab_contact_formatter_format_contact (
- vcard_part->formatter, contact, buffer);
+ if (context && context->uri) {
+ if (camel_strstrcase (context->uri, "vcard-format=normal"))
+ display_mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ else if (camel_strstrcase (context->uri, "vcard-format=compact"))
+ display_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
+ }
+
+ vcard_formatter = g_object_new (EAB_TYPE_CONTACT_FORMATTER,
+ "display-mode", display_mode,
+ "render-maps", FALSE,
+ NULL);
+
+ eab_contact_formatter_format_contact (vcard_formatter, contact, buffer);
g_output_stream_write_all (
stream, buffer->str, buffer->len,
NULL, cancellable, NULL);
g_string_free (buffer, TRUE);
-
+ g_object_unref (vcard_formatter);
} else {
CamelFolder *folder;
const gchar *message_uid;
const gchar *default_charset, *charset;
- gchar *str, *uri;
+ gchar *str, *uri, *button_iframe_uri;
gint length;
const gchar *label = NULL;
- EABContactDisplayMode mode;
const gchar *info = NULL;
gchar *access_key = NULL;
gchar *html_label;
- length = g_slist_length (vcard_part->contact_list);
+ length = g_slist_length ((GSList *) contacts);
folder = e_mail_part_list_get_folder (context->part_list);
message_uid = e_mail_part_list_get_message_uid (context->part_list);
@@ -109,29 +125,15 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
if (!charset)
charset = "";
- if (vcard_part->message_uid == NULL && message_uid != NULL)
- vcard_part->message_uid = g_strdup (message_uid);
-
- if (vcard_part->folder == NULL && folder != NULL)
- vcard_part->folder = g_object_ref (folder);
-
uri = e_mail_part_build_uri (
folder, message_uid,
"part_id", G_TYPE_STRING, e_mail_part_get_id (part),
"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
"formatter_default_charset", G_TYPE_STRING, default_charset,
"formatter_charset", G_TYPE_STRING, charset,
+ "vcard-format", G_TYPE_STRING, "compact",
NULL);
- mode = eab_contact_formatter_get_display_mode (vcard_part->formatter);
- if (mode == EAB_CONTACT_DISPLAY_RENDER_COMPACT) {
- mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
- label = _("Show F_ull vCard");
- } else {
- mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
- label = _("Show Com_pact vCard");
- }
-
str = g_strdup_printf (
"<div id=\"%s\">",
e_mail_part_get_id (part));
@@ -139,25 +141,65 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
stream, str, strlen (str), NULL, cancellable, NULL);
g_free (str);
- html_label = e_mail_formatter_parse_html_mnemonics (
- label, &access_key);
+ button_iframe_uri = e_mail_part_build_uri (
+ folder, message_uid,
+ "part_id", G_TYPE_STRING, e_mail_part_get_id (part),
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ "formatter_default_charset", G_TYPE_STRING, default_charset,
+ "formatter_charset", G_TYPE_STRING, charset,
+ "vcard-format", G_TYPE_STRING, "normal",
+ NULL);
+
+ label = _("Show F_ull vCard");
+ html_label = e_mail_formatter_parse_html_mnemonics (label, &access_key);
str = g_strdup_printf (
"<button type=\"button\" "
- "name=\"set-display-mode\" "
+ "name=\"set-display-mode-normal\" "
"id=\"%s\" "
"class=\"org-gnome-vcard-display-mode-button\" "
"value=\"%d\" "
+ "evo-iframe-uri=\"%s\" "
"style=\"margin-left: 0px\""
"accesskey=\"%s\">%s</button>",
e_mail_part_get_id (part),
- mode, access_key, html_label);
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL, button_iframe_uri, access_key,
+ html_label);
g_output_stream_write_all (
stream, str, strlen (str), NULL, cancellable, NULL);
g_free (str);
g_free (html_label);
+ g_free (button_iframe_uri);
+ g_clear_pointer (&access_key, g_free);
+
+ button_iframe_uri = e_mail_part_build_uri (
+ folder, message_uid,
+ "part_id", G_TYPE_STRING, e_mail_part_get_id (part),
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ "formatter_default_charset", G_TYPE_STRING, default_charset,
+ "formatter_charset", G_TYPE_STRING, charset,
+ "vcard-format", G_TYPE_STRING, "compact",
+ NULL);
- g_free (access_key);
- access_key = NULL;
+ label = _("Show Com_pact vCard");
+ html_label = e_mail_formatter_parse_html_mnemonics (label, &access_key);
+ str = g_strdup_printf (
+ "<button type=\"button\" "
+ "name=\"set-display-mode-compact\" "
+ "id=\"%s\" "
+ "class=\"org-gnome-vcard-display-mode-button\" "
+ "value=\"%d\" "
+ "evo-iframe-uri=\"%s\" "
+ "style=\"margin-left: 0px\""
+ "accesskey=\"%s\" hidden>%s</button>",
+ e_mail_part_get_id (part),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT, button_iframe_uri, access_key,
+ html_label);
+ g_output_stream_write_all (
+ stream, str, strlen (str), NULL, cancellable, NULL);
+ g_free (str);
+ g_free (html_label);
+ g_free (button_iframe_uri);
+ g_clear_pointer (&access_key, g_free);
html_label = e_mail_formatter_parse_html_mnemonics (
_("Save _To Addressbook"), &access_key);
@@ -170,18 +212,17 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
"<iframe width=\"100%%\" height=\"auto\" "
" class=\"-e-mail-formatter-frame-color -e-web-view-background-color\" "
" style=\"border: 1px solid;\""
- " src=\"%s\" name=\"%s\"></iframe>"
+ " src=\"%s\" id=\"%s\" name=\"%s\"></iframe>"
"</div>",
e_mail_part_get_id (part),
access_key, html_label, uri,
+ e_mail_part_get_id (part),
e_mail_part_get_id (part));
g_output_stream_write_all (
stream, str, strlen (str), NULL, cancellable, NULL);
g_free (str);
g_free (html_label);
-
- g_free (access_key);
- access_key = NULL;
+ g_clear_pointer (&access_key, g_free);
if (length == 2) {
info = _("There is one other contact.");
diff --git a/src/modules/vcard-inline/e-mail-parser-vcard.c b/src/modules/vcard-inline/e-mail-parser-vcard.c
index 6ec7e1cd4d..557b599edb 100644
--- a/src/modules/vcard-inline/e-mail-parser-vcard.c
+++ b/src/modules/vcard-inline/e-mail-parser-vcard.c
@@ -86,7 +86,7 @@ decode_vcard (EMailPartVCard *vcard_part,
string = (gchar *) array->data;
contact_list = eab_contact_list_from_string (string);
- vcard_part->contact_list = contact_list;
+ e_mail_part_vcard_take_contacts (vcard_part, contact_list);
g_object_unref (mime_part);
g_object_unref (stream);
@@ -109,10 +109,6 @@ empe_vcard_parse (EMailParserExtension *extension,
vcard_part = e_mail_part_vcard_new (part, part_id->str);
- vcard_part->formatter = g_object_new (
- EAB_TYPE_CONTACT_FORMATTER,
- "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT,
- "render-maps", FALSE, NULL);
g_object_ref (part);
decode_vcard (vcard_part, part);
diff --git a/src/modules/vcard-inline/e-mail-part-vcard.c b/src/modules/vcard-inline/e-mail-part-vcard.c
index 72cea885f3..57ac2cc433 100644
--- a/src/modules/vcard-inline/e-mail-part-vcard.c
+++ b/src/modules/vcard-inline/e-mail-part-vcard.c
@@ -32,13 +32,7 @@
((obj), E_TYPE_MAIL_PART_VCARD, EMailPartVCardPrivate))
struct _EMailPartVCardPrivate {
- gint placeholder;
-
- guint display_mode_toggled_signal_id;
- guint save_vcard_button_pressed_signal_id;
-
- GDBusProxy *web_extension;
- guint64 page_id;
+ GSList *contacts;
};
G_DEFINE_DYNAMIC_TYPE (
@@ -92,30 +86,28 @@ client_connect_cb (GObject *source_object,
}
static void
-save_vcard_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- EMailPartVCard *vcard_part)
+mail_part_vcard_save_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *element_class,
+ const gchar *element_value,
+ const GtkAllocation *element_position,
+ gpointer user_data)
{
+ EMailPartVCard *vcard_part = user_data;
EShell *shell;
ESource *source;
ESourceRegistry *registry;
ESourceSelector *selector;
GSList *contact_list;
- const gchar *extension_name, *button_value, *part_id;
+ const gchar *extension_name, *part_id;
GtkWidget *dialog;
- if (g_strcmp0 (signal_name, "VCardInlineSaveButtonPressed") != 0)
- return;
-
- g_variant_get (parameters, "(&s)", &button_value);
+ g_return_if_fail (E_IS_MAIL_PART_VCARD (vcard_part));
part_id = e_mail_part_get_id (E_MAIL_PART (vcard_part));
- if (!strstr (part_id, button_value))
+ if (!strstr (part_id, element_value))
return;
shell = e_shell_get_default ();
@@ -144,179 +136,19 @@ save_vcard_cb (GDBusConnection *connection,
g_return_if_fail (source != NULL);
contact_list = g_slist_copy_deep (
- vcard_part->contact_list,
+ vcard_part->priv->contacts,
(GCopyFunc) g_object_ref, NULL);
e_book_client_connect (
source, 30, NULL, client_connect_cb, contact_list);
}
-static void
-display_mode_toggle_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- EMailPartVCard *vcard_part)
-{
- EABContactDisplayMode mode;
- gchar *uri;
- gchar *html_label;
- gchar *access_key;
- const gchar *part_id;
- const gchar *button_id;
-
- if (g_strcmp0 (signal_name, "VCardInlineDisplayModeToggled") != 0)
- return;
-
- if (!vcard_part->priv->web_extension)
- return;
-
- g_variant_get (parameters, "(&s)", &button_id);
-
- part_id = e_mail_part_get_id (E_MAIL_PART (vcard_part));
-
- if (!strstr (part_id, button_id))
- return;
-
- mode = eab_contact_formatter_get_display_mode (vcard_part->formatter);
- if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
- mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
-
- html_label = e_mail_formatter_parse_html_mnemonics (
- _("Show F_ull vCard"), &access_key);
- } else {
- mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
-
- html_label = e_mail_formatter_parse_html_mnemonics (
- _("Show Com_pact vCard"), &access_key);
- }
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- vcard_part->priv->web_extension,
- "VCardInlineUpdateButton",
- g_variant_new (
- "(tsss)",
- vcard_part->priv->page_id,
- button_id,
- html_label,
- access_key),
- NULL);
-
- if (access_key)
- g_free (access_key);
-
- g_free (html_label);
-
- eab_contact_formatter_set_display_mode (vcard_part->formatter, mode);
-
- uri = e_mail_part_build_uri (
- vcard_part->folder, vcard_part->message_uid,
- "part_id", G_TYPE_STRING, part_id,
- "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW, NULL);
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- vcard_part->priv->web_extension,
- "VCardInlineSetIFrameSrc",
- g_variant_new (
- "(tss)",
- vcard_part->priv->page_id,
- button_id,
- uri),
- NULL);
-
- g_free (uri);
-}
-
-static void
-mail_part_vcard_set_web_extension_proxy (EMailPartVCard *part,
- GDBusProxy *proxy)
-{
- g_return_if_fail (E_IS_MAIL_PART_VCARD (part));
-
- if (part->priv->web_extension) {
- GDBusConnection *connection;
-
- connection = g_dbus_proxy_get_connection (part->priv->web_extension);
-
- if (connection && g_dbus_connection_is_closed (connection))
- connection = NULL;
-
- if (connection && part->priv->display_mode_toggled_signal_id)
- g_dbus_connection_signal_unsubscribe (connection,
part->priv->display_mode_toggled_signal_id);
- part->priv->display_mode_toggled_signal_id = 0;
-
- if (connection && part->priv->save_vcard_button_pressed_signal_id)
- g_dbus_connection_signal_unsubscribe (connection,
part->priv->save_vcard_button_pressed_signal_id);
- part->priv->save_vcard_button_pressed_signal_id = 0;
-
- g_clear_object (&part->priv->web_extension);
- }
-
- if (proxy) {
- GDBusConnection *connection;
-
- part->priv->web_extension = g_object_ref (proxy);
-
- connection = g_dbus_proxy_get_connection (proxy);
-
- if (connection && g_dbus_connection_is_closed (connection))
- connection = NULL;
-
- if (connection) {
- part->priv->display_mode_toggled_signal_id =
- g_dbus_connection_signal_subscribe (
- connection,
- g_dbus_proxy_get_name (proxy),
- g_dbus_proxy_get_interface_name (proxy),
- "VCardInlineDisplayModeToggled",
- g_dbus_proxy_get_object_path (proxy),
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback) display_mode_toggle_cb,
- part,
- NULL);
-
- part->priv->save_vcard_button_pressed_signal_id =
- g_dbus_connection_signal_subscribe (
- connection,
- g_dbus_proxy_get_name (proxy),
- g_dbus_proxy_get_interface_name (proxy),
- "VCardInlineSaveButtonPressed",
- g_dbus_proxy_get_object_path (proxy),
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback) save_vcard_cb,
- part,
- NULL);
- }
- }
-}
-
-static void
-mail_part_vcard_dispose (GObject *object)
-{
- EMailPartVCard *part = E_MAIL_PART_VCARD (object);
-
- g_clear_object (&part->contact_display);
- g_clear_object (&part->message_label);
- g_clear_object (&part->formatter);
- g_clear_object (&part->folder);
-
- mail_part_vcard_set_web_extension_proxy (part, NULL);
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_mail_part_vcard_parent_class)->dispose (object);
-}
-
static void
mail_part_vcard_finalize (GObject *object)
{
EMailPartVCard *part = E_MAIL_PART_VCARD (object);
- g_slist_free_full (part->contact_list, g_object_unref);
- g_free (part->message_uid);
+ g_slist_free_full (part->priv->contacts, g_object_unref);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_mail_part_vcard_parent_class)->finalize (object);
@@ -348,34 +180,14 @@ mail_part_vcard_constructed (GObject *object)
}
static void
-mail_part_vcard_bind_dom_element (EMailPart *part,
- EWebView *web_view,
- guint64 page_id,
- const gchar *element_id)
+mail_part_vcard_content_loaded (EMailPart *part,
+ EWebView *web_view)
{
- EMailPartVCard *vcard_part;
- GDBusProxy *web_extension;
-
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (E_IS_MAIL_PART_VCARD (part));
- web_extension = e_web_view_get_web_extension_proxy (web_view);
- if (!web_extension)
- return;
-
- vcard_part = E_MAIL_PART_VCARD (part);
- vcard_part->priv->page_id = page_id;
-
- mail_part_vcard_set_web_extension_proxy (vcard_part, web_extension);
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- web_extension,
- "VCardInlineBindDOM",
- g_variant_new (
- "(ts)",
- vcard_part->priv->page_id,
- element_id),
- NULL);
+ e_web_view_register_element_clicked (web_view, "org-gnome-vcard-save-button",
+ mail_part_vcard_save_clicked_cb, part);
}
static void
@@ -387,12 +199,11 @@ e_mail_part_vcard_class_init (EMailPartVCardClass *class)
g_type_class_add_private (class, sizeof (EMailPartVCardPrivate));
object_class = G_OBJECT_CLASS (class);
- object_class->dispose = mail_part_vcard_dispose;
object_class->finalize = mail_part_vcard_finalize;
object_class->constructed = mail_part_vcard_constructed;
mail_part_class = E_MAIL_PART_CLASS (class);
- mail_part_class->bind_dom_element = mail_part_vcard_bind_dom_element;
+ mail_part_class->content_loaded = mail_part_vcard_content_loaded;
}
static void
@@ -426,3 +237,20 @@ e_mail_part_vcard_new (CamelMimePart *mime_part,
"id", id, "mime-part", mime_part, NULL);
}
+void
+e_mail_part_vcard_take_contacts (EMailPartVCard *vcard_part,
+ GSList *contacts)
+{
+ g_return_if_fail (E_IS_MAIL_PART_VCARD (vcard_part));
+
+ g_slist_free_full (vcard_part->priv->contacts, g_object_unref);
+ vcard_part->priv->contacts = contacts;
+}
+
+const GSList *
+e_mail_part_vcard_get_contacts (EMailPartVCard *vcard_part)
+{
+ g_return_val_if_fail (E_IS_MAIL_PART_VCARD (vcard_part), NULL);
+
+ return vcard_part->priv->contacts;
+}
diff --git a/src/modules/vcard-inline/e-mail-part-vcard.h b/src/modules/vcard-inline/e-mail-part-vcard.h
index 9aeb595482..c2e3b0a360 100644
--- a/src/modules/vcard-inline/e-mail-part-vcard.h
+++ b/src/modules/vcard-inline/e-mail-part-vcard.h
@@ -50,15 +50,6 @@ typedef struct _EMailPartVCardPrivate EMailPartVCardPrivate;
struct _EMailPartVCard {
EMailPart parent;
EMailPartVCardPrivate *priv;
-
- GSList *contact_list;
- GtkWidget *contact_display;
- GtkWidget *message_label;
-
- EABContactFormatter *formatter;
-
- CamelFolder *folder;
- gchar *message_uid;
};
struct _EMailPartVCardClass {
@@ -70,6 +61,9 @@ void e_mail_part_vcard_type_register (GTypeModule *type_module);
EMailPartVCard *
e_mail_part_vcard_new (CamelMimePart *mime_part,
const gchar *id);
+void e_mail_part_vcard_take_contacts (EMailPartVCard *vcard_part,
+ GSList *contacts);
+const GSList * e_mail_part_vcard_get_contacts (EMailPartVCard *vcard_part);
G_END_DECLS
diff --git a/src/modules/webkit-editor/web-extension/CMakeLists.txt
b/src/modules/webkit-editor/web-extension/CMakeLists.txt
index a7f07ff742..ed59c7ebc7 100644
--- a/src/modules/webkit-editor/web-extension/CMakeLists.txt
+++ b/src/modules/webkit-editor/web-extension/CMakeLists.txt
@@ -1,3 +1,27 @@
+macro(add_simple_webextension_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdirsvar _ldflagsvar
_destdir)
+ set(wex_deps
+ ${${_depsvar}}
+ )
+ set(wex_cflags
+ ${${_cflagsvar}}
+ ${WEB_EXTENSIONS_CFLAGS}
+ )
+ set(wex_incdirs
+ ${${_incdirsvar}}
+ ${WEB_EXTENSIONS_INCLUDE_DIRS}
+ )
+ set(wex_ldflags
+ ${${_ldflagsvar}}
+ ${WEB_EXTENSIONS_LDFLAGS}
+ )
+
+ add_simple_module(${_name} ${_sourcesvar} wex_deps ${_defsvar} wex_cflags wex_incdirs wex_ldflags
${_destdir})
+endmacro(add_simple_webextension_module)
+
+macro(add_webextension_editor_module _name _sourcesvar _depsvar _defsvar _cflagsvar _incdirsvar _ldflagsvar)
+ add_simple_webextension_module(${_name} ${_sourcesvar} ${_depsvar} ${_defsvar} ${_cflagsvar}
${_incdirsvar} ${_ldflagsvar} "${webextensionswebkiteditordir}")
+endmacro(add_webextension_editor_module)
+
set(extra_deps
evolution-mail
)
@@ -6,6 +30,8 @@ set(sources
e-composer-dom-functions.h
e-dialogs-dom-functions.c
e-dialogs-dom-functions.h
+ e-dom-utils.c
+ e-dom-utils.h
e-editor-dom-functions.c
e-editor-dom-functions.h
e-editor-page.c
diff --git a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
index 4e1b7d1cc5..bd840c2537 100644
--- a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
@@ -24,8 +24,7 @@
#include <camel/camel.h>
-#include "web-extensions/e-dom-utils.h"
-
+#include "e-dom-utils.h"
#include "e-editor-page.h"
#include "e-editor-dom-functions.h"
#include "e-editor-undo-redo-manager.h"
diff --git a/src/modules/webkit-editor/web-extension/e-dialogs-dom-functions.c
b/src/modules/webkit-editor/web-extension/e-dialogs-dom-functions.c
index 64f6c28c10..ce3c2d6ad4 100644
--- a/src/modules/webkit-editor/web-extension/e-dialogs-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-dialogs-dom-functions.c
@@ -19,8 +19,7 @@
#include <webkitdom/webkitdom.h>
-#include "web-extensions/e-dom-utils.h"
-
+#include "e-dom-utils.h"
#include "e-editor-dom-functions.h"
#include "e-editor-undo-redo-manager.h"
diff --git a/src/modules/webkit-editor/web-extension/e-dom-utils.c
b/src/modules/webkit-editor/web-extension/e-dom-utils.c
new file mode 100644
index 0000000000..33776dc0dd
--- /dev/null
+++ b/src/modules/webkit-editor/web-extension/e-dom-utils.c
@@ -0,0 +1,621 @@
+/*
+ * e-dom-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "evolution-config.h"
+
+#include <string.h>
+
+#include <webkitdom/webkitdom.h>
+
+#include "e-dom-utils.h"
+
+void
+e_dom_utils_create_and_add_css_style_sheet (WebKitDOMDocument *document,
+ const gchar *style_sheet_id)
+{
+ WebKitDOMElement *style_element;
+
+ style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
+
+ if (!style_element) {
+ WebKitDOMText *dom_text;
+ WebKitDOMHTMLHeadElement *head;
+
+ dom_text = webkit_dom_document_create_text_node (document, "");
+
+ /* Create new <style> element */
+ style_element = webkit_dom_document_create_element (document, "style", NULL);
+ webkit_dom_element_set_id (
+ style_element,
+ style_sheet_id);
+ webkit_dom_html_style_element_set_media (
+ WEBKIT_DOM_HTML_STYLE_ELEMENT (style_element),
+ "screen");
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (style_element),
+ /* WebKit hack - we have to insert empty TextNode into style element */
+ WEBKIT_DOM_NODE (dom_text),
+ NULL);
+
+ head = webkit_dom_document_get_head (document);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (head),
+ WEBKIT_DOM_NODE (style_element),
+ NULL);
+ }
+}
+
+/**
+ * e_html_editor_dom_node_find_parent_element:
+ * @node: Start node
+ * @tagname: Tag name of element to search
+ *
+ * Recursively searches for first occurance of element with given @tagname
+ * that is parent of given @node.
+ *
+ * Returns: A #WebKitDOMElement with @tagname representing parent of @node or
+ * @NULL when @node has no parent with given @tagname. When @node matches @tagname,
+ * then the @node is returned.
+ */
+WebKitDOMElement *
+dom_node_find_parent_element (WebKitDOMNode *node,
+ const gchar *tagname)
+{
+ WebKitDOMNode *tmp_node = node;
+ gint taglen = strlen (tagname);
+
+ while (tmp_node) {
+ if (WEBKIT_DOM_IS_ELEMENT (tmp_node)) {
+ gchar *node_tagname;
+
+ node_tagname = webkit_dom_element_get_tag_name (
+ WEBKIT_DOM_ELEMENT (tmp_node));
+
+ if (node_tagname &&
+ (strlen (node_tagname) == taglen) &&
+ (g_ascii_strncasecmp (node_tagname, tagname, taglen) == 0)) {
+ g_free (node_tagname);
+ return WEBKIT_DOM_ELEMENT (tmp_node);
+ }
+
+ g_free (node_tagname);
+ }
+
+ tmp_node = webkit_dom_node_get_parent_node (tmp_node);
+ }
+
+ return NULL;
+}
+
+gboolean
+element_has_id (WebKitDOMElement *element,
+ const gchar* id)
+{
+ gchar *element_id;
+
+ if (!element)
+ return FALSE;
+
+ if (!WEBKIT_DOM_IS_ELEMENT (element))
+ return FALSE;
+
+ element_id = webkit_dom_element_get_id (element);
+
+ if (element_id && g_ascii_strcasecmp (element_id, id) == 0) {
+ g_free (element_id);
+ return TRUE;
+ }
+ g_free (element_id);
+
+ return FALSE;
+}
+
+gboolean
+element_has_tag (WebKitDOMElement *element,
+ const gchar* tag)
+{
+ gchar *element_tag;
+
+ if (!WEBKIT_DOM_IS_ELEMENT (element))
+ return FALSE;
+
+ element_tag = webkit_dom_element_get_tag_name (element);
+
+ if (g_ascii_strcasecmp (element_tag, tag) != 0) {
+ g_free (element_tag);
+ return FALSE;
+ }
+ g_free (element_tag);
+
+ return TRUE;
+}
+
+gboolean
+element_has_class (WebKitDOMElement *element,
+ const gchar* class)
+{
+ gchar *element_class;
+
+ if (!element)
+ return FALSE;
+
+ if (!WEBKIT_DOM_IS_ELEMENT (element))
+ return FALSE;
+
+ element_class = webkit_dom_element_get_class_name (element);
+
+ if (element_class && g_strstr_len (element_class, -1, class)) {
+ g_free (element_class);
+ return TRUE;
+ }
+ g_free (element_class);
+
+ return FALSE;
+}
+
+void
+element_add_class (WebKitDOMElement *element,
+ const gchar* class)
+{
+ gchar *element_class;
+ gchar *new_class;
+
+ if (!WEBKIT_DOM_IS_ELEMENT (element))
+ return;
+
+ if (element_has_class (element, class))
+ return;
+
+ element_class = webkit_dom_element_get_class_name (element);
+
+ if (!element_class)
+ new_class = g_strdup (class);
+ else
+ new_class = g_strconcat (element_class, " ", class, NULL);
+
+ webkit_dom_element_set_class_name (element, new_class);
+
+ g_free (element_class);
+ g_free (new_class);
+}
+
+void
+element_remove_class (WebKitDOMElement *element,
+ const gchar* class)
+{
+ gchar *element_class, *final_class;
+ GRegex *regex;
+ gchar *pattern = NULL;
+
+ if (!WEBKIT_DOM_IS_ELEMENT (element))
+ return;
+
+ if (!element_has_class (element, class))
+ return;
+
+ element_class = webkit_dom_element_get_class_name (element);
+
+ pattern = g_strconcat ("[\\s]*", class, "[\\s]*", NULL);
+ regex = g_regex_new (pattern, 0, 0, NULL);
+ final_class = g_regex_replace (regex, element_class, -1, 0, " ", 0, NULL);
+
+ if (g_strcmp0 (final_class, " ") != 0)
+ webkit_dom_element_set_class_name (element, final_class);
+ else
+ webkit_dom_element_remove_attribute (element, "class");
+
+ g_free (element_class);
+ g_free (final_class);
+ g_free (pattern);
+ g_regex_unref (regex);
+}
+
+void
+element_rename_attribute (WebKitDOMElement *element,
+ const gchar *from,
+ const gchar *to)
+{
+ gchar *value;
+
+ if (!webkit_dom_element_has_attribute (element, from))
+ return;
+
+ value = webkit_dom_element_get_attribute (element, from);
+ webkit_dom_element_set_attribute (element, to, (value && *value) ? value : "", NULL);
+ webkit_dom_element_remove_attribute (element, from);
+ g_free (value);
+}
+
+void
+remove_node (WebKitDOMNode *node)
+{
+ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+ if (parent)
+ webkit_dom_node_remove_child (parent, node, NULL);
+}
+
+void
+remove_node_if_empty (WebKitDOMNode *node)
+{
+ WebKitDOMNode *child;
+
+ if (!WEBKIT_DOM_IS_NODE (node))
+ return;
+
+ if ((child = webkit_dom_node_get_first_child (node))) {
+ WebKitDOMNode *prev_sibling, *next_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (child);
+ next_sibling = webkit_dom_node_get_next_sibling (child);
+ /* Empty or BR as sibling, but no sibling after it. */
+ if (!webkit_dom_node_get_first_child (child) &&
+ !WEBKIT_DOM_IS_TEXT (child) &&
+ (!prev_sibling ||
+ (WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling) &&
+ !webkit_dom_node_get_previous_sibling (prev_sibling))) &&
+ (!next_sibling ||
+ (WEBKIT_DOM_IS_HTML_BR_ELEMENT (next_sibling) &&
+ !webkit_dom_node_get_next_sibling (next_sibling)))) {
+
+ remove_node (node);
+ } else {
+ gchar *text_content;
+
+ text_content = webkit_dom_node_get_text_content (node);
+ if (!text_content)
+ remove_node (node);
+
+ if (text_content && !*text_content)
+ remove_node (node);
+
+ if (g_strcmp0 (text_content, UNICODE_ZERO_WIDTH_SPACE) == 0)
+ remove_node (node);
+
+ g_free (text_content);
+ }
+ } else
+ remove_node (node);
+}
+
+WebKitDOMNode *
+split_list_into_two (WebKitDOMNode *item,
+ gint level)
+{
+ gint current_level = 1;
+ WebKitDOMDocument *document;
+ WebKitDOMDocumentFragment *fragment;
+ WebKitDOMNode *parent, *prev_parent = NULL, *tmp;
+
+ document = webkit_dom_node_get_owner_document (item);
+ fragment = webkit_dom_document_create_document_fragment (document);
+
+ tmp = item;
+ parent = webkit_dom_node_get_parent_node (item);
+ while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ WebKitDOMNode *clone, *first_child, *insert_before = NULL, *sibling;
+
+ first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
+ clone = webkit_dom_node_clone_node_with_error (parent, FALSE, NULL);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (fragment), clone, first_child, NULL);
+
+ if (first_child)
+ insert_before = webkit_dom_node_get_first_child (first_child);
+
+ while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child)))
+ webkit_dom_node_insert_before (first_child, sibling, insert_before, NULL);
+
+ while (tmp && (sibling = webkit_dom_node_get_next_sibling (tmp)))
+ webkit_dom_node_append_child (clone, sibling, NULL);
+
+ if (tmp)
+ webkit_dom_node_insert_before (
+ clone, tmp, webkit_dom_node_get_first_child (clone), NULL);
+
+ prev_parent = parent;
+ tmp = webkit_dom_node_get_next_sibling (parent);
+ parent = webkit_dom_node_get_parent_node (parent);
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
+ insert_before = webkit_dom_node_get_first_child (first_child);
+ while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child))) {
+ webkit_dom_node_insert_before (
+ first_child, sibling, insert_before, NULL);
+ }
+ }
+
+ if (current_level >= level && level >= 0)
+ break;
+
+ current_level++;
+ }
+
+ tmp = webkit_dom_node_insert_before (
+ parent,
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment)),
+ prev_parent ? webkit_dom_node_get_next_sibling (prev_parent) : NULL,
+ NULL);
+ remove_node_if_empty (prev_parent);
+
+ return tmp;
+}
+
+WebKitDOMElement *
+dom_create_selection_marker (WebKitDOMDocument *document,
+ gboolean selection_start_marker)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_create_element (
+ document, "SPAN", NULL);
+ webkit_dom_element_set_id (
+ element,
+ selection_start_marker ?
+ "-x-evo-selection-start-marker" :
+ "-x-evo-selection-end-marker");
+
+ return element;
+}
+
+void
+dom_remove_selection_markers (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *marker;
+
+ marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+ if (marker)
+ remove_node (WEBKIT_DOM_NODE (marker));
+ marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-end-marker");
+ if (marker)
+ remove_node (WEBKIT_DOM_NODE (marker));
+}
+
+void
+dom_add_selection_markers_into_element_start (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ dom_remove_selection_markers (document);
+ marker = dom_create_selection_marker (document, FALSE);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (marker),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+ NULL);
+ if (selection_end_marker)
+ *selection_end_marker = marker;
+
+ marker = dom_create_selection_marker (document, TRUE);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (marker),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+ NULL);
+ if (selection_start_marker)
+ *selection_start_marker = marker;
+}
+
+void
+dom_add_selection_markers_into_element_end (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ dom_remove_selection_markers (document);
+ marker = dom_create_selection_marker (document, TRUE);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+ if (selection_start_marker)
+ *selection_start_marker = marker;
+
+ marker = dom_create_selection_marker (document, FALSE);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+ if (selection_end_marker)
+ *selection_end_marker = marker;
+}
+
+gboolean
+node_is_list_or_item (WebKitDOMNode *node)
+{
+ return node && (
+ WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_LI_ELEMENT (node));
+}
+
+gboolean
+node_is_list (WebKitDOMNode *node)
+{
+ return node && (
+ WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node));
+}
+
+/**
+ * e_html_editor_selection_get_list_format_from_node:
+ * @node: an #WebKitDOMNode
+ *
+ * Returns block format of given list.
+ *
+ * Returns: #EContentEditorBlockFormat
+ */
+EContentEditorBlockFormat
+dom_get_list_format_from_node (WebKitDOMNode *node)
+{
+ EContentEditorBlockFormat format =
+ E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST;
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (node))
+ return E_CONTENT_EDITOR_BLOCK_FORMAT_NONE;
+
+ if (WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node))
+ return format;
+
+ if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node)) {
+ gchar *type_value = webkit_dom_element_get_attribute (
+ WEBKIT_DOM_ELEMENT (node), "type");
+
+ if (!type_value)
+ return E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST;
+
+ if (!*type_value)
+ format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST;
+ else if (g_ascii_strcasecmp (type_value, "A") == 0)
+ format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA;
+ else if (g_ascii_strcasecmp (type_value, "I") == 0)
+ format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN;
+ g_free (type_value);
+
+ return format;
+ }
+
+ return E_CONTENT_EDITOR_BLOCK_FORMAT_NONE;
+}
+
+void
+merge_list_into_list (WebKitDOMNode *from,
+ WebKitDOMNode *to,
+ gboolean insert_before)
+{
+ WebKitDOMNode *item, *insert_before_node;
+
+ if (!(to && from))
+ return;
+
+ insert_before_node = webkit_dom_node_get_first_child (to);
+ while ((item = webkit_dom_node_get_first_child (from)) != NULL) {
+ if (insert_before)
+ webkit_dom_node_insert_before (
+ to, item, insert_before_node, NULL);
+ else
+ webkit_dom_node_append_child (to, item, NULL);
+ }
+
+ if (!webkit_dom_node_has_child_nodes (from))
+ remove_node (from);
+
+}
+
+void
+merge_lists_if_possible (WebKitDOMNode *list)
+{
+ EContentEditorBlockFormat format, prev, next;
+ gint ii, length;
+ WebKitDOMNode *prev_sibling, *next_sibling;
+ WebKitDOMNodeList *lists = NULL;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (list));
+ next_sibling = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (list));
+
+ format = dom_get_list_format_from_node (list),
+ prev = dom_get_list_format_from_node (prev_sibling);
+ next = dom_get_list_format_from_node (next_sibling);
+
+ if (format != E_CONTENT_EDITOR_BLOCK_FORMAT_NONE) {
+ if (format == prev && prev != E_CONTENT_EDITOR_BLOCK_FORMAT_NONE)
+ merge_list_into_list (prev_sibling, list, TRUE);
+
+ if (format == next && next != E_CONTENT_EDITOR_BLOCK_FORMAT_NONE)
+ merge_list_into_list (next_sibling, list, FALSE);
+ }
+
+ lists = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (list), "ol + ol, ul + ul", NULL);
+ length = webkit_dom_node_list_get_length (lists);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (lists, ii);
+ merge_lists_if_possible (node);
+ }
+ g_clear_object (&lists);
+}
+
+WebKitDOMElement *
+get_parent_block_element (WebKitDOMNode *node)
+{
+ WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
+
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent))
+ return WEBKIT_DOM_IS_ELEMENT (node) ? WEBKIT_DOM_ELEMENT (node) : NULL;
+
+ while (parent &&
+ !WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_HEADING_ELEMENT (parent) &&
+ !WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (parent) &&
+ !element_has_tag (parent, "address")) {
+ parent = webkit_dom_node_get_parent_element (
+ WEBKIT_DOM_NODE (parent));
+ }
+
+ return parent;
+}
+
+gchar *
+dom_get_node_inner_html (WebKitDOMNode *node)
+{
+ gchar *inner_html;
+ WebKitDOMDocument *document;
+ WebKitDOMElement *div;
+
+ document = webkit_dom_node_get_owner_document (node);
+ div = webkit_dom_document_create_element (document, "div", NULL);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (div),
+ webkit_dom_node_clone_node_with_error (node, TRUE, NULL),
+ NULL);
+
+ inner_html = webkit_dom_element_get_inner_html (div);
+ remove_node (WEBKIT_DOM_NODE (div));
+
+ return inner_html;
+}
+
+void
+dom_element_swap_attributes (WebKitDOMElement *element,
+ const gchar *from,
+ const gchar *to)
+{
+ gchar *value_from, *value_to;
+
+ if (!webkit_dom_element_has_attribute (element, from) ||
+ !webkit_dom_element_has_attribute (element, to))
+ return;
+
+ value_from = webkit_dom_element_get_attribute (element, from);
+ value_to = webkit_dom_element_get_attribute (element, to);
+ webkit_dom_element_set_attribute (element, to, (value_from && *value_from) ? value_from : "", NULL);
+ webkit_dom_element_set_attribute (element, from, (value_to && *value_to) ? value_to : "", NULL);
+ g_free (value_from);
+ g_free (value_to);
+}
diff --git a/src/modules/webkit-editor/web-extension/e-dom-utils.h
b/src/modules/webkit-editor/web-extension/e-dom-utils.h
new file mode 100644
index 0000000000..dceb65c17e
--- /dev/null
+++ b/src/modules/webkit-editor/web-extension/e-dom-utils.h
@@ -0,0 +1,91 @@
+/*
+ * e-dom-utils.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_DOM_UTILS_H
+#define E_DOM_UTILS_H
+
+#define E_UTIL_INCLUDE_WITHOUT_WEBKIT
+#include <e-util/e-util.h>
+#undef E_UTIL_INCLUDE_WITHOUT_WEBKIT
+
+#include <webkitdom/webkitdom.h>
+
+#include <gtk/gtk.h>
+
+#define UNICODE_ZERO_WIDTH_SPACE "\xe2\x80\x8b"
+#define UNICODE_NBSP "\xc2\xa0"
+
+#define E_EVOLUTION_BLOCKQUOTE_STYLE "margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"
+
+G_BEGIN_DECLS
+
+void e_dom_utils_create_and_add_css_style_sheet
+ (WebKitDOMDocument *document,
+ const gchar *style_sheet_id);
+WebKitDOMElement *
+ dom_node_find_parent_element (WebKitDOMNode *node,
+ const gchar *tagname);
+gboolean element_has_id (WebKitDOMElement *element,
+ const gchar* id);
+gboolean element_has_tag (WebKitDOMElement *element,
+ const gchar* tag);
+gboolean element_has_class (WebKitDOMElement *element,
+ const gchar* class);
+void element_add_class (WebKitDOMElement *element,
+ const gchar* class);
+void element_remove_class (WebKitDOMElement *element,
+ const gchar* class);
+void element_rename_attribute (WebKitDOMElement *element,
+ const gchar *from,
+ const gchar *to);
+void remove_node (WebKitDOMNode *node);
+void remove_node_if_empty (WebKitDOMNode *node);
+WebKitDOMNode * split_list_into_two (WebKitDOMNode *item,
+ gint level);
+WebKitDOMElement *
+ dom_create_selection_marker (WebKitDOMDocument *document,
+ gboolean start);
+void dom_add_selection_markers_into_element_start
+ (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker);
+void dom_add_selection_markers_into_element_end
+ (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker);
+void dom_remove_selection_markers (WebKitDOMDocument *document);
+gboolean node_is_list (WebKitDOMNode *node);
+gboolean node_is_list_or_item (WebKitDOMNode *node);
+EContentEditorBlockFormat
+ dom_get_list_format_from_node (WebKitDOMNode *node);
+void merge_list_into_list (WebKitDOMNode *from,
+ WebKitDOMNode *to,
+ gboolean insert_before);
+void merge_lists_if_possible (WebKitDOMNode *list);
+WebKitDOMElement *
+ get_parent_block_element (WebKitDOMNode *node);
+gchar * dom_get_node_inner_html (WebKitDOMNode *node);
+void dom_element_swap_attributes (WebKitDOMElement *element,
+ const gchar *from,
+ const gchar *to);
+
+G_END_DECLS
+
+#endif /* E_DOM_UTILS_H */
diff --git a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
index 97bf1ac350..35cab8cc10 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
@@ -20,8 +20,7 @@
#include <webkitdom/webkitdom.h>
-#include "web-extensions/e-dom-utils.h"
-
+#include "e-dom-utils.h"
#include "e-editor-page.h"
#include "e-editor-undo-redo-manager.h"
diff --git a/src/modules/webkit-editor/web-extension/e-editor-page.c
b/src/modules/webkit-editor/web-extension/e-editor-page.c
index 18d50837b6..8164900575 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-page.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-page.c
@@ -20,8 +20,7 @@
#include <glib.h>
#include <webkit2/webkit-web-extension.h>
-#include "web-extensions/e-dom-utils.h"
-
+#include "e-dom-utils.h"
#include "e-editor-dom-functions.h"
#include "e-editor-web-extension.h"
#include "e-editor-undo-redo-manager.h"
diff --git a/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
b/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
index ff1b8f5c63..c4053eb47f 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
@@ -20,8 +20,7 @@
#include <webkitdom/webkitdom.h>
-#include "web-extensions/e-dom-utils.h"
-
+#include "e-dom-utils.h"
#include "e-editor-page.h"
#include "e-editor-dom-functions.h"
#include "e-editor-undo-redo-manager.h"
diff --git a/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
b/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
index 3138556dcd..05a1d4ac8d 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
@@ -32,8 +32,7 @@
#include "mail/e-http-request.h"
#undef E_UTIL_INCLUDE_WITHOUT_WEBKIT
-#include "web-extensions/e-dom-utils.h"
-
+//#include "e-dom-utils.h"
#include "e-editor-page.h"
#include "e-composer-dom-functions.h"
#include "e-dialogs-dom-functions.h"
diff --git a/src/plugins/mail-to-task/mail-to-task.c b/src/plugins/mail-to-task/mail-to-task.c
index e28dba3e8d..ca443dcda5 100644
--- a/src/plugins/mail-to-task/mail-to-task.c
+++ b/src/plugins/mail-to-task/mail-to-task.c
@@ -1091,43 +1091,71 @@ text_contains_nonwhitespace (const gchar *text,
return p - text < len - 1 && c != 0;
}
-static gchar *
-get_selected_text (EMailReader *reader)
+static void
+get_charsets (EMailReader *reader,
+ gchar **default_charset,
+ gchar **forced_charset)
{
EMailDisplay *display;
- gchar *text = NULL;
+ EMailFormatter *formatter;
display = e_mail_reader_get_mail_display (reader);
+ formatter = e_mail_display_get_formatter (display);
- if (!e_web_view_is_selection_active (E_WEB_VIEW (display)))
- return NULL;
+ *default_charset = e_mail_formatter_dup_default_charset (formatter);
+ *forced_charset = e_mail_formatter_dup_charset (formatter);
+}
- text = e_mail_display_get_selection_plain_text_sync (display, NULL, NULL);
+static void
+start_mail_to_event_thread (AsyncData *data)
+{
+ GThread *thread = NULL;
+ GError *error = NULL;
- if (!text)
- return NULL;
+ thread = g_thread_try_new (NULL, (GThreadFunc) do_mail_to_event, data, &error);
- if (!text_contains_nonwhitespace (text, strlen (text))) {
- g_free (text);
- return NULL;
+ if (error != NULL) {
+ g_warning (G_STRLOC ": %s", error->message);
+ g_error_free (error);
+ } else {
+ g_thread_unref (thread);
}
-
- return text;
}
static void
-get_charsets (EMailReader *reader,
- gchar **default_charset,
- gchar **forced_charset)
+mail_to_task_got_selection_jsc_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EMailDisplay *display;
- EMailFormatter *formatter;
+ AsyncData *data = user_data;
+ GSList *texts = NULL;
+ gchar *text;
+ GError *error = NULL;
- display = e_mail_reader_get_mail_display (reader);
- formatter = e_mail_display_get_formatter (display);
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW (source_object));
- *default_charset = e_mail_formatter_dup_default_charset (formatter);
- *forced_charset = e_mail_formatter_dup_charset (formatter);
+ if (!e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source_object), result, &texts, &error)) {
+ texts = NULL;
+ g_warning ("%s: Failed to get view selection: %s", G_STRFUNC, error ? error->message :
"Unknown error");
+ }
+
+ text = texts ? texts->data : NULL;
+
+ if (text && !text_contains_nonwhitespace (text, strlen (text))) {
+ text = NULL;
+ } else {
+ /* Steal the pointer */
+ if (texts)
+ texts->data = NULL;
+ }
+
+ data->selected_text = text;
+
+ start_mail_to_event_thread (data);
+
+ g_slist_free_full (texts, g_free);
+ g_clear_error (&error);
}
static void
@@ -1227,8 +1255,7 @@ mail_to_event (ECalClientSourceType source_type,
if (source) {
/* if a source has been selected, perform the mail2event operation */
AsyncData *data = NULL;
- GThread *thread = NULL;
- GError *error = NULL;
+ EMailDisplay *mail_display;
/* Fill the elements in AsynData */
data = g_new0 (AsyncData, 1);
@@ -1241,18 +1268,15 @@ mail_to_event (ECalClientSourceType source_type,
data->with_attendees = with_attendees;
get_charsets (reader, &data->default_charset, &data->forced_charset);
- if (uids->len == 1)
- data->selected_text = get_selected_text (reader);
- else
- data->selected_text = NULL;
+ mail_display = e_mail_reader_get_mail_display (reader);
- thread = g_thread_try_new (
- NULL, (GThreadFunc) do_mail_to_event, data, &error);
- if (error != NULL) {
- g_warning (G_STRLOC ": %s", error->message);
- g_error_free (error);
+ if (uids->len == 1 && e_web_view_has_selection (E_WEB_VIEW (mail_display))) {
+ e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (mail_display), E_TEXT_FORMAT_PLAIN,
NULL,
+ mail_to_task_got_selection_jsc_cb, data);
} else {
- g_thread_unref (thread);
+ data->selected_text = NULL;
+
+ start_mail_to_event_thread (data);
}
}
diff --git a/src/web-extensions/CMakeLists.txt b/src/web-extensions/CMakeLists.txt
index 82ba059de0..35151503fe 100644
--- a/src/web-extensions/CMakeLists.txt
+++ b/src/web-extensions/CMakeLists.txt
@@ -3,56 +3,9 @@ set(DEPENDENCIES
)
set(SOURCES
- e-dom-utils.h
- e-dom-utils.c
-)
-
-add_library(edomutils SHARED
- ${SOURCES}
-)
-
-add_dependencies(edomutils
- ${DEPENDENCIES}
-)
-
-target_compile_definitions(edomutils PRIVATE
- -DG_LOG_DOMAIN=\"edomutils\"
- -DEVOLUTION_IMAGESDIR=\"${imagesdir}\"
-)
-
-target_compile_options(edomutils PUBLIC
- ${EVOLUTION_DATA_SERVER_CFLAGS}
- ${GNOME_PLATFORM_CFLAGS}
-)
-
-target_include_directories(edomutils PUBLIC
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}/src
- ${CMAKE_SOURCE_DIR}/src
- ${CMAKE_CURRENT_BINARY_DIR}
- ${EVOLUTION_DATA_SERVER_INCLUDE_DIRS}
- ${GNOME_PLATFORM_INCLUDE_DIRS}
-)
-
-target_link_libraries(edomutils
- ${DEPENDENCIES}
- ${EVOLUTION_DATA_SERVER_LDFLAGS}
- ${GNOME_PLATFORM_LDFLAGS}
-)
-
-install(TARGETS edomutils
- DESTINATION ${privsolibdir}
-)
-
-set(SOURCES
- e-dom-utils.h
- e-dom-utils.c
- e-itip-formatter-dom-utils.h
- e-itip-formatter-dom-utils.c
e-web-extension.h
e-web-extension.c
e-web-extension-main.c
- e-web-extension-names.h
)
add_library(ewebextension MODULE
@@ -65,12 +18,10 @@ add_dependencies(ewebextension
target_compile_definitions(ewebextension PRIVATE
-DG_LOG_DOMAIN=\"ewebextension\"
- -DEVOLUTION_IMAGESDIR=\"${imagesdir}\"
+ -DEVOLUTION_WEBKITDATADIR=\"${webkitdatadir}\"
)
target_compile_options(ewebextension PUBLIC
- ${EVOLUTION_DATA_SERVER_CFLAGS}
- ${GNOME_PLATFORM_CFLAGS}
${WEB_EXTENSIONS_CFLAGS}
)
@@ -79,15 +30,11 @@ target_include_directories(ewebextension PUBLIC
${CMAKE_BINARY_DIR}/src
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_BINARY_DIR}
- ${EVOLUTION_DATA_SERVER_INCLUDE_DIRS}
- ${GNOME_PLATFORM_INCLUDE_DIRS}
${WEB_EXTENSIONS_INCLUDE_DIRS}
)
target_link_libraries(ewebextension
${DEPENDENCIES}
- ${EVOLUTION_DATA_SERVER_LDFLAGS}
- ${GNOME_PLATFORM_LDFLAGS}
${WEB_EXTENSIONS_LDFLAGS}
)
diff --git a/src/web-extensions/e-web-extension-main.c b/src/web-extensions/e-web-extension-main.c
index cb09f246ee..185c519670 100644
--- a/src/web-extensions/e-web-extension-main.c
+++ b/src/web-extensions/e-web-extension-main.c
@@ -18,38 +18,7 @@
#include "evolution-config.h"
-#include <camel/camel.h>
-
-#define E_UTIL_INCLUDE_WITHOUT_WEBKIT
-#include <e-util/e-util.h>
-#undef E_UTIL_INCLUDE_WITHOUT_WEBKIT
-
#include "e-web-extension.h"
-#include "e-web-extension-names.h"
-
-static void
-connected_to_server_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- EWebExtension *extension = user_data;
- GDBusConnection *connection;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- connection = e_web_extension_container_utils_connect_to_server_finish (result, &error);
- if (!connection) {
- g_warning ("%d %s: Failed to connect to the UI D-Bus server: %s", getpid (), G_STRFUNC,
- error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- e_web_extension_dbus_register (extension, connection);
- g_object_unref (connection);
- g_object_unref (extension);
-}
/* Forward declaration */
G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension,
@@ -60,24 +29,8 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension
GVariant *user_data)
{
EWebExtension *extension;
- const gchar *guid = NULL, *server_address = NULL;
-
- g_return_if_fail (user_data != NULL);
-
- g_variant_get (user_data, "(&s&s)", &guid, &server_address);
-
- if (!server_address) {
- g_warning ("%d %s: The UI process didn't provide server address", getpid (), G_STRFUNC);
- return;
- }
-
- camel_debug_init ();
-
- if (camel_debug ("webkit:preview"))
- printf ("%s\n", G_STRFUNC);
extension = e_web_extension_get ();
- e_web_extension_initialize (extension, wk_extension);
- e_web_extension_container_utils_connect_to_server (server_address, NULL, connected_to_server_cb,
g_object_ref (extension));
+ e_web_extension_initialize (extension, wk_extension);
}
diff --git a/src/web-extensions/e-web-extension.c b/src/web-extensions/e-web-extension.c
index 9d85388a13..87c52fd91e 100644
--- a/src/web-extensions/e-web-extension.c
+++ b/src/web-extensions/e-web-extension.c
@@ -24,1851 +24,23 @@
#include <glib/gstdio.h>
#include <gtk/gtk.h>
-#include <camel/camel.h>
-#include <libedataserver/libedataserver.h>
-
-#include "e-web-extension.h"
-#include "e-dom-utils.h"
-#include "e-itip-formatter-dom-utils.h"
-#include "e-web-extension-names.h"
-
#include <webkitdom/webkitdom.h>
-#define WEB_EXTENSION_PAGE_ID_KEY "web-extension-page-id"
-
-#define E_WEB_EXTENSION_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_WEB_EXTENSION, EWebExtensionPrivate))
+#define E_UTIL_INCLUDE_WITHOUT_WEBKIT
+#include <e-util/e-util.h>
+#undef E_UTIL_INCLUDE_WITHOUT_WEBKIT
-typedef struct _EWebPageData {
- WebKitWebPage *web_page; /* not referenced */
- gint stamp;
- gboolean need_input;
- guint32 clipboard_flags;
-} EWebPageData;
+#include "e-web-extension.h"
struct _EWebExtensionPrivate {
WebKitWebExtension *wk_extension;
- GDBusConnection *dbus_connection;
- guint registration_id;
-
gboolean initialized;
-
- GSList *pages; /* EWebPageData * */
-};
-
-enum {
- REGISTER_DBUS_CONNECTION,
- LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL];
-
-static const char introspection_xml[] =
-"<node>"
-" <interface name='" E_WEB_EXTENSION_INTERFACE "'>"
-" <signal name='ExtensionObjectReady'>"
-" </signal>"
-" <method name='GetExtensionHandlesPages'>"
-" <arg type='at' name='array' direction='out'/>"
-" </method>"
-" <signal name='ExtensionHandlesPage'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='i' name='stamp' direction='out'/>"
-" </signal>"
-" <method name='RegisterElementClicked'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_class' direction='in'/>"
-" </method>"
-" <signal name='ElementClicked'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='s' name='element_class' direction='out'/>"
-" <arg type='s' name='element_value' direction='out'/>"
-" <arg type='i' name='position_left' direction='out'/>"
-" <arg type='i' name='position_top' direction='out'/>"
-" <arg type='i' name='position_width' direction='out'/>"
-" <arg type='i' name='position_height' direction='out'/>"
-" </signal>"
-" <method name='SetElementHidden'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='b' name='hidden' direction='in'/>"
-" </method>"
-" <method name='SetElementStyleProperty'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='s' name='property_name' direction='in'/>"
-" <arg type='s' name='value' direction='in'/>"
-" <arg type='s' name='priority' direction='in'/>"
-" </method>"
-" <method name='SetElementAttribute'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='s' name='namespace_uri' direction='in'/>"
-" <arg type='s' name='qualified_name' direction='in'/>"
-" <arg type='s' name='value' direction='in'/>"
-" </method>"
-" <signal name='HeadersCollapsed'>"
-" <arg type='b' name='expanded' direction='out'/>"
-" </signal>"
-" <method name='DocumentHasSelection'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='b' name='has_selection' direction='out'/>"
-" </method>"
-" <method name='GetDocumentContentHTML'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='html_content' direction='out'/>"
-" </method>"
-" <method name='GetSelectionContentHTML'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='html_content' direction='out'/>"
-" </method>"
-" <method name='GetSelectionContentText'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='text_content' direction='out'/>"
-" </method>"
-" <method name='GetSelectionContentMultipart'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='content' direction='out'/>"
-" <arg type='b' name='is_html' direction='out'/>"
-" </method>"
-" <method name='CreateAndAddCSSStyleSheet'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='style_sheet_id' direction='in'/>"
-" </method>"
-" <method name='AddCSSRuleIntoStyleSheet'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='style_sheet_id' direction='in'/>"
-" <arg type='s' name='selector' direction='in'/>"
-" <arg type='s' name='style' direction='in'/>"
-" </method>"
-" <method name='EABContactFormatterBindDOM'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" </method>"
-" <method name='EMailDisplayBindDOM'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" </method>"
-" <method name='ElementExists'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='b' name='element_exists' direction='out'/>"
-" <arg type='t' name='page_id' direction='out'/>"
-" </method>"
-" <method name='GetActiveElementName'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_name' direction='out'/>"
-" </method>"
-" <method name='EMailPartHeadersBindDOMElement'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" </method>"
-" <signal name='VCardInlineDisplayModeToggled'>"
-" <arg type='s' name='button_id' direction='out'/>"
-" </signal>"
-" <signal name='VCardInlineSaveButtonPressed'>"
-" <arg type='s' name='button_value' direction='out'/>"
-" </signal>"
-" <method name='VCardInlineBindDOM'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" </method>"
-" <method name='VCardInlineUpdateButton'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='button_id' direction='in'/>"
-" <arg type='s' name='html_label' direction='in'/>"
-" <arg type='s' name='access_key' direction='in'/>"
-" </method>"
-" <method name='VCardInlineSetIFrameSrc'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='button_id' direction='in'/>"
-" <arg type='s' name='src' direction='in'/>"
-" </method>"
-" <method name='GetDocumentURIFromPoint'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='i' name='x' direction='in'/>"
-" <arg type='i' name='y' direction='in'/>"
-" <arg type='s' name='document_uri' direction='out'/>"
-" </method>"
-" <method name='SetDocumentIFrameSrc'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='document_uri' direction='in'/>"
-" <arg type='s' name='new_iframe_src' direction='in'/>"
-" </method>"
-" <method name='ProcessMagicSpacebar'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='b' name='towards_bottom' direction='in'/>"
-" <arg type='b' name='processed' direction='out'/>"
-" </method>"
-" <method name='EWebViewEnsureBodyClass'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='body_class' direction='in'/>"
-" </method>"
-" <signal name='NeedInputChanged'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='b' name='need_input' direction='out'/>"
-" </signal>"
-" <signal name='ClipboardFlagsChanged'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='u' name='flags' direction='out'/>"
-" </signal>"
-" <signal name='MailPartAppeared'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='s' name='part_id' direction='out'/>"
-" </signal>"
-" <signal name='ItipRecurToggled'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='s' name='part_id' direction='out'/>"
-" </signal>"
-" <signal name='ItipSourceChanged'>"
-" <arg type='t' name='page_id' direction='out'/>"
-" <arg type='s' name='part_id' direction='out'/>"
-" </signal>"
-" <method name='ItipCreateDOMBindings'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" </method>"
-" <method name='ItipShowButton'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='button_id' direction='in'/>"
-" </method>"
-" <method name='ItipElementSetInnerHTML'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='s' name='inner_html' direction='in'/>"
-" </method>"
-" <method name='ItipRemoveElement'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" </method>"
-" <method name='ItipElementRemoveChildNodes'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" </method>"
-" <method name='ItipEnableButton'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='button_id' direction='in'/>"
-" <arg type='b' name='enable' direction='in'/>"
-" </method>"
-" <method name='ItipElementIsHidden'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='b' name='is_hidden' direction='out'/>"
-" </method>"
-" <method name='ItipHideElement'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='b' name='hide' direction='in'/>"
-" </method>"
-" <method name='ItipInputSetChecked'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='input_id' direction='in'/>"
-" <arg type='b' name='checked' direction='in'/>"
-" </method>"
-" <method name='ItipInputIsChecked'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='input_id' direction='in'/>"
-" <arg type='b' name='checked' direction='out'/>"
-" </method>"
-" <method name='ItipShowCheckbox'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='id' direction='in'/>"
-" <arg type='b' name='show' direction='in'/>"
-" <arg type='b' name='update_second' direction='in'/>"
-" </method>"
-" <method name='ItipSetButtonsSensitive'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='b' name='sensitive' direction='in'/>"
-" </method>"
-" <method name='ItipSetAreaText'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='id' direction='in'/>"
-" <arg type='s' name='text' direction='in'/>"
-" </method>"
-" <method name='ItipElementSetAccessKey'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='s' name='access_key' direction='in'/>"
-" </method>"
-" <method name='ItipElementHideChildNodes'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" </method>"
-" <method name='ItipEnableSelect'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='select_id' direction='in'/>"
-" <arg type='b' name='enable' direction='in'/>"
-" </method>"
-" <method name='ItipSelectIsEnabled'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='select_id' direction='in'/>"
-" <arg type='b' name='enable' direction='out'/>"
-" </method>"
-" <method name='ItipSelectGetValue'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='select_id' direction='in'/>"
-" <arg type='s' name='value' direction='out'/>"
-" </method>"
-" <method name='ItipSelectSetSelected'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='select_id' direction='in'/>"
-" <arg type='s' name='option' direction='in'/>"
-" </method>"
-" <method name='ItipUpdateTimes'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='element_id' direction='in'/>"
-" <arg type='s' name='header' direction='in'/>"
-" <arg type='s' name='label' direction='in'/>"
-" </method>"
-" <method name='ItipAppendInfoItemRow'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='table_id' direction='in'/>"
-" <arg type='s' name='row_id' direction='in'/>"
-" <arg type='s' name='icon_name' direction='in'/>"
-" <arg type='s' name='message' direction='in'/>"
-" </method>"
-" <method name='ItipEnableTextArea'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='area_id' direction='in'/>"
-" <arg type='b' name='enable' direction='in'/>"
-" </method>"
-" <method name='ItipTextAreaSetValue'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='area_id' direction='in'/>"
-" <arg type='s' name='value' direction='in'/>"
-" </method>"
-" <method name='ItipTextAreaGetValue'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='area_id' direction='in'/>"
-" <arg type='s' name='value' direction='out'/>"
-" </method>"
-" <method name='ItipRebuildSourceList'>"
-" <arg type='t' name='page_id' direction='in'/>"
-" <arg type='s' name='part_id' direction='in'/>"
-" <arg type='s' name='optgroup_id' direction='in'/>"
-" <arg type='s' name='optgroup_label' direction='in'/>"
-" <arg type='s' name='option_id' direction='in'/>"
-" <arg type='s' name='option_label' direction='in'/>"
-" <arg type='b' name='writable' direction='in'/>"
-" </method>"
-" </interface>"
-"</node>";
-
G_DEFINE_TYPE_WITH_CODE (EWebExtension, e_web_extension, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL))
-static WebKitWebPage *
-get_webkit_web_page_or_return_dbus_error (GDBusMethodInvocation *invocation,
- WebKitWebExtension *web_extension,
- guint64 page_id)
-{
- WebKitWebPage *web_page = webkit_web_extension_get_page (web_extension, page_id);
- if (!web_page) {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "Invalid page ID: %" G_GUINT64_FORMAT, page_id);
- }
- return web_page;
-}
-
-static WebKitDOMDocument *
-get_webkit_document_or_return_dbus_error (GDBusMethodInvocation *invocation,
- WebKitWebExtension *web_extension,
- guint64 page_id)
-{
- WebKitDOMDocument *document;
- WebKitWebPage *web_page;
-
- web_page = webkit_web_extension_get_page (web_extension, page_id);
- if (!web_page) {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "Invalid page ID: %" G_GUINT64_FORMAT, page_id);
- return NULL;
- }
-
- document = webkit_web_page_get_dom_document (web_page);
- if (!document) {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "No document for page ID: %" G_GUINT64_FORMAT, page_id);
- return NULL;
- }
-
- return document;
-}
-
-static WebKitDOMDocument *
-find_webkit_document_for_partid_or_return_dbus_error (GDBusMethodInvocation *invocation,
- WebKitDOMDocument *owner,
- const gchar *part_id)
-{
- WebKitDOMElement *element;
-
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
- g_return_val_if_fail (WEBKIT_DOM_IS_DOCUMENT (owner), NULL);
- g_return_val_if_fail (part_id && *part_id, NULL);
-
- element = e_dom_utils_find_element_by_id (owner, part_id);
- if (element && WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
- WebKitDOMDocument *document = webkit_dom_html_iframe_element_get_content_document
(WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
- return document;
- }
-
- if (element)
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "Part ID '%s' is not IFRAME, but %s", part_id, G_OBJECT_TYPE_NAME (element));
- else
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "Part ID '%s' not found", part_id);
- return NULL;
-}
-
-static void
-element_clicked_cb (WebKitDOMElement *element,
- WebKitDOMEvent *event,
- gpointer user_data)
-{
- EWebExtension *extension = user_data;
- WebKitDOMElement *offset_parent;
- WebKitDOMDOMWindow *dom_window = NULL;
- gchar *attr_class, *attr_value;
- const guint64 *ppage_id;
- gdouble with_parents_left, with_parents_top;
- glong scroll_x = 0, scroll_y = 0;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (G_IS_OBJECT (element));
-
- ppage_id = g_object_get_data (G_OBJECT (element), WEB_EXTENSION_PAGE_ID_KEY);
- g_return_if_fail (ppage_id != NULL);
-
- with_parents_left = webkit_dom_element_get_offset_left (element);
- with_parents_top = webkit_dom_element_get_offset_top (element);
-
- offset_parent = element;
- while (offset_parent = webkit_dom_element_get_offset_parent (offset_parent), offset_parent) {
- with_parents_left += webkit_dom_element_get_offset_left (offset_parent);
- with_parents_top += webkit_dom_element_get_offset_top (offset_parent);
- }
-
- dom_window = webkit_dom_document_get_default_view (webkit_dom_node_get_owner_document
(WEBKIT_DOM_NODE (element)));
- while (WEBKIT_DOM_IS_DOM_WINDOW (dom_window)) {
- WebKitDOMDOMWindow *parent_dom_window = webkit_dom_dom_window_get_parent (dom_window);
- WebKitDOMElement *frame_element;
- glong scrll_x = 0, scrll_y = 0;
-
- frame_element = webkit_dom_dom_window_get_frame_element (dom_window);
-
- if (parent_dom_window != dom_window && frame_element) {
- with_parents_left += webkit_dom_element_get_client_left (frame_element);
- with_parents_top += webkit_dom_element_get_client_top (frame_element);
- }
-
- while (frame_element) {
- with_parents_left += webkit_dom_element_get_offset_left (frame_element);
- with_parents_top += webkit_dom_element_get_offset_top (frame_element);
-
- frame_element = webkit_dom_element_get_offset_parent (frame_element);
- }
-
- g_object_get (G_OBJECT (dom_window),
- "scroll-x", &scrll_x,
- "scroll-y", &scrll_y,
- NULL);
-
- scroll_x += scrll_x;
- scroll_y += scrll_y;
-
- if (parent_dom_window == dom_window) {
- g_clear_object (&parent_dom_window);
- break;
- }
-
- g_object_unref (dom_window);
- dom_window = parent_dom_window;
- }
- g_clear_object (&dom_window);
-
- attr_class = webkit_dom_element_get_class_name (element);
- attr_value = webkit_dom_element_get_attribute (element, "value");
-
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "ElementClicked",
- g_variant_new ("(tssiiii)", *ppage_id, attr_class ? attr_class : "", attr_value ? attr_value
: "",
- (gint) (with_parents_left - scroll_x),
- (gint) (with_parents_top - scroll_y),
- (gint) webkit_dom_element_get_offset_width (element),
- (gint) webkit_dom_element_get_offset_height (element)),
- &error);
-
- if (error) {
- g_warning ("Error emitting signal ElementClicked: %s\n", error->message);
- g_error_free (error);
- }
-
- g_free (attr_class);
- g_free (attr_value);
-}
-
-static void
-web_extension_register_element_clicked_in_document (EWebExtension *extension,
- guint64 page_id,
- WebKitDOMDocument *document,
- const gchar *element_class)
-{
- WebKitDOMHTMLCollection *collection = NULL;
- gulong ii, len;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (WEBKIT_DOM_IS_DOCUMENT (document));
- g_return_if_fail (element_class && *element_class);
-
- collection = webkit_dom_document_get_elements_by_class_name_as_html_collection (document,
element_class);
- if (collection) {
- len = webkit_dom_html_collection_get_length (collection);
- for (ii = 0; ii < len; ii++) {
- WebKitDOMNode *node;
-
- node = webkit_dom_html_collection_item (collection, ii);
- if (WEBKIT_DOM_IS_EVENT_TARGET (node)) {
- guint64 *ppage_id;
-
- ppage_id = g_new0 (guint64, 1);
- *ppage_id = page_id;
-
- g_object_set_data_full (G_OBJECT (node), WEB_EXTENSION_PAGE_ID_KEY, ppage_id,
g_free);
-
- /* Remove first, in case there was a listener already (it's when
- the page is dynamically filled and not all the elements are
- available in time of the first call. */
- webkit_dom_event_target_remove_event_listener (
- WEBKIT_DOM_EVENT_TARGET (node), "click",
- G_CALLBACK (element_clicked_cb), FALSE);
-
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (node), "click",
- G_CALLBACK (element_clicked_cb), FALSE, extension);
- }
- }
- }
- g_clear_object (&collection);
-
- /* Traverse also iframe-s */
- collection = webkit_dom_document_get_elements_by_tag_name_as_html_collection (document, "iframe");
- if (collection) {
- len = webkit_dom_html_collection_get_length (collection);
- for (ii = 0; ii < len; ii++) {
- WebKitDOMNode *node;
-
- node = webkit_dom_html_collection_item (collection, ii);
- if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (node)) {
- WebKitDOMDocument *content;
-
- content = webkit_dom_html_iframe_element_get_content_document
(WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
- if (content)
- web_extension_register_element_clicked_in_document (extension,
page_id, content, element_class);
- }
- }
- }
- g_clear_object (&collection);
-}
-
-static guint64
-e_web_extension_find_page_id_from_document (WebKitDOMDocument *document)
-{
- guint64 *ppage_id;
-
- g_return_val_if_fail (WEBKIT_DOM_IS_DOCUMENT (document), 0);
-
- while (document) {
- WebKitDOMDocument *prev_document = document;
-
- ppage_id = g_object_get_data (G_OBJECT (document), WEB_EXTENSION_PAGE_ID_KEY);
- if (ppage_id)
- return *ppage_id;
-
- document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (document));
- if (prev_document == document)
- break;
- }
-
- return 0;
-}
-
-static EWebPageData *
-e_web_extension_get_page_data (EWebExtension *extension,
- guint64 page_id)
-{
- GSList *link;
-
- for (link = extension->priv->pages; link; link = g_slist_next (link)) {
- EWebPageData *page_data = link->data;
-
- if (page_data && webkit_web_page_get_id (page_data->web_page) == page_id)
- return page_data;
- }
-
- return NULL;
-}
-
-static void
-e_web_extension_set_need_input (EWebExtension *extension,
- guint64 page_id,
- gboolean need_input)
-{
- EWebPageData *page_data;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (page_id != 0);
-
- page_data = e_web_extension_get_page_data (extension, page_id);
-
- if (!page_data || (!page_data->need_input) == (!need_input))
- return;
-
- page_data->need_input = need_input;
-
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "NeedInputChanged",
- g_variant_new ("(tb)", page_id, need_input),
- &error);
-
- if (error) {
- g_warning ("Error emitting signal NeedInputChanged: %s\n", error->message);
- g_error_free (error);
- }
-}
-
-static void
-element_focus_cb (WebKitDOMElement *element,
- WebKitDOMEvent *event,
- EWebExtension *extension)
-{
- guint64 *ppage_id;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- ppage_id = g_object_get_data (G_OBJECT (element), WEB_EXTENSION_PAGE_ID_KEY);
- g_return_if_fail (ppage_id != NULL);
-
- e_web_extension_set_need_input (extension, *ppage_id, TRUE);
-}
-
-static void
-element_blur_cb (WebKitDOMElement *element,
- WebKitDOMEvent *event,
- EWebExtension *extension)
-{
- guint64 *ppage_id;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- ppage_id = g_object_get_data (G_OBJECT (element), WEB_EXTENSION_PAGE_ID_KEY);
- g_return_if_fail (ppage_id != NULL);
-
- e_web_extension_set_need_input (extension, *ppage_id, FALSE);
-}
-
-static void
-e_web_extension_bind_focus_and_blur_recursively (EWebExtension *extension,
- WebKitDOMDocument *document,
- const gchar *selector,
- guint64 page_id)
-{
- WebKitDOMNodeList *nodes = NULL;
- WebKitDOMHTMLCollection *frames = NULL;
- gulong ii, length;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- nodes = webkit_dom_document_query_selector_all (document, selector, NULL);
-
- length = webkit_dom_node_list_get_length (nodes);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node;
- guint64 *ppage_id;
-
- node = webkit_dom_node_list_item (nodes, ii);
-
- ppage_id = g_new (guint64, 1);
- *ppage_id = page_id;
-
- g_object_set_data_full (G_OBJECT (node), WEB_EXTENSION_PAGE_ID_KEY, ppage_id, g_free);
-
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (node), "focus",
- G_CALLBACK (element_focus_cb), FALSE, extension);
-
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (node), "blur",
- G_CALLBACK (element_blur_cb), FALSE, extension);
- }
- g_clear_object (&nodes);
-
- frames = webkit_dom_document_get_elements_by_tag_name_as_html_collection (document, "iframe");
- length = webkit_dom_html_collection_get_length (frames);
-
- /* Add rules to every sub document */
- for (ii = 0; ii < length; ii++) {
- WebKitDOMDocument *content_document = NULL;
- WebKitDOMNode *node;
-
- node = webkit_dom_html_collection_item (frames, ii);
- content_document =
- webkit_dom_html_iframe_element_get_content_document (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
-
- if (!content_document)
- continue;
-
- e_web_extension_bind_focus_and_blur_recursively (
- extension,
- content_document,
- selector,
- page_id);
- }
- g_clear_object (&frames);
-}
-
-static void
-e_web_extension_bind_focus_on_elements (EWebExtension *extension,
- WebKitDOMDocument *document)
-{
- const gchar *elements = "input, textarea, select, button, label";
- guint64 page_id;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (WEBKIT_DOM_IS_DOCUMENT (document));
-
- page_id = e_web_extension_find_page_id_from_document (document);
- g_return_if_fail (page_id != 0);
-
- e_web_extension_bind_focus_and_blur_recursively (
- extension,
- document,
- elements,
- page_id);
-}
-
-typedef struct _MailPartAppearedData {
- GWeakRef *dbus_connection;
- GWeakRef *web_page;
- gchar *element_id;
- GVariant *params;
-} MailPartAppearedData;
-
-static void
-mail_part_appeared_data_free (gpointer ptr)
-{
- MailPartAppearedData *mpad = ptr;
-
- if (mpad) {
- e_weak_ref_free (mpad->dbus_connection);
- e_weak_ref_free (mpad->web_page);
- g_free (mpad->element_id);
- if (mpad->params)
- g_variant_unref (mpad->params);
- g_free (mpad);
- }
-}
-
-static gboolean
-web_extension_can_emit_mail_part_appeared (WebKitWebPage *web_page,
- const gchar *element_id,
- gboolean *out_abort_wait)
-{
- WebKitDOMDocument *document;
- WebKitDOMElement *element;
- WebKitDOMElement *iframe;
- WebKitDOMDocument *iframe_document;
- WebKitDOMHTMLElement *iframe_body;
-
- g_return_val_if_fail (out_abort_wait != NULL, FALSE);
-
- *out_abort_wait = TRUE;
-
- if (!web_page)
- return FALSE;
-
- if (!element_id || !*element_id)
- return FALSE;
-
- document = webkit_web_page_get_dom_document (web_page);
- if (!document)
- return FALSE;
-
- element = e_dom_utils_find_element_by_id (document, element_id);
-
- if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
- return FALSE;
-
- iframe = webkit_dom_element_query_selector (element, "iframe", NULL);
- if (!iframe)
- return FALSE;
-
- iframe_document = webkit_dom_html_iframe_element_get_content_document (WEBKIT_DOM_HTML_IFRAME_ELEMENT
(iframe));
- if (!iframe_document)
- return FALSE;
-
- iframe_body = webkit_dom_document_get_body (iframe_document);
- if (!iframe_body)
- return FALSE;
-
- *out_abort_wait = FALSE;
-
- return webkit_dom_element_get_first_element_child (WEBKIT_DOM_ELEMENT (iframe_body)) != NULL;
-}
-
-static gboolean
-web_extension_emit_mail_part_appeared_cb (gpointer user_data)
-{
- MailPartAppearedData *mpad = user_data;
- GDBusConnection *dbus_connection;
- WebKitWebPage *web_page;
- gboolean abort_wait = TRUE;
-
- g_return_val_if_fail (mpad != NULL, FALSE);
-
- dbus_connection = g_weak_ref_get (mpad->dbus_connection);
- web_page = g_weak_ref_get (mpad->web_page);
-
- if (dbus_connection && web_page &&
- web_extension_can_emit_mail_part_appeared (web_page, mpad->element_id, &abort_wait)) {
- GError *error = NULL;
-
- g_dbus_connection_emit_signal (
- dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "MailPartAppeared",
- mpad->params,
- &error);
-
- if (error) {
- g_warning ("Error emitting signal MailPartAppeared: %s", error->message);
- g_error_free (error);
- }
-
- abort_wait = TRUE;
- mpad->params = NULL;
- }
-
- if (abort_wait)
- mail_part_appeared_data_free (mpad);
-
- g_clear_object (&dbus_connection);
- g_clear_object (&web_page);
-
- return !abort_wait;
-}
-
-static void
-handle_method_call (GDBusConnection *connection,
- const char *sender,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- guint64 page_id;
- EWebExtension *extension = E_WEB_EXTENSION (user_data);
- WebKitDOMDocument *document;
- WebKitWebExtension *web_extension = extension->priv->wk_extension;
- WebKitWebPage *web_page;
-
- if (g_strcmp0 (interface_name, E_WEB_EXTENSION_INTERFACE) != 0)
- return;
-
- if (camel_debug ("webkit:preview"))
- printf ("EWebExtension - %s - %s\n", G_STRFUNC, method_name);
-
- if (g_strcmp0 (method_name, "GetExtensionHandlesPages") == 0) {
- GVariantBuilder *builder;
- GSList *link;
-
- builder = g_variant_builder_new (G_VARIANT_TYPE ("at"));
-
- for (link = extension->priv->pages; link; link = g_slist_next (link)) {
- EWebPageData *page_data = link->data;
-
- if (page_data) {
- g_variant_builder_add (builder, "t", webkit_web_page_get_id
(page_data->web_page));
- g_variant_builder_add (builder, "t", (guint64) page_data->stamp);
- }
- }
-
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(at)", builder));
-
- g_variant_builder_unref (builder);
- } else if (g_strcmp0 (method_name, "RegisterElementClicked") == 0) {
- const gchar *element_class = NULL;
-
- g_variant_get (parameters, "(t&s)", &page_id, &element_class);
-
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- if (!element_class || !*element_class) {
- g_warn_if_fail (element_class && *element_class);
- } else {
- document = webkit_web_page_get_dom_document (web_page);
- web_extension_register_element_clicked_in_document (extension, page_id, document,
element_class);
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "SetElementHidden") == 0) {
- const gchar *element_id = NULL;
- gboolean hidden = FALSE;
-
- g_variant_get (parameters, "(t&sb)", &page_id, &element_id, &hidden);
-
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- if (!element_id || !*element_id) {
- g_warn_if_fail (element_id && *element_id);
- } else {
- gboolean expand_inner_data = FALSE;
-
- document = webkit_web_page_get_dom_document (web_page);
- /* A secret short-cut, to not have two functions for basically the same thing ("hide
attachment" and "hide element") */
- if (!hidden && g_str_has_prefix (element_id, "attachment-wrapper-")) {
- WebKitDOMElement *element;
-
- element = e_dom_utils_find_element_by_id (document, element_id);
-
- if (WEBKIT_DOM_IS_HTML_ELEMENT (element) &&
- webkit_dom_element_get_child_element_count (element) == 0) {
- gchar *inner_html_data;
-
- expand_inner_data = TRUE;
-
- inner_html_data = webkit_dom_element_get_attribute (element,
"inner-html-data");
- if (inner_html_data && *inner_html_data) {
- gchar *related_part_id;
-
- webkit_dom_element_set_inner_html (element, inner_html_data,
NULL);
- webkit_dom_element_remove_attribute (element,
"inner-html-data");
-
- related_part_id = webkit_dom_element_get_attribute (element,
"related-part-id");
- webkit_dom_element_remove_attribute (element,
"related-part-id");
-
- if (related_part_id && *related_part_id) {
- GVariant *params = g_variant_new ("(ts)", page_id,
related_part_id);
- WebKitDOMElement *iframe;
-
- iframe = webkit_dom_element_query_selector (element,
"iframe", NULL);
- if (iframe) {
- WebKitDOMDocument *iframe_document;
-
- iframe_document =
webkit_dom_html_iframe_element_get_content_document (WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
- if (iframe_document) {
- WebKitDOMHTMLElement *iframe_body;
-
- iframe_body =
webkit_dom_document_get_body (iframe_document);
- if (iframe_body &&
!webkit_dom_element_get_first_element_child (WEBKIT_DOM_ELEMENT (iframe_body))) {
- /* The iframe document is
still empty, wait until it's loaded;
- wish being there something
better than this busy-wait... */
- MailPartAppearedData *mpad;
-
- mpad = g_new0
(MailPartAppearedData, 1);
- mpad->dbus_connection =
e_weak_ref_new (extension->priv->dbus_connection);
- mpad->web_page =
e_weak_ref_new (web_page);
- mpad->element_id = g_strdup
(element_id);
- mpad->params = params;
-
- /* Try 10 times per second */
- g_timeout_add (100,
web_extension_emit_mail_part_appeared_cb, mpad);
-
- /* To not emit the signal
below */
- params = NULL;
- }
- }
- }
-
- if (params) {
- GError *error = NULL;
-
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "MailPartAppeared",
- params,
- &error);
-
- if (error) {
- g_warning ("Error emitting signal
MailPartAppeared: %s", error->message);
- g_error_free (error);
- }
- }
- }
-
- g_free (related_part_id);
- }
-
- g_free (inner_html_data);
- }
- }
-
- e_dom_utils_hide_element (document, element_id, hidden);
-
- if (expand_inner_data)
- e_dom_resize_document_content_to_preview_width (document);
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "SetElementStyleProperty") == 0) {
- const gchar *element_id = NULL, *property_name = NULL, *value = NULL, *priority = NULL;
-
- g_variant_get (parameters, "(t&s&s&s&s)", &page_id, &element_id, &property_name, &value,
&priority);
-
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- if (!element_id || !*element_id || !property_name || !*property_name) {
- g_warn_if_fail (element_id && *element_id);
- g_warn_if_fail (property_name && *property_name);
- } else {
- WebKitDOMElement *element;
- gboolean use_child = FALSE;
- gchar *tmp = NULL;
-
- /* element_id can be also of the form: "id::child", where the change will
- be done on the first child of it */
- use_child = g_str_has_suffix (element_id, "::child");
- if (use_child) {
- tmp = g_strdup (element_id);
- tmp[strlen (tmp) - 7] = '\0';
-
- element_id = tmp;
- }
-
- document = webkit_web_page_get_dom_document (web_page);
- element = e_dom_utils_find_element_by_id (document, element_id);
-
- if (use_child && element)
- element = webkit_dom_element_get_first_element_child (element);
-
- if (element) {
- WebKitDOMCSSStyleDeclaration *css;
-
- css = webkit_dom_element_get_style (element);
-
- if (value && *value)
- webkit_dom_css_style_declaration_set_property (css, property_name,
value, priority, NULL);
- else
- g_free (webkit_dom_css_style_declaration_remove_property (css,
property_name, NULL));
-
- g_clear_object (&css);
- }
-
- g_free (tmp);
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "SetElementAttribute") == 0) {
- const gchar *element_id = NULL, *namespace_uri = NULL, *qualified_name = NULL, *value = NULL;
-
- g_variant_get (parameters, "(t&s&s&s&s)", &page_id, &element_id, &namespace_uri,
&qualified_name, &value);
-
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- if (!element_id || !*element_id || !qualified_name || !*qualified_name) {
- g_warn_if_fail (element_id && *element_id);
- g_warn_if_fail (qualified_name && *qualified_name);
- } else {
- WebKitDOMElement *element;
- gboolean use_child = FALSE;
- gchar *tmp = NULL;
-
- /* element_id can be also of the form: "id::child", where the change will
- be done on the first child of it */
- use_child = g_str_has_suffix (element_id, "::child");
- if (use_child) {
- tmp = g_strdup (element_id);
- tmp[strlen (tmp) - 7] = '\0';
-
- element_id = tmp;
- }
-
- if (namespace_uri && !*namespace_uri)
- namespace_uri = NULL;
-
- document = webkit_web_page_get_dom_document (web_page);
- element = e_dom_utils_find_element_by_id (document, element_id);
-
- if (use_child && element)
- element = webkit_dom_element_get_first_element_child (element);
-
- if (element) {
- if (value && *value)
- webkit_dom_element_set_attribute_ns (element, namespace_uri,
qualified_name, value, NULL);
- else
- webkit_dom_element_remove_attribute_ns (element, namespace_uri,
qualified_name);
- }
-
- g_free (tmp);
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "DocumentHasSelection") == 0) {
- gboolean has_selection;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- has_selection = e_dom_utils_document_has_selection (document);
-
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(b)", has_selection));
- } else if (g_strcmp0 (method_name, "GetDocumentContentHTML") == 0) {
- gchar *html_content;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- html_content = e_dom_utils_get_document_content_html (document);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (
- html_content ? html_content : g_strdup (""))));
- } else if (g_strcmp0 (method_name, "GetSelectionContentHTML") == 0) {
- gchar *html_content;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- html_content = e_dom_utils_get_selection_content_html (document);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (
- html_content ? html_content : g_strdup (""))));
- } else if (g_strcmp0 (method_name, "GetSelectionContentMultipart") == 0) {
- gchar *text_content;
- gboolean is_html = FALSE;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- text_content = e_dom_utils_get_selection_content_multipart (document, &is_html);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new (
- "(@sb)",
- g_variant_new_take_string (
- text_content ? text_content : g_strdup ("")),
- is_html));
- } else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
- gchar *text_content;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- text_content = e_dom_utils_get_selection_content_text (document);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (
- text_content ? text_content : g_strdup (""))));
- } else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
- const gchar *style_sheet_id, *selector, *style;
-
- g_variant_get (
- parameters,
- "(t&s&s&s)",
- &page_id, &style_sheet_id, &selector, &style);
-
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_add_css_rule_into_style_sheet (document, style_sheet_id, selector, style);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "CreateAndAddCSSStyleSheet") == 0) {
- const gchar *style_sheet_id;
-
- g_variant_get (parameters, "(t&s)", &page_id, &style_sheet_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_create_and_add_css_style_sheet (document, style_sheet_id);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "EABContactFormatterBindDOM") == 0) {
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_eab_contact_formatter_bind_dom (document);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "EMailDisplayBindDOM") == 0) {
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_e_mail_display_unstyle_blockquotes (document);
- e_dom_utils_e_mail_display_bind_dom (document, connection);
- e_web_extension_bind_focus_on_elements (extension, document);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "ElementExists") == 0) {
- const gchar *element_id;
- gboolean element_exists;
-
- g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- element_exists = e_dom_utils_element_exists (document, element_id);
-
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(bt)", element_exists, page_id));
- } else if (g_strcmp0 (method_name, "GetActiveElementName") == 0) {
- gchar *element_name;
-
- g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- element_name = e_dom_utils_get_active_element_name (document);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (
- element_name ? element_name : g_strdup (""))));
- } else if (g_strcmp0 (method_name, "EMailPartHeadersBindDOMElement") == 0) {
- const gchar *element_id;
-
- g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_e_mail_part_headers_bind_dom_element (document, element_id);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "VCardInlineBindDOM") == 0) {
- const gchar *element_id;
-
- g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_module_vcard_inline_bind_dom (
- document, element_id, connection);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "VCardInlineUpdateButton") == 0) {
- const gchar *button_id, *html_label, *access_key;
-
- g_variant_get (
- parameters,
- "(t&s&s&s)",
- &page_id, &button_id, &html_label, &access_key);
-
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_module_vcard_inline_update_button (
- document, button_id, html_label, access_key);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "VCardInlineSetIFrameSrc") == 0) {
- const gchar *src, *button_id;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &button_id, &src);
- web_page = get_webkit_web_page_or_return_dbus_error (
- invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- e_dom_utils_module_vcard_inline_set_iframe_src (document, button_id, src);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "GetDocumentURIFromPoint") == 0) {
- WebKitDOMDocument *document_at_point;
- gchar *document_uri = NULL;
- gint32 xx = 0, yy = 0;
-
- g_variant_get (parameters, "(tii)", &page_id, &xx, &yy);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- document_at_point = e_dom_utils_get_document_from_point (document, xx, yy);
-
- if (document_at_point)
- document_uri = webkit_dom_document_get_document_uri (document_at_point);
-
- g_dbus_method_invocation_return_value (
- invocation,
- g_variant_new ("(@s)", g_variant_new_take_string (document_uri ? document_uri :
g_strdup (""))));
- } else if (g_strcmp0 (method_name, "SetDocumentIFrameSrc") == 0) {
- const gchar *document_uri = NULL, *new_iframe_src = NULL;
- WebKitDOMDocument *iframe_document;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &document_uri, &new_iframe_src);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- iframe_document = e_dom_utils_find_document_with_uri (document, document_uri);
-
- if (iframe_document) {
- WebKitDOMDOMWindow *dom_window;
- WebKitDOMElement *frame_element;
-
- /* Get frame's window and from the window the actual <iframe> element */
- dom_window = webkit_dom_document_get_default_view (iframe_document);
- frame_element = webkit_dom_dom_window_get_frame_element (dom_window);
- webkit_dom_html_iframe_element_set_src (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), new_iframe_src);
- g_clear_object (&dom_window);
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "ProcessMagicSpacebar") == 0) {
- gboolean towards_bottom = FALSE, processed = FALSE;
- WebKitDOMDOMWindow *dom_window;
- glong inner_height = -1, scroll_y_before = -1, scroll_y_after = -1;
-
- g_variant_get (parameters, "(tb)", &page_id, &towards_bottom);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
- dom_window = webkit_dom_document_get_default_view (document);
-
- g_object_get (G_OBJECT (dom_window),
- "inner-height", &inner_height,
- "scroll-y", &scroll_y_before,
- NULL);
-
- if (inner_height) {
- webkit_dom_dom_window_scroll_by (dom_window, 0, towards_bottom ? inner_height :
-inner_height);
-
- g_object_get (G_OBJECT (dom_window),
- "scroll-y", &scroll_y_after,
- NULL);
-
- processed = scroll_y_before != scroll_y_after;
- }
-
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", processed));
- } else if (g_strcmp0 (method_name, "EWebViewEnsureBodyClass") == 0) {
- const gchar *body_class = NULL;
- WebKitDOMHTMLElement *body;
-
- g_variant_get (parameters, "(t&s)", &page_id, &body_class);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
- if (!web_page)
- return;
-
- document = webkit_web_page_get_dom_document (web_page);
-
- body = webkit_dom_document_get_body (document);
- if (body && !webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (body), "class"))
- webkit_dom_element_set_class_name (WEBKIT_DOM_ELEMENT (body), body_class);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else if (g_strcmp0 (method_name, "ItipCreateDOMBindings") == 0) {
- const gchar *part_id = NULL;
-
- g_variant_get (parameters, "(t&s)", &page_id, &part_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_create_dom_bindings (document, page_id, part_id,
connection);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipShowButton") == 0) {
- const gchar *button_id, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &button_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_show_button (document, button_id);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipEnableButton") == 0) {
- const gchar *button_id, *part_id = NULL;
- gboolean enable;
-
- g_variant_get (parameters, "(t&s&sb)", &page_id, &part_id, &button_id, &enable);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_enable_button (document, button_id, enable);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipElementSetInnerHTML") == 0) {
- const gchar *element_id, *inner_html, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s)", &page_id, &part_id, &element_id, &inner_html);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_dom_utils_element_set_inner_html (document, element_id, inner_html);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipRemoveElement") == 0) {
- const gchar *element_id, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &element_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_dom_utils_remove_element (document, element_id);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipElementRemoveChildNodes") == 0) {
- const gchar *element_id, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &element_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_dom_utils_element_remove_child_nodes (document, element_id);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipHideElement") == 0) {
- const gchar *element_id, *part_id = NULL;
- gboolean hide;
-
- g_variant_get (parameters, "(t&s&sb)", &page_id, &part_id, &element_id, &hide);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_dom_utils_hide_element (document, element_id, hide);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipElementIsHidden") == 0) {
- const gchar *element_id, *part_id = NULL;
- gboolean hidden;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &element_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- hidden = e_dom_utils_element_is_hidden (document, element_id);
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", hidden));
- }
- } else if (g_strcmp0 (method_name, "ItipInputSetChecked") == 0) {
- const gchar *input_id, *part_id = NULL;
- gboolean checked;
-
- g_variant_get (parameters, "(t&s&sb)", &page_id, &part_id, &input_id, &checked);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_input_set_checked (document, input_id, checked);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipInputIsChecked") == 0) {
- const gchar *input_id, *part_id = NULL;
- gboolean checked;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &input_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- checked = e_itip_formatter_dom_utils_input_is_checked (document, input_id);
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", checked));
- }
- } else if (g_strcmp0 (method_name, "ItipShowCheckbox") == 0) {
- const gchar *id, *part_id = NULL;
- gboolean show, update_second;
-
- g_variant_get (parameters, "(t&s&sbb)", &page_id, &part_id, &id, &show, &update_second);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_show_checkbox (document, id, show, update_second);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipSetButtonsSensitive") == 0) {
- const gchar *part_id = NULL;
- gboolean sensitive;
-
- g_variant_get (parameters, "(t&sb)", &page_id, &part_id, &sensitive);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_set_buttons_sensitive (document, sensitive);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipSetAreaText") == 0) {
- const gchar *id, *text, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s)", &page_id, &part_id, &id, &text);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_set_area_text (document, id, text);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipElementSetAccessKey") == 0) {
- const gchar *element_id, *access_key, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s)", &page_id, &part_id, &element_id, &access_key);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_element_set_access_key (document, element_id, access_key);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipElementHideChildNodes") == 0) {
- const gchar *element_id, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &element_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_element_hide_child_nodes (document, element_id);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipEnableSelect") == 0) {
- const gchar *select_id, *part_id = NULL;
- gboolean enable;
-
- g_variant_get (parameters, "(t&s&sb)", &page_id, &part_id, &select_id, &enable);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_enable_select (document, select_id, enable);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipSelectIsEnabled") == 0) {
- const gchar *select_id, *part_id = NULL;
- gboolean enabled;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &select_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- enabled = e_itip_formatter_dom_utils_select_is_enabled (document, select_id);
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", enabled));
- }
- } else if (g_strcmp0 (method_name, "ItipSelectGetValue") == 0) {
- const gchar *select_id, *part_id = NULL;
- gchar *value;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &select_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- value = e_itip_formatter_dom_utils_select_get_value (document, select_id);
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (value ? value : g_strdup (""))));
- }
- } else if (g_strcmp0 (method_name, "ItipSelectSetSelected") == 0) {
- const gchar *select_id, *option, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s)", &page_id, &part_id, &select_id, &option);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_select_set_selected (document, select_id, option);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipUpdateTimes") == 0) {
- const gchar *element_id, *header, *label, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s&s)", &page_id, &part_id, &element_id, &header, &label);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_update_times (document, element_id, header, label);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipAppendInfoItemRow") == 0) {
- const gchar *table_id, *row_id, *icon_name, *message, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s&s&s)", &page_id, &part_id, &table_id, &row_id,
&icon_name, &message);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_append_info_item_row (document, table_id, row_id,
icon_name, message);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipEnableTextArea") == 0) {
- const gchar *area_id, *part_id = NULL;
- gboolean enable;
-
- g_variant_get (parameters, "(t&s&sb)", &page_id, &part_id, &area_id, &enable);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_enable_text_area (document, area_id, enable);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipTextAreaSetValue") == 0) {
- const gchar *area_id, *value, *part_id = NULL;
-
- g_variant_get (parameters, "(t&s&s&s)", &page_id, &part_id, &area_id, &value);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_text_area_set_value (document, area_id, value);
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- } else if (g_strcmp0 (method_name, "ItipTextAreaGetValue") == 0) {
- const gchar *area_id, *part_id = NULL;
- gchar *value;
-
- g_variant_get (parameters, "(t&s&s)", &page_id, &part_id, &area_id);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- value = e_itip_formatter_dom_utils_text_area_get_value (document, area_id);
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new (
- "(@s)",
- g_variant_new_take_string (value ? value : g_strdup (""))));
- }
- } else if (g_strcmp0 (method_name, "ItipRebuildSourceList") == 0) {
- const gchar *optgroup_id, *optgroup_label, *option_id, *option_label, *part_id = NULL;
- gboolean writable;
-
- g_variant_get (parameters,"(t&s&s&s&s&sb)", &page_id, &part_id, &optgroup_id,
&optgroup_label, &option_id, &option_label, &writable);
-
- document = get_webkit_document_or_return_dbus_error (invocation, web_extension, page_id);
- if (document)
- document = find_webkit_document_for_partid_or_return_dbus_error (invocation,
document, part_id);
- if (document) {
- e_itip_formatter_dom_utils_rebuild_source_list (
- document,
- optgroup_id,
- optgroup_label,
- option_id,
- option_label,
- writable);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
- }
- }
-}
-
-static GVariant *
-handle_get_property (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GError **error,
- gpointer user_data)
-{
- /* EWebExtension *extension = E_WEB_EXTENSION (user_data); */
- GVariant *variant = NULL;
-
- g_warn_if_reached ();
-
- return variant;
-}
-
-static gboolean
-handle_set_property (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GVariant *variant,
- GError **error,
- gpointer user_data)
-{
- /* EWebExtension *extension = E_WEB_EXTENSION (user_data); */
-
- g_warn_if_reached ();
-
- return TRUE;
-}
-
-static const GDBusInterfaceVTable interface_vtable = {
- handle_method_call,
- handle_get_property,
- handle_set_property
-};
-
-static void
-web_page_gone_cb (gpointer user_data,
- GObject *gone_web_page)
-{
- EWebExtension *extension = user_data;
- GSList *link;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- for (link = extension->priv->pages; link; link = g_slist_next (link)) {
- EWebPageData *page_data = link->data;
-
- if (page_data && page_data->web_page == (gpointer) gone_web_page) {
- extension->priv->pages = g_slist_remove (extension->priv->pages, page_data);
- g_free (page_data);
- break;
- }
- }
-}
-
static void
e_web_extension_constructed (GObject *object)
{
@@ -1882,17 +54,6 @@ e_web_extension_dispose (GObject *object)
{
EWebExtension *extension = E_WEB_EXTENSION (object);
- if (extension->priv->dbus_connection) {
- g_dbus_connection_unregister_object (
- extension->priv->dbus_connection,
- extension->priv->registration_id);
- extension->priv->registration_id = 0;
- g_clear_object (&extension->priv->dbus_connection);
- }
-
- g_slist_free_full (extension->priv->pages, g_free);
- extension->priv->pages = NULL;
-
g_clear_object (&extension->priv->wk_extension);
G_OBJECT_CLASS (e_web_extension_parent_class)->dispose (object);
@@ -1907,15 +68,6 @@ e_web_extension_class_init (EWebExtensionClass *class)
object_class->constructed = e_web_extension_constructed;
object_class->dispose = e_web_extension_dispose;
-
- signals[REGISTER_DBUS_CONNECTION] = g_signal_new (
- "register-dbus-connection",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 1, G_TYPE_DBUS_CONNECTION);
}
static void
@@ -1927,7 +79,7 @@ e_web_extension_init (EWebExtension *extension)
}
static gpointer
-e_web_extension_create_instance(gpointer data)
+e_web_extension_create_instance (gpointer data)
{
return g_object_new (E_TYPE_WEB_EXTENSION, NULL);
}
@@ -1936,6 +88,7 @@ EWebExtension *
e_web_extension_get (void)
{
static GOnce once_init = G_ONCE_INIT;
+
return E_WEB_EXTENSION (g_once (&once_init, e_web_extension_create_instance, NULL));
}
@@ -1973,218 +126,87 @@ web_page_send_request_cb (WebKitWebPage *web_page,
}
static void
-e_web_extension_store_page_id_on_document (WebKitWebPage *web_page)
-{
- WebKitDOMDocument *document;
- guint64 *ppage_id;
-
- g_return_if_fail (WEBKIT_IS_WEB_PAGE (web_page));
-
- ppage_id = g_new (guint64, 1);
- *ppage_id = webkit_web_page_get_id (web_page);
-
- document = webkit_web_page_get_dom_document (web_page);
-
- g_object_set_data_full (G_OBJECT (document), WEB_EXTENSION_PAGE_ID_KEY, ppage_id, g_free);
-}
-
-static void
-web_page_document_loaded_cb (WebKitWebPage *web_page,
- gpointer user_data)
+web_page_created_cb (WebKitWebExtension *wk_extension,
+ WebKitWebPage *web_page,
+ EWebExtension *extension)
{
- WebKitDOMDocument *document;
-
- e_web_extension_store_page_id_on_document (web_page);
-
- document = webkit_web_page_get_dom_document (web_page);
-
- e_dom_utils_replace_local_image_links (document);
-
- if ((webkit_dom_document_query_selector (
- document, "[data-evo-signature-plain-text-mode]", NULL))) {
-
- WebKitDOMHTMLElement *body;
-
- body = webkit_dom_document_get_body (document);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body),
- "style",
- "font-family: Monospace;",
- NULL);
- }
+ g_signal_connect_object (
+ web_page, "send-request",
+ G_CALLBACK (web_page_send_request_cb),
+ extension, 0);
}
static void
-e_web_extension_set_clipboard_flags (EWebExtension *extension,
- WebKitDOMDocument *document,
- guint32 clipboard_flags)
+load_javascript_file (JSCContext *jsc_context,
+ const gchar *js_filename)
{
- EWebPageData *page_data = NULL;
- guint64 page_id;
+ JSCValue *result;
+ JSCException *exception;
+ gchar *content, *filename, *resource_uri;
+ gsize length = 0;
GError *error = NULL;
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (WEBKIT_DOM_IS_DOCUMENT (document));
-
- page_id = e_web_extension_find_page_id_from_document (document);
- g_return_if_fail (page_id != 0);
+ g_return_if_fail (jsc_context != NULL);
- page_data = e_web_extension_get_page_data (extension, page_id);
+ filename = g_build_filename (EVOLUTION_WEBKITDATADIR, js_filename, NULL);
- if (!page_data || page_data->clipboard_flags == clipboard_flags)
- return;
+ if (!g_file_get_contents (filename, &content, &length, &error)) {
+ g_warning ("Failed to load '%s': %s", filename, error ? error->message : "Unknown error");
- page_data->clipboard_flags = clipboard_flags;
+ g_clear_error (&error);
+ g_free (filename);
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "ClipboardFlagsChanged",
- g_variant_new ("(tu)", page_id, clipboard_flags),
- &error);
-
- if (error) {
- g_warning ("Error emitting signal ClipboardFlagsChanged: %s\n", error->message);
- g_error_free (error);
+ return;
}
-}
-
-static void
-web_editor_selection_changed_cb (WebKitWebEditor *web_editor,
- EWebExtension *extension)
-{
- WebKitWebPage *web_page;
- WebKitDOMDocument *document;
- guint32 clipboard_flags = 0;
-
- web_page = webkit_web_editor_get_page (web_editor);
-
- document = webkit_web_page_get_dom_document (web_page);
-
- if (e_dom_utils_document_has_selection (document))
- clipboard_flags |= E_CLIPBOARD_CAN_COPY;
-
- e_web_extension_set_clipboard_flags (extension, document, clipboard_flags);
-}
-
-static void
-web_page_notify_uri_cb (GObject *object,
- GParamSpec *param,
- gpointer user_data)
-{
- EWebExtension *extension = user_data;
- WebKitWebPage *web_page;
- GSList *link;
- const gchar *uri;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
-
- web_page = WEBKIT_WEB_PAGE (object);
- uri = webkit_web_page_get_uri (web_page);
-
- for (link = extension->priv->pages; link; link = g_slist_next (link)) {
- EWebPageData *page_data = link->data;
-
- if (page_data && page_data->web_page == web_page) {
- gint new_stamp = 0;
-
- if (uri && *uri) {
- SoupURI *suri;
-
- suri = soup_uri_new (uri);
- if (suri) {
- if (soup_uri_get_query (suri)) {
- GHashTable *form;
-
- form = soup_form_decode (soup_uri_get_query (suri));
- if (form) {
- const gchar *evo_stamp;
-
- evo_stamp = g_hash_table_lookup (form, "evo-stamp");
- if (evo_stamp)
- new_stamp = (gint) g_ascii_strtoll
(evo_stamp, NULL, 10);
- g_hash_table_destroy (form);
- }
- }
+ resource_uri = g_strconcat ("resource:///", js_filename, NULL);
- soup_uri_free (suri);
- }
- }
+ result = jsc_context_evaluate_with_source_uri (jsc_context, content, length, resource_uri, 1);
- if (extension->priv->dbus_connection) {
- GError *error = NULL;
+ g_free (resource_uri);
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "ExtensionHandlesPage",
- g_variant_new ("(ti)", webkit_web_page_get_id (web_page), new_stamp),
- &error);
+ exception = jsc_context_get_exception (jsc_context);
- if (error) {
- g_warning ("Error emitting signal ExtensionHandlesPage: %s",
error->message);
- g_error_free (error);
- }
- }
-
- page_data->stamp = new_stamp;
- return;
- }
+ if (exception) {
+ g_warning ("Failed to call script '%s': %d:%d: %s",
+ filename,
+ jsc_exception_get_line_number (exception),
+ jsc_exception_get_column_number (exception),
+ jsc_exception_get_message (exception));
}
- g_warning ("%s: Cannot find web_page %p\n", G_STRFUNC, web_page);
+ g_clear_object (&result);
+ g_free (filename);
+ g_free (content);
}
static void
-web_page_created_cb (WebKitWebExtension *wk_extension,
- WebKitWebPage *web_page,
- EWebExtension *extension)
+window_object_cleared_cb (WebKitScriptWorld *world,
+ WebKitWebPage *page,
+ WebKitFrame *frame,
+ gpointer user_data)
{
- EWebPageData *page_data;
-
- page_data = g_new0 (EWebPageData, 1);
- page_data->web_page = web_page;
- page_data->need_input = FALSE;
- page_data->clipboard_flags = 0;
- page_data->stamp = 0;
-
- e_web_extension_store_page_id_on_document (web_page);
-
- extension->priv->pages = g_slist_prepend (extension->priv->pages, page_data);
+ JSCContext *jsc_context;
- g_object_weak_ref (G_OBJECT (web_page), web_page_gone_cb, extension);
+ /* Load the javascript files only to the main frame, not to the subframes */
+ if (!webkit_frame_is_main_frame (frame))
+ return;
- g_signal_connect_object (
- web_page, "send-request",
- G_CALLBACK (web_page_send_request_cb),
- extension, 0);
+ jsc_context = webkit_frame_get_js_context (frame);
- g_signal_connect_object (
- web_page, "document-loaded",
- G_CALLBACK (web_page_document_loaded_cb),
- extension, 0);
+ /* Read e-convert.js first, because e-web-view.js uses it */
+ load_javascript_file (jsc_context, "e-convert.js");
+ load_javascript_file (jsc_context, "e-web-view.js");
- g_signal_connect_object (
- web_page, "notify::uri",
- G_CALLBACK (web_page_notify_uri_cb),
- extension, 0);
-
- g_signal_connect_object (
- webkit_web_page_get_editor (web_page), "selection-changed",
- G_CALLBACK (web_editor_selection_changed_cb),
- extension, 0);
+ g_clear_object (&jsc_context);
}
void
e_web_extension_initialize (EWebExtension *extension,
WebKitWebExtension *wk_extension)
{
+ WebKitScriptWorld *script_world;
+
g_return_if_fail (E_IS_WEB_EXTENSION (extension));
if (extension->priv->initialized)
@@ -2197,55 +219,11 @@ e_web_extension_initialize (EWebExtension *extension,
g_signal_connect (
wk_extension, "page-created",
G_CALLBACK (web_page_created_cb), extension);
-}
-
-void
-e_web_extension_dbus_register (EWebExtension *extension,
- GDBusConnection *connection)
-{
- GError *error = NULL;
- static GDBusNodeInfo *introspection_data = NULL;
-
- g_return_if_fail (E_IS_WEB_EXTENSION (extension));
- g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
-
- if (!introspection_data) {
- introspection_data =
- g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
- extension->priv->registration_id =
- g_dbus_connection_register_object (
- connection,
- E_WEB_EXTENSION_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- extension,
- NULL,
- &error);
-
- if (!extension->priv->registration_id) {
- g_warning ("Failed to register object: %s\n", error->message);
- g_error_free (error);
- } else {
- extension->priv->dbus_connection = g_object_ref (connection);
- g_signal_emit (extension, signals[REGISTER_DBUS_CONNECTION], 0, connection);
+ script_world = webkit_script_world_get_default ();
- g_dbus_connection_emit_signal (
- extension->priv->dbus_connection,
- NULL,
- E_WEB_EXTENSION_OBJECT_PATH,
- E_WEB_EXTENSION_INTERFACE,
- "ExtensionObjectReady",
- NULL,
- &error);
-
- if (error) {
- g_warning ("Error emitting signal ExtensionObjectReady: %s", error->message);
- g_error_free (error);
- }
- }
- }
+ g_signal_connect (script_world, "window-object-cleared",
+ G_CALLBACK (window_object_cleared_cb), NULL);
}
WebKitWebExtension *
@@ -2255,11 +233,3 @@ e_web_extension_get_webkit_extension (EWebExtension *extension)
return extension->priv->wk_extension;
}
-
-GDBusConnection *
-e_web_extension_get_dbus_connection (EWebExtension *extension)
-{
- g_return_val_if_fail (E_IS_WEB_EXTENSION (extension), NULL);
-
- return extension->priv->dbus_connection;
-}
diff --git a/src/web-extensions/e-web-extension.h b/src/web-extensions/e-web-extension.h
index 834b63c7fd..5bb941338c 100644
--- a/src/web-extensions/e-web-extension.h
+++ b/src/web-extensions/e-web-extension.h
@@ -20,7 +20,6 @@
#define E_WEB_EXTENSION_H
#include <glib-object.h>
-#include <gio/gio.h>
#include <webkit2/webkit-web-extension.h>
/* Standard GObject macros */
@@ -65,14 +64,9 @@ EWebExtension * e_web_extension_get (void);
void e_web_extension_initialize (EWebExtension *extension,
WebKitWebExtension *wk_extension);
-void e_web_extension_dbus_register (EWebExtension *extension,
- GDBusConnection *connection);
WebKitWebExtension *
e_web_extension_get_webkit_extension
(EWebExtension *extension);
-GDBusConnection *
- e_web_extension_get_dbus_connection
- (EWebExtension *extension);
G_END_DECLS
#endif /* E_WEB_EXTENSION_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]