[evolution/wip/mcrha/webkit-jsc-api: 255/292] Mostly table editing and some cleanups and removal of get_caret_position()



commit 2ea4cbaf4b59f92fd55427c4a6b976a03ece5d35
Author: Milan Crha <mcrha redhat com>
Date:   Tue Dec 10 18:44:09 2019 +0100

    Mostly table editing and some cleanups and removal of get_caret_position()

 data/webkit/e-editor.js                       |  814 ++++++++++-
 src/e-util/e-content-editor.c                 |   35 -
 src/e-util/e-content-editor.h                 |   24 -
 src/e-util/e-html-editor-table-dialog.c       |   42 +-
 src/modules/webkit-editor/e-webkit-editor.c   | 1924 +++++--------------------
 src/plugins/external-editor/external-editor.c |   27 +-
 6 files changed, 1171 insertions(+), 1695 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 8dd30e4331..3f8ac61d54 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -67,6 +67,11 @@ var EvoEditor = {
        E_CONTENT_EDITOR_NODE_IS_TEXT           : 1 << 5,
        E_CONTENT_EDITOR_NODE_IS_TEXT_COLLAPSED : 1 << 6,
 
+       E_CONTENT_EDITOR_SCOPE_CELL             : 0,
+       E_CONTENT_EDITOR_SCOPE_ROW              : 1,
+       E_CONTENT_EDITOR_SCOPE_COLUMN           : 2,
+       E_CONTENT_EDITOR_SCOPE_TABLE            : 3,
+
        /* Flags for ClaimAffectedContent() */
        CLAIM_CONTENT_FLAG_NONE : 0,
        CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE : 1 << 0,
@@ -219,9 +224,7 @@ EvoEditor.maybeUpdateFormattingState = function(force)
        }
 
        tmp = (computedStyle ? computedStyle.textAlign : "").toLowerCase();
-       if (tmp == "")
-               value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_NONE;
-       else if (tmp == "left" || tmp == "start")
+       if (tmp == "left" || tmp == "start")
                value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        else if (tmp == "right")
                value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
@@ -229,8 +232,10 @@ EvoEditor.maybeUpdateFormattingState = function(force)
                value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_CENTER;
        else if (tmp == "justify")
                value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_JUSTIFY;
+       else if ((computedStyle ? computedStyle.direction : "").toLowerCase() == "rtl")
+               value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
        else
-               value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_NONE;
+               value = EvoEditor.E_CONTENT_EDITOR_ALIGNMENT_LEFT;
 
        if (force || value != EvoEditor.formattingState.alignment) {
                EvoEditor.formattingState.alignment = value;
@@ -1966,7 +1971,7 @@ EvoEditor.convertHtmlToSend = function()
 
 EvoEditor.GetContent = function(flags, cid_uid_prefix)
 {
-       var content_data = {}, img_elems = [], elems, ii, jj;
+       var content_data = {}, img_elems = [], bkg_elems = [], elems, ii, jj;
 
        if (!document.body)
                return content_data;
@@ -2062,6 +2067,51 @@ EvoEditor.GetContent = function(flags, cid_uid_prefix)
                                }
                        }
 
+                       images = document.querySelectorAll("[background]");
+                       for (ii = 0; ii < images.length; ii++) {
+                               var elem = images[ii];
+                               var src = elem ? elem.getAttribute("background").toLowerCase() : "";
+
+                               if (elem &&
+                                   src.startsWith("data:") ||
+                                   src.startsWith("file://") ||
+                                   src.startsWith("evo-file://")) {
+                                       var bkg = elem.getAttribute("background");
+
+                                       for (jj = 0; jj < bkg_elems.length; jj++) {
+                                               if (bkg == bkg_elems[jj].orig_src) {
+                                                       elem.subelems[elem.subelems.length] = elem;
+                                                       elem.setAttribute("background", bkg_elems[jj].cid);
+                                                       break;
+                                               }
+                                       }
+
+                                       if (jj >= bkg_elems.length) {
+                                               var bkg_obj = {
+                                                       subelems : [ elem ],
+                                                       cid : "cid:" + cid_uid_prefix + "-" + 
bkg_elems.length,
+                                                       orig_src : bkg
+                                               };
+
+                                               // re-read, because it could change
+                                               if 
(elem.getAttribute("background").toLowerCase().startsWith("cid:"))
+                                                       bkg_obj.cid = elem.getAttribute("background");
+
+                                               bkg_elems[bkg_elems.length] = bkg_obj;
+                                               images[images.length] = {
+                                                       cid : bkg_obj.cid,
+                                                       src : elem.getAttribute("background")
+                                               };
+                                               elem.setAttribute("background", bkg_obj.cid);
+                                       }
+                               } else if (elem && src.startsWith("cid:")) {
+                                       images[images.length] = {
+                                               cid : elem.getAttribute("background"),
+                                               src : elem.getAttribute("background")
+                                       };
+                               }
+                       }
+
                        if (images.length)
                                content_data["images"] = images;
                }
@@ -2091,6 +2141,14 @@ EvoEditor.GetContent = function(flags, cid_uid_prefix)
                                        img_obj.subelems[jj].src = img_obj.orig_src;
                                }
                        }
+
+                       for (ii = 0; ii < bkg_elems.length; ii++) {
+                               var bkg_obj = bkg_elems[ii];
+
+                               for (jj = 0; jj < bkg_obj.subelems.length; jj++) {
+                                       bkg_obj.subelems[jj].setAttribute("background", bkg_obj.orig_src);
+                               }
+                       }
                } finally {
                        EvoUndoRedo.Enable();
                }
@@ -2289,11 +2347,12 @@ EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
        }
 }
 
-EvoEditor.getCaretElement = function(tagName)
+EvoEditor.getParentElement = function(tagName, fromNode, canClimbUp)
 {
-       var node;
+       var node = fromNode;
 
-       node = document.getSelection().extentNode;
+       if (!node)
+               node = document.getSelection().extentNode;
 
        if (!node)
                node = document.getSelection().baseNode;
@@ -2302,6 +2361,12 @@ EvoEditor.getCaretElement = function(tagName)
                node = node.parentElement;
        }
 
+       if (canClimbUp) {
+               while (node && node.tagName != tagName) {
+                       node = node.parentElement;
+               }
+       }
+
        if (node && node.tagName == tagName)
                return node;
 
@@ -2342,10 +2407,10 @@ EvoEditor.OnDialogOpen = function(name)
                EvoEditor.storePropertiesSelection();
 
                if (name == "cell") {
-                       var tdnode, tdnode;
+                       var tdnode, thnode;
 
-                       tdnode = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TD") ? 
EvoEditor.contextMenuNode : EvoEditor.getCaretElement("TD");
-                       thnode = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TH") ? 
EvoEditor.contextMenuNode : EvoEditor.getCaretElement("TH");
+                       tdnode = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TD") ? 
EvoEditor.contextMenuNode : EvoEditor.getParentElement("TD", null, false);
+                       thnode = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TH") ? 
EvoEditor.contextMenuNode : EvoEditor.getParentElement("TH", null, false);
 
                        if (tdnode === EvoEditor.contextMenuNode) {
                                node = tdnode;
@@ -2378,11 +2443,11 @@ EvoEditor.OnDialogOpen = function(name)
                EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_GROUP, "Dialog::" + name);
 
                if (name == "hrule") {
-                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "HR") ? 
EvoEditor.contextMenuNode : EvoEditor.getCaretElement("HR");
+                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "HR") ? 
EvoEditor.contextMenuNode : EvoEditor.getParentElement("HR", null, false);
                } else if (name == "image") {
-                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "IMG") ? 
EvoEditor.contextMenuNode : EvoEditor.getCaretElement("IMG");
+                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "IMG") ? 
EvoEditor.contextMenuNode : EvoEditor.getParentElement("IMG", null, false);
                } else if (name == "table") {
-                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TABLE") ? 
EvoEditor.contextMenuNode : EvoEditor.getCaretElement("TABLE");
+                       node = (EvoEditor.contextMenuNode && EvoEditor.contextMenuNode.tagName == "TABLE") ? 
EvoEditor.contextMenuNode : EvoEditor.getParentElement("TABLE", null, true);
                }
 
                if (node) {
@@ -2438,7 +2503,7 @@ EvoEditor.OnDialogClose = function(name)
        }
 }
 
-EvoEditor.applyDialogUtilsSetAttribute = function(record, isUndo)
+EvoEditor.applySetAttribute = function(record, isUndo)
 {
        var element = EvoSelection.FindElementByPath(document.body, record.path);
 
@@ -2458,41 +2523,122 @@ EvoEditor.applyDialogUtilsSetAttribute = function(record, isUndo)
                element.setAttribute(record.attrName, value);
 }
 
-// 'value' can be 'null', to remove the attribute
-EvoEditor.DialogUtilsSetAttribute = function(name, value)
+EvoEditor.setAttributeWithUndoRedo = function(opTypePrefix, element, name, value)
 {
-       var element = document.getElementById("x-evo-dialog-current-element");
+       if (!element)
+               return false;
 
-       if (element) {
-               var record = EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DlgUtilSetAttribute::" 
+ name, element, element, EvoEditor.CLAIM_CONTENT_FLAG_NONE);
+       if ((value == null && !element.hasAttribute(name)) ||
+           (value != null && value == element.getAttribute(name)))
+               return false;
 
-               try {
-                       if (record) {
-                               record.path = EvoSelection.GetChildPath(document.body, element);
-                               record.attrName = name;
-                               record.beforeValue = element.hasAttribute(name) ? element.getAttribute(name) 
: null;
-                               record.afterValue = value;
-                               record.apply = EvoEditor.applyDialogUtilsSetAttribute;
-                       }
+       var record = EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opTypePrefix + "::" + name, 
element, element, EvoEditor.CLAIM_CONTENT_FLAG_NONE);
 
-                       if (value != null) {
-                               element.setAttribute(name, value);
-                       } else {
-                               element.removeAttribute(name);
+       try {
+               if (record) {
+                       record.path = EvoSelection.GetChildPath(document.body, element);
+                       record.attrName = name;
+                       record.beforeValue = element.hasAttribute(name) ? element.getAttribute(name) : null;
+                       record.afterValue = value;
+                       record.apply = EvoEditor.applyDialogUtilsSetAttribute;
+               }
+
+               if (value == null) {
+                       element.removeAttribute(name);
+               } else {
+                       element.setAttribute(name, value);
+               }
+
+               if (record && record.beforeValue == record.afterValue) {
+                       record.ignore = true;
+               }
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opTypePrefix + "::" + name);
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+       }
+
+       return true;
+}
+
+EvoEditor.addElementWithUndoRedo = function(opType, tagName, fillNodeFunc, parent, insertBefore, 
contentArray)
+{
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType, parent, parent, 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+       try {
+               var selectionUpdater = EvoSelection.CreateUpdaterObject(), node;
+
+               node = document.createElement(tagName);
+
+               if (fillNodeFunc)
+                       fillNodeFunc(node);
+
+               parent.insertBefore(node, insertBefore);
+
+               if (contentArray) {
+                       var ii;
+
+                       for (ii = 0; ii < contentArray.length; ii++) {
+                               node.append(contentArray[ii]);
                        }
+               }
 
-                       if (record && record.beforeValue == record.afterValue) {
-                               record.ignore = true;
+               selectionUpdater.restore();
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType);
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+       }
+}
+
+EvoEditor.removeElementWithUndoRedo = function(opType, element)
+{
+       if (element) {
+               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType, element.parentElement, 
element.parentElement, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+               try {
+                       var selectionUpdater = EvoSelection.CreateUpdaterObject(), firstChild;
+
+                       firstChild = element.firstChild;
+
+                       while (element.firstChild) {
+                               element.parentElement.insertBefore(element.firstChild, element);
                        }
+
+                       selectionUpdater.beforeRemove(element);
+                       element.parentElement.removeChild(element);
+                       selectionUpdater.afterRemove(firstChild);
+
+                       selectionUpdater.restore();
                } finally {
-                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DlgUtilSetAttribute::" + 
name);
+                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType);
+                       EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+                       EvoEditor.EmitContentChanged();
                }
        }
 }
 
-EvoEditor.DialogUtilsGetAttribute = function(name)
+// 'value' can be 'null', to remove the attribute
+EvoEditor.DialogUtilsSetAttribute = function(selector, name, value)
 {
-       var element = document.getElementById("x-evo-dialog-current-element");
+       var element;
+
+       if (selector)
+               element = document.querySelector(selector);
+       else
+               element = document.getElementById("x-evo-dialog-current-element");
+
+       if (element) {
+               EvoEditor.setAttributeWithUndoRedo("DlgUtilSetAttribute", element, name, value);
+       }
+}
+
+EvoEditor.DialogUtilsGetAttribute = function(selector, name)
+{
+       var element;
+
+       if (selector)
+               element = document.querySelector(selector);
+       else
+               element = document.getElementById("x-evo-dialog-current-element");
 
        if (element && element.hasAttribute(name))
                return element.getAttribute(name);
@@ -2509,7 +2655,7 @@ EvoEditor.DialogUtilsHasAttribute = function(name)
 
 EvoEditor.LinkGetProperties = function()
 {
-       var res = null, anchor = EvoEditor.getCaretElement("A");
+       var res = null, anchor = EvoEditor.getParentElement("A", null, false);
 
        if (anchor) {
                res = [];
@@ -2534,7 +2680,7 @@ EvoEditor.LinkSetProperties = function(href, text)
        // The properties dialog can discard selection, thus restore it before doing changes
        EvoEditor.restorePropertiesSelection();
 
-       var anchor = EvoEditor.getCaretElement("A");
+       var anchor = EvoEditor.getParentElement("A", null, false);
 
        if (anchor && (anchor.href != href || anchor.innerText != text)) {
                EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "SetLinkValues", anchor, anchor, 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
@@ -2564,29 +2710,585 @@ EvoEditor.Unlink = function()
        // The properties dialog can discard selection, thus restore it before doing changes
        EvoEditor.restorePropertiesSelection();
 
-       var anchor = EvoEditor.getCaretElement("A");
+       var anchor = EvoEditor.getParentElement("A", null, false);
 
-       if (anchor) {
-               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "Unlink", anchor.parentElement, 
anchor.parentElement, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
-               try {
-                       var selectionUpdater = EvoSelection.CreateUpdaterObject(), firstChild;
+       EvoEditor.removeElementWithUndoRedo("Unlink", anchor);
+}
 
-                       firstChild = anchor.firstChild;
+EvoEditor.ReplaceImageSrc = function(selector, uri)
+{
+       if (!selector)
+               selector = "#x-evo-dialog-current-element";
+
+       var element = document.querySelector(selector);
+
+       if (element) {
+               if (uri) {
+                       var attrName;
 
-                       while (anchor.firstChild) {
-                               anchor.parentElement.insertBefore(anchor.firstChild, anchor);
+                       if (element.tagName == "IMG")
+                               attrName = "src";
+                       else
+                               attrName = "background";
+
+                       EvoEditor.setAttributeWithUndoRedo("ReplaceImageSrc", element, attrName, uri);
+               } else {
+                       if (element.tagName == "IMG") {
+                               EvoEditor.removeElementWithUndoRedo("ReplaceImageSrc", element);
+                       } else {
+                               EvoEditor.setAttributeWithUndoRedo("ReplaceImageSrc", element, "background", 
null);
                        }
+               }
+       }
+}
 
-                       selectionUpdater.beforeRemove(anchor);
-                       anchor.parentElement.removeChild(anchor);
-                       selectionUpdater.afterRemove(firstChild);
+EvoEditor.DialogUtilsSetImageUrl = function(href)
+{
+       var element = document.getElementById("x-evo-dialog-current-element");
 
-                       selectionUpdater.restore();
-               } finally {
-                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "Unlink");
-                       EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+       if (element && element.tagName == "IMG") {
+               var anchor = EvoEditor.getParentElement("A", element, true);
+
+               if (anchor) {
+                       if (href && anchor.href != href) {
+                               EvoEditor.setAttributeWithUndoRedo("DialogUtilsSetImageUrl", anchor, "href", 
href);
+                       } else if (!href) {
+                               EvoEditor.removeElementWithUndoRedo("DialogUtilsSetImageUrl::unset", element);
+                       }
+               } else if (href) {
+                       var fillHref = function(node) {
+                               node.href = href;
+                       };
+
+                       EvoEditor.addElementWithUndoRedo("DialogUtilsSetImageUrl", "A", fillHref, 
element.parentElement, element, [ element ]);
+               }
+       }
+}
+
+EvoEditor.DialogUtilsGetImageUrl = function()
+{
+       var element = document.getElementById("x-evo-dialog-current-element"), res = null;
+
+       if (element && element.tagName == "IMG") {
+               var anchor = EvoEditor.getParentElement("A", element, true);
+
+               if (anchor)
+                       res = anchor.href;
+       }
+
+       return res;
+}
+
+EvoEditor.DialogUtilsGetImageWidth = function(natural)
+{
+       var element = document.getElementById("x-evo-dialog-current-element"), res = -1;
+
+       if (element && element.tagName == "IMG") {
+               if (natural)
+                       res = element.naturalWidth;
+               else
+                       res = element.width;
+       }
+
+       return res;
+}
+
+EvoEditor.DialogUtilsGetImageHeight = function(natural)
+{
+       var element = document.getElementById("x-evo-dialog-current-element"), res = -1;
+
+       if (element && element.tagName == "IMG") {
+               if (natural)
+                       res = element.naturalHeight;
+               else
+                       res = element.height;
+       }
+
+       return res;
+}
+
+EvoEditor.dialogUtilsForeachTableScope = function(scope, traversar, opType)
+{
+       var cell = document.getElementById("x-evo-dialog-current-element");
+
+       if (!cell)
+               throw "EvoEditor.dialogUtilsForeachTableScope: Current cell not found";
+
+       cell.removeAttribute("id");
+
+       traversar.selectionUpdater = EvoSelection.CreateUpdaterObject();
+
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_GROUP, opType);
+
+       cell.id = "x-evo-dialog-current-element";
+
+       try {
+               var rowFunc = function(row, traversar) {
+                       var jj, length = row.cells.length;
+
+                       for (jj = 0; jj < length; jj++) {
+                               var cell = row.cells[length - jj - 1];
+
+                               if (cell && !traversar.exec(cell))
+                                       return false;
+                       }
+
+                       return true;
+               };
+
+               if (scope == EvoEditor.E_CONTENT_EDITOR_SCOPE_CELL) {
+                       traversar.exec(cell);
+               } else if (scope == EvoEditor.E_CONTENT_EDITOR_SCOPE_COLUMN) {
+                       var table;
+
+                       table = EvoEditor.getParentElement("TABLE", cell, true);
+                       if (table) {
+                               var length = table.rows.length, ii, cellIndex = cell.cellIndex;
+
+                               for (ii = 0; ii < length; ii++) {
+                                       var row = table.rows[length - ii - 1];
+
+                                       if (row && cellIndex < row.cells.length &&
+                                           !traversar.exec(row.cells[cellIndex]))
+                                               break;
+                               }
+                       }
+               } else if (scope == EvoEditor.E_CONTENT_EDITOR_SCOPE_ROW) {
+                       var row = EvoEditor.getParentElement("TR", cell, true);
+
+                       if (row)
+                               rowFunc(row, traversar);
+               } else if (scope == EvoEditor.E_CONTENT_EDITOR_SCOPE_TABLE) {
+                       var table = EvoEditor.getParentElement("TABLE", cell, true);
+
+                       if (table) {
+                               var length = table.rows.length, ii;
+
+                               for (ii = 0; ii < length; ii++) {
+                                       if (!rowFunc(table.rows[length - ii - 1], traversar))
+                                               break;
+                               }
+                       }
+               }
+
+               traversar.selectionUpdater.restore();
+
+               cell = document.getElementById("x-evo-dialog-current-element");
+
+               if (cell)
+                       cell.removeAttribute("id");
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_GROUP, opType);
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+
+               if (traversar.anyChanged)
                        EvoEditor.EmitContentChanged();
+
+               if (cell)
+                       cell.id = "x-evo-dialog-current-element";
+       }
+
+       traversar.selectionUpdater = null;
+}
+
+EvoEditor.DialogUtilsTableSetAttribute = function(scope, attrName, attrValue)
+{
+       var traversar = {
+               attrName : attrName,
+               attrValue : attrValue,
+               anyChanged : false,
+
+               exec : function(cell) {
+                       if (EvoEditor.setAttributeWithUndoRedo("", cell, this.attrName, this.attrValue))
+                               this.anyChanged = true;
+
+                       return true;
                }
+       };
+
+       EvoEditor.dialogUtilsForeachTableScope(scope, traversar, "TableSetAttribute::" + attrName);
+}
+
+EvoEditor.DialogUtilsTableGetCellIsHeader = function()
+{
+       var element = document.getElementById("x-evo-dialog-current-element");
+
+       return element && element.tagName == "TH";
+}
+
+EvoEditor.DialogUtilsTableSetHeader = function(scope, isHeader)
+{
+       var traversar = {
+               isHeader : isHeader,
+               selectionUpdater : null,
+               anyChanged : false,
+
+               exec : function(cell) {
+                       if ((!this.isHeader && cell.tagName == "TD") ||
+                           (this.isHeader && cell.tagName == "TH"))
+                               return;
+
+                       this.anyChanged = true;
+
+                       var opType = this.isHeader ? "unsetheader" : "setheader";
+
+                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType, cell, cell,
+                               EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                       try {
+                               var node = document.createElement(this.isHeader ? "TH" : "TD");
+
+                               while(cell.firstChild) {
+                                       node.append(cell.firstChild);
+                               }
+
+                               var ii;
+
+                               for (ii = 0; ii < cell.attributes.length; ii++) {
+                                       node.setAttribute(cell.attributes[ii].name, 
cell.attributes[ii].value);
+                               }
+
+                               cell.parentElement.insertBefore(node, cell);
+
+                               if (this.selectionUpdater)
+                                       this.selectionUpdater.beforeRemove(cell);
+
+                               cell.parentElement.removeChild(cell);
+
+                               if (this.selectionUpdater)
+                                       this.selectionUpdater.afterRemove(node);
+                       } finally {
+                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType);
+                       }
+
+                       return true;
+               }
+       };
+
+       EvoEditor.dialogUtilsForeachTableScope(scope, traversar, "DialogUtilsTableSetHeader");
+}
+
+EvoEditor.DialogUtilsTableGetRowCount = function()
+{
+       var element = document.getElementById("x-evo-dialog-current-element");
+
+       if (!element)
+               return 0;
+
+       element = EvoEditor.getParentElement("TABLE", element, true);
+
+       if (!element)
+               return 0;
+
+       return element.rows.length;
+}
+
+EvoEditor.DialogUtilsTableSetRowCount = function(rowCount)
+{
+       var currentElem = document.getElementById("x-evo-dialog-current-element");
+
+       if (!currentElem)
+               return;
+
+       var table = EvoEditor.getParentElement("TABLE", currentElem, true);
+
+       if (!table || table.rows.length == rowCount)
+               return;
+
+       var selectionUpdater = EvoSelection.CreateUpdaterObject();
+
+       currentElem.removeAttribute("id");
+
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DialogUtilsTableSetRowCount", table, table, 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+
+       currentElem.id = "x-evo-dialog-current-element";
+
+       try {
+               var ii;
+
+               if (table.rows.length < rowCount) {
+                       var jj, nCells = table.rows.length ? table.rows[0].cells.length : 1;
+
+                       for (ii = table.rows.length; ii < rowCount; ii++) {
+                               var row;
+
+                               row = table.insertRow(-1);
+
+                               for (jj = 0; jj < nCells; jj++) {
+                                       row.insertCell(-1);
+                               }
+                       }
+               } else if (table.rows.length > rowCount) {
+                       for (ii = table.rows.length; ii > rowCount; ii--) {
+                               table.deleteRow(ii - 1);
+                       }
+               }
+
+               try {
+                       // it can fail, due to removed rows
+                       selectionUpdater.restore();
+               } catch (ex) {
+               }
+
+               currentElem = document.getElementById("x-evo-dialog-current-element");
+               if (!currentElem && table.rows.length > 0) {
+                       currentElem = table.rows[0].cells.length > 0 ? table.rows[0].cells[0] : null;
+               }
+
+               if (currentElem)
+                       currentElem.removeAttribute("id");
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DialogUtilsTableSetRowCount");
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+
+               if (currentElem)
+                       currentElem.id = "x-evo-dialog-current-element";
+       }
+}
+
+EvoEditor.DialogUtilsTableGetColumnCount = function()
+{
+       var element = document.getElementById("x-evo-dialog-current-element");
+
+       if (!element)
+               return 0;
+
+       element = EvoEditor.getParentElement("TABLE", element, true);
+
+       if (!element || !element.rows.length)
+               return 0;
+
+       return element.rows[0].cells.length;
+}
+
+EvoEditor.DialogUtilsTableSetColumnCount = function(columnCount)
+{
+       var currentElem = document.getElementById("x-evo-dialog-current-element");
+
+       if (!currentElem)
+               return;
+
+       var table = EvoEditor.getParentElement("TABLE", currentElem, true);
+
+       if (!table || !table.rows.length || table.rows[0].cells.length == columnCount)
+               return;
+
+       var selectionUpdater = EvoSelection.CreateUpdaterObject();
+
+       currentElem.removeAttribute("id");
+
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DialogUtilsTableSetColumnCount", table, 
table, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+
+       currentElem.id = "x-evo-dialog-current-element";
+
+       try {
+               var ii, jj;
+
+               for (jj = 0; jj < table.rows.length; jj++) {
+                       var row = table.rows[jj];
+
+                       if (row.cells.length < columnCount) {
+                               for (ii = row.cells.length; ii < columnCount; ii++) {
+                                       row.insertCell(-1);
+                               }
+                       } else if (row.cells.length > columnCount) {
+                               for (ii = row.cells.length; ii > columnCount; ii--) {
+                                       row.deleteCell(ii - 1);
+                               }
+                       }
+               }
+
+               try {
+                       // it can fail, due to removed columns
+                       selectionUpdater.restore();
+               } catch (ex) {
+               }
+
+               currentElem = document.getElementById("x-evo-dialog-current-element");
+               if (!currentElem && table.rows.length > 0) {
+                       currentElem = table.rows[0].cells.length > 0 ? table.rows[0].cells[0] : null;
+               }
+
+               if (currentElem)
+                       currentElem.removeAttribute("id");
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "DialogUtilsTableSetColumnCount");
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+
+               if (currentElem)
+                       currentElem.id = "x-evo-dialog-current-element";
+       }
+}
+
+EvoEditor.DialogUtilsTableDeleteCellContent = function()
+{
+       var traversar = {
+               anyChanged : false,
+
+               exec : function(cell) {
+                       if (cell.firstChild) {
+                               this.anyChanged = true;
+
+                               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"subdeletecellcontent", cell, cell, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                               try {
+                                       while (cell.firstChild) {
+                                               if (this.selectionUpdater)
+                                                       this.selectionUpdater.beforeRemove(cell.firstChild);
+
+                                               cell.removeChild(cell.firstChild);
+
+                                               if (this.selectionUpdater)
+                                                       this.selectionUpdater.afterRemove(cell);
+                                       }
+                               } finally {
+                                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"subdeletecellcontent");
+                               }
+                       }
+
+                       return true;
+               }
+       };
+
+       EvoEditor.dialogUtilsForeachTableScope(EvoEditor.E_CONTENT_EDITOR_SCOPE_CELL, traversar, 
"TableDeleteCellContent");
+}
+
+EvoEditor.DialogUtilsTableDeleteColumn = function()
+{
+       var traversar = {
+               anyChanged : false,
+
+               exec : function(cell) {
+                       this.anyChanged = true;
+
+                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "subdeletecolumn", cell, cell,
+                               EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                       try {
+                               if (this.selectionUpdater) {
+                                       this.selectionUpdater.beforeRemove(cell);
+                                       this.selectionUpdater.afterRemove(cell.nextElementSibling ? 
cell.nextElementSibling : cell.previousElementSibling);
+                               }
+
+                               cell.parentElement.removeChild(cell);
+                       } finally {
+                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "subdeletecolumn");
+                       }
+
+                       return true;
+               }
+       };
+
+       EvoEditor.dialogUtilsForeachTableScope(EvoEditor.E_CONTENT_EDITOR_SCOPE_COLUMN, traversar, 
"TableDeleteColumn");
+}
+
+EvoEditor.DialogUtilsTableDeleteRow = function()
+{
+       var traversar = {
+               anyChanged : false,
+
+               exec : function(cell) {
+                       this.anyChanged = true;
+
+                       var row = cell.parentElement;
+
+                       if (!row)
+                               return false;
+
+                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "subdeleterow", row, row,
+                               EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                       try {
+                               row.parentElement.deleteRow(row.rowIndex);
+                               // TODO handle changed selection and "x-evo-dialog-current-element"
+                       } finally {
+                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "subdeleterow");
+                       }
+
+                       return false;
+               }
+       };
+
+       EvoEditor.dialogUtilsForeachTableScope(EvoEditor.E_CONTENT_EDITOR_SCOPE_ROW, traversar, 
"TableDeleteColumn");
+}
+
+EvoEditor.DialogUtilsTableDelete = function()
+{
+       var element = document.getElementById("x-evo-dialog-current-element");
+
+       if (!element)
+               return;
+
+       element = EvoEditor.getParentElement("TABLE", element, true);
+
+       if (!element)
+               return;
+
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "TableDelete", element, element,
+               EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+       try {
+               element.parentElement.removeChild(element);
+               // TODO handle changed selection and "x-evo-dialog-current-element"
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "TableDelete");
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+       }
+}
+
+// 'what' can be "column" or "row",
+// 'where' can be lower than 0 for before/above, higher than 0 for after/below
+EvoEditor.DialogUtilsTableInsert = function(what, where)
+{
+       if (what != "column" && what != "row")
+               throw "EvoEditor.DialogUtilsTableInsert: 'what' (" + what + ") can be only 'column' or 'row'";
+       if (!where)
+               throw "EvoEditor.DialogUtilsTableInsert: 'where' cannot be zero";
+
+       var cell, table;
+
+       cell = document.getElementById("x-evo-dialog-current-element");
+
+       if (!cell)
+               return;
+
+       table = EvoEditor.getParentElement("TABLE", cell, true);
+
+       if (!table)
+               return;
+
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "TableInsert::" + what, table, table,
+               EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+       try {
+               var index, ii;
+
+               if (what == "column") {
+                       index = cell.cellIndex;
+
+                       if (where > 0)
+                               index++;
+
+                       for (ii = 0; ii < table.rows.length; ii++) {
+                               table.rows[ii].insertCell(index <= table.rows[ii].cells.length ? index : -1);
+                       }
+               } else { // what == "row"
+                       var row = EvoEditor.getParentElement("TR", cell, true);
+
+                       if (row) {
+                               index = row.rowIndex;
+
+                               if (where > 0)
+                                       index++;
+
+                               row = table.insertRow(index <= table.rows.length ? index : -1);
+
+                               for (ii = 0; ii < table.rows[0].cells.length; ii++) {
+                                       row.insertCell(-1);
+                               }
+                       }
+               }
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "TableInsert::" + what);
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
        }
 }
 
@@ -2619,7 +3321,7 @@ EvoEditor.onContextMenu = function(event)
 
        var nodeFlags = EvoEditor.E_CONTENT_EDITOR_NODE_UNKNOWN, res;
 
-       while (node) {
+       while (node && node.tagName != "BODY") {
                if (node.tagName == "A")
                        nodeFlags |= EvoEditor.E_CONTENT_EDITOR_NODE_IS_ANCHOR;
                else if (node.tagName == "HR")
@@ -2629,7 +3331,7 @@ EvoEditor.onContextMenu = function(event)
                else if (node.tagName == "TABLE")
                        nodeFlags |= EvoEditor.E_CONTENT_EDITOR_NODE_IS_TABLE;
                else if (node.tagName == "TD" || node.tagName == "TH")
-                       nodeFlags |= EvoEditor.E_CONTENT_EDITOR_NODE_IS_CELL;
+                       nodeFlags |= EvoEditor.E_CONTENT_EDITOR_NODE_IS_TABLE_CELL;
 
                node = node.parentElement;
        }
diff --git a/src/e-util/e-content-editor.c b/src/e-util/e-content-editor.c
index 698f39b39b..7ce8bff41c 100644
--- a/src/e-util/e-content-editor.c
+++ b/src/e-util/e-content-editor.c
@@ -2354,41 +2354,6 @@ e_content_editor_selection_wrap (EContentEditor *editor)
        iface->selection_wrap (editor);
 }
 
-void
-e_content_editor_get_caret_position (EContentEditor *editor,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
-{
-       EContentEditorInterface *iface;
-
-       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
-
-       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
-       g_return_if_fail (iface != NULL);
-       g_return_if_fail (iface->get_caret_position != NULL);
-
-       iface->get_caret_position (editor, cancellable, callback, user_data);
-}
-
-gboolean
-e_content_editor_get_caret_position_finish (EContentEditor *editor,
-                                           GAsyncResult *result,
-                                           guint *out_position,
-                                           guint *out_offset,
-                                           GError **error)
-{
-       EContentEditorInterface *iface;
-
-       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
-
-       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
-       g_return_val_if_fail (iface != NULL, FALSE);
-       g_return_val_if_fail (iface->get_caret_position_finish != NULL, FALSE);
-
-       return iface->get_caret_position_finish (editor, result, out_position, out_offset, error);
-}
-
 gchar *
 e_content_editor_get_current_signature_uid (EContentEditor *editor)
 {
diff --git a/src/e-util/e-content-editor.h b/src/e-util/e-content-editor.h
index ea68ef4ed5..ecc305168a 100644
--- a/src/e-util/e-content-editor.h
+++ b/src/e-util/e-content-editor.h
@@ -142,17 +142,6 @@ struct _EContentEditorInterface {
 
        void            (*selection_wrap)               (EContentEditor *editor);
 
-       void            (*get_caret_position)           (EContentEditor *editor,
-                                                        GCancellable *cancellable,
-                                                        GAsyncReadyCallback callback,
-                                                        gpointer user_data);
-
-       gboolean        (*get_caret_position_finish)    (EContentEditor *editor,
-                                                        GAsyncResult *result,
-                                                        guint *out_position,
-                                                        guint *out_offset,
-                                                        GError **error);
-
        gchar *         (*get_current_signature_uid)    (EContentEditor *editor);
 
        gboolean        (*is_ready)                     (EContentEditor *editor);
@@ -659,19 +648,6 @@ void               e_content_editor_selection_restore
 
 void           e_content_editor_selection_wrap (EContentEditor *editor);
 
-void           e_content_editor_get_caret_position
-                                               (EContentEditor *editor,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-
-gboolean       e_content_editor_get_caret_position_finish
-                                               (EContentEditor *editor,
-                                                GAsyncResult *result,
-                                                guint *out_position,
-                                                guint *out_offset,
-                                                GError **error);
-
 gchar *                e_content_editor_get_current_signature_uid
                                                (EContentEditor *editor);
 
diff --git a/src/e-util/e-html-editor-table-dialog.c b/src/e-util/e-html-editor-table-dialog.c
index 4f08e9bcd4..e13d914fff 100644
--- a/src/e-util/e-html-editor-table-dialog.c
+++ b/src/e-util/e-html-editor-table-dialog.c
@@ -214,8 +214,8 @@ html_editor_table_dialog_get_alignment (EHTMLEditorTableDialog *dialog)
        cnt_editor = e_html_editor_get_content_editor (editor);
 
        value = e_content_editor_table_get_align (cnt_editor);
-       gtk_combo_box_set_active_id (
-               GTK_COMBO_BOX (dialog->priv->alignment_combo), value);
+       gtk_combo_box_set_active_id (GTK_COMBO_BOX (dialog->priv->alignment_combo),
+               value && *value ? value : "left");
        g_free (value);
 }
 
@@ -394,32 +394,21 @@ html_editor_table_dialog_get_values (EHTMLEditorTableDialog *dialog)
 static void
 html_editor_table_dialog_reset_values (EHTMLEditorTableDialog *dialog)
 {
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->rows_edit), 3);
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->columns_edit), 3);
-       gtk_combo_box_set_active_id (
-               GTK_COMBO_BOX (dialog->priv->alignment_combo), "left");
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->rows_edit), 3);
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->columns_edit), 3);
+       gtk_combo_box_set_active_id (GTK_COMBO_BOX (dialog->priv->alignment_combo), "left");
 
-       gtk_toggle_button_set_active (
-               GTK_TOGGLE_BUTTON (dialog->priv->width_check), TRUE);
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->width_edit), 100);
-       gtk_combo_box_set_active_id (
-               GTK_COMBO_BOX (dialog->priv->width_units), "units-percent");
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->width_check), TRUE);
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->width_edit), 100);
+       gtk_combo_box_set_active_id (GTK_COMBO_BOX (dialog->priv->width_units), "units-percent");
 
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->spacing_edit), 2);
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->padding_edit), 1);
-       gtk_spin_button_set_value (
-               GTK_SPIN_BUTTON (dialog->priv->border_edit), 1);
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->spacing_edit), 2);
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->padding_edit), 1);
+       gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->border_edit), 1);
 
-       e_color_combo_set_current_color (
-               E_COLOR_COMBO (dialog->priv->background_color_picker), &transparent);
+       e_color_combo_set_current_color (E_COLOR_COMBO (dialog->priv->background_color_picker), &transparent);
 
-       gtk_file_chooser_unselect_all (
-               GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
+       gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
 
        html_editor_table_dialog_set_row_count (dialog);
        html_editor_table_dialog_set_column_count (dialog);
@@ -445,7 +434,10 @@ html_editor_table_dialog_show (GtkWidget *widget)
 
        e_content_editor_on_dialog_open (cnt_editor, E_CONTENT_EDITOR_DIALOG_TABLE);
 
-       html_editor_table_dialog_get_values (dialog);
+       if (!e_content_editor_table_get_row_count (cnt_editor))
+               html_editor_table_dialog_reset_values (dialog);
+       else
+               html_editor_table_dialog_get_values (dialog);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_table_dialog_parent_class)->show (widget);
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index ca3aa6996c..dea0c1db87 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -88,11 +88,6 @@ struct _EWebKitEditorPrivate {
        gboolean can_redo;
 
        gboolean reload_in_progress;
-       gboolean copy_paste_clipboard_in_view;
-       gboolean copy_paste_primary_in_view;
-       gboolean copy_cut_actions_triggered;
-       gboolean pasting_primary_clipboard;
-       gboolean pasting_from_itself_extension_value;
 
        guint32 style_flags;
        guint32 temporary_style_flags; /* that's for collapsed selection, format changes only after something 
is typed */
@@ -353,7 +348,7 @@ webkit_editor_extract_and_free_jsc_boolean (JSCValue *jsc_value,
        return value;
 }
 
-/*static gint32
+static gint32
 webkit_editor_extract_and_free_jsc_int32 (JSCValue *jsc_value,
                                          gint32 default_value)
 {
@@ -369,38 +364,237 @@ webkit_editor_extract_and_free_jsc_int32 (JSCValue *jsc_value,
        return value;
 }
 
-static gdouble
-webkit_editor_extract_and_free_jsc_double (JSCValue *jsc_value,
-                                          gdouble default_value)
+static gchar *
+webkit_editor_extract_and_free_jsc_string (JSCValue *jsc_value,
+                                          const gchar *default_value)
 {
-       gdouble value;
+       gchar *value;
 
-       if (jsc_value && jsc_value_is_number (jsc_value))
-               value = jsc_value_to_double (jsc_value);
+       if (jsc_value && jsc_value_is_string (jsc_value))
+               value = jsc_value_to_string (jsc_value);
        else
-               value = default_value;
+               value = g_strdup (default_value);
 
        g_clear_object (&jsc_value);
 
        return value;
-}*/
+}
+
+static const gchar *
+webkit_editor_utils_int_to_string (gchar *inout_buff,
+                                  gulong buff_len,
+                                  gint value)
+{
+       g_snprintf (inout_buff, buff_len, "%d", value);
+
+       return inout_buff;
+}
+
+static const gchar *
+webkit_editor_utils_int_with_unit_to_string (gchar *inout_buff,
+                                            gulong buff_len,
+                                            gint value,
+                                            EContentEditorUnit unit)
+{
+       if (unit == E_CONTENT_EDITOR_UNIT_AUTO)
+               g_snprintf (inout_buff, buff_len, "auto");
+       else
+               g_snprintf (inout_buff, buff_len, "%d%s",
+                       value,
+                       (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
+
+       return inout_buff;
+}
+
+static const gchar *
+webkit_editor_utils_color_to_string (gchar *inout_buff,
+                                    gulong buff_len,
+                                    const GdkRGBA *color)
+{
+       if (color && color->alpha > 1e-9)
+               g_snprintf (inout_buff, buff_len, "#%06x", e_rgba_to_value (color));
+       else if (buff_len)
+               inout_buff[0] = '\0';
+
+       return inout_buff;
+}
+
+static void
+webkit_editor_dialog_utils_set_attribute (EWebKitEditor *wk_editor,
+                                         const gchar *selector,
+                                         const gchar *name,
+                                         const gchar *value)
+{
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+       g_return_if_fail (name != NULL);
+
+       if (value) {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.DialogUtilsSetAttribute(%s, %s, %s);",
+                       selector, name, value);
+       } else {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.DialogUtilsSetAttribute(%s, %s, null);",
+                       selector, name);
+       }
+}
+
+static void
+webkit_editor_dialog_utils_set_attribute_int (EWebKitEditor *wk_editor,
+                                             const gchar *selector,
+                                             const gchar *name,
+                                             gint value)
+{
+       gchar str_value[64];
+
+       webkit_editor_dialog_utils_set_attribute (wk_editor, selector, name,
+               webkit_editor_utils_int_to_string (str_value, sizeof (str_value), value));
+}
+
+static void
+webkit_editor_dialog_utils_set_attribute_with_unit (EWebKitEditor *wk_editor,
+                                                   const gchar *selector,
+                                                   const gchar *name,
+                                                   gint value,
+                                                   EContentEditorUnit unit)
+{
+       gchar str_value[64];
+
+       webkit_editor_dialog_utils_set_attribute (wk_editor, selector, name,
+               webkit_editor_utils_int_with_unit_to_string (str_value, sizeof (str_value), value, unit));
+}
+
+static void
+webkit_editor_dialog_utils_set_attribute_color (EWebKitEditor *wk_editor,
+                                               const gchar *selector,
+                                               const gchar *name,
+                                               const GdkRGBA *color)
+{
+       gchar str_value[64];
+
+       webkit_editor_dialog_utils_set_attribute (wk_editor, selector, name,
+               webkit_editor_utils_color_to_string (str_value, sizeof (str_value), color));
+}
+
+static void
+webkit_editor_dialog_utils_set_table_attribute (EWebKitEditor *wk_editor,
+                                               EContentEditorScope scope,
+                                               const gchar *name,
+                                               const gchar *value)
+{
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+       g_return_if_fail (name != NULL);
+
+       if (value) {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.DialogUtilsTableSetAttribute(%d, %s, %s);",
+                       scope, name, value);
+       } else {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.DialogUtilsTableSetAttribute(%d, %s, null);",
+                       scope, name);
+       }
+}
 
 static gchar *
-webkit_editor_extract_and_free_jsc_string (JSCValue *jsc_value,
-                                          const gchar *default_value)
+webkit_editor_dialog_utils_get_attribute (EWebKitEditor *wk_editor,
+                                         const gchar *selector,
+                                         const gchar *name)
 {
-       gchar *value;
+       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), NULL);
+       g_return_val_if_fail (name != NULL, NULL);
 
-       if (jsc_value && jsc_value_is_string (jsc_value))
-               value = jsc_value_to_string (jsc_value);
+       return webkit_editor_extract_and_free_jsc_string (
+               webkit_editor_call_jsc_sync (wk_editor,
+                       "EvoEditor.DialogUtilsGetAttribute(%s, %s);",
+                       selector, name),
+               NULL);
+}
+
+static gint
+webkit_editor_dialog_utils_get_attribute_int (EWebKitEditor *wk_editor,
+                                             const gchar *selector,
+                                             const gchar *name,
+                                             gint default_value)
+{
+       gchar *attr;
+       gint value;
+
+       attr = webkit_editor_dialog_utils_get_attribute (wk_editor, selector, name);
+
+       if (attr && *attr)
+               value = atoi (attr);
        else
-               value = g_strdup (default_value);
+               value = default_value;
 
-       g_clear_object (&jsc_value);
+       g_free (attr);
 
        return value;
 }
 
+static gint
+webkit_editor_dialog_utils_get_attribute_with_unit (EWebKitEditor *wk_editor,
+                                                   const gchar *selector,
+                                                   const gchar *name,
+                                                   gint default_value,
+                                                   EContentEditorUnit *out_unit)
+{
+       gint result;
+       gchar *value;
+
+       *out_unit = E_CONTENT_EDITOR_UNIT_AUTO;
+
+       if (!wk_editor->priv->html_mode)
+               return default_value;
+
+       value = webkit_editor_dialog_utils_get_attribute (wk_editor, selector, name);
+
+       if (value && *value) {
+               result = atoi (value);
+
+               if (strstr (value, "%"))
+                       *out_unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
+               else if (g_ascii_strncasecmp (value, "auto", 4) != 0)
+                       *out_unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+       } else {
+               result = default_value;
+       }
+
+       g_free (value);
+
+       return result;
+}
+
+static void
+webkit_editor_dialog_utils_get_attribute_color (EWebKitEditor *wk_editor,
+                                               const gchar *selector,
+                                               const gchar *name,
+                                               GdkRGBA *out_color)
+{
+       gchar *value;
+
+       value = webkit_editor_dialog_utils_get_attribute (wk_editor, selector, name);
+
+       if (!value || !*value || !gdk_rgba_parse (out_color, value))
+               *out_color = transparent;
+
+       g_free (value);
+}
+
+static gboolean
+webkit_editor_dialog_utils_has_attribute (EWebKitEditor *wk_editor,
+                                         const gchar *name)
+{
+       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+
+       return webkit_editor_extract_and_free_jsc_boolean (
+               webkit_editor_call_jsc_sync (wk_editor,
+                       "EvoEditor.DialogUtilsHasAttribute(%s);",
+                       name),
+               FALSE);
+}
+
 static gint16
 e_webkit_editor_three_state_to_int16 (EThreeState value)
 {
@@ -496,11 +690,6 @@ webkit_editor_can_copy_cb (WebKitWebView *view,
 
        if (wk_editor->priv->can_copy != value) {
                wk_editor->priv->can_copy = value;
-               /* This means that we have an active selection thus the primary
-                * clipboard content is from composer. */
-               if (value)
-                       wk_editor->priv->copy_paste_primary_in_view = TRUE;
-               /* FIXME notify web extension about pasting content from itself */
                g_object_notify (G_OBJECT (wk_editor), "can-copy");
        }
 }
@@ -928,8 +1117,7 @@ undu_redo_state_changed_cb (WebKitUserContentManager *manager,
 static void
 dispatch_pending_operations (EWebKitEditor *wk_editor)
 {
-       if (wk_editor->priv->webkit_load_event != WEBKIT_LOAD_FINISHED ||
-           !wk_editor->priv->web_extension_proxy)
+       if (wk_editor->priv->webkit_load_event != WEBKIT_LOAD_FINISHED)
                return;
 
        /* Dispatch queued operations - as we are using this just for load
@@ -963,27 +1151,6 @@ current_page_id (EWebKitEditor *wk_editor)
        return webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (wk_editor));
 }
 
-static void
-webkit_editor_call_simple_extension_function_sync (EWebKitEditor *wk_editor,
-                                                  const gchar *method_name)
-{
-       GVariant *result;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               method_name,
-               g_variant_new ("(t)", current_page_id (wk_editor)),
-               NULL);
-
-       if (result)
-               g_variant_unref (result);
-}
-
 static void
 webkit_editor_call_simple_extension_function (EWebKitEditor *wk_editor,
                                               const gchar *method_name)
@@ -997,58 +1164,6 @@ webkit_editor_call_simple_extension_function (EWebKitEditor *wk_editor,
        printf ("%s: '%s'\n", __FUNCTION__, method_name);
 }
 
-static GVariant *
-webkit_editor_get_element_attribute (EWebKitEditor *wk_editor,
-                                     const gchar *selector,
-                                     const gchar *attribute)
-{
-       /*GVariant *result;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return NULL;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ElementGetAttributeBySelector",
-               g_variant_new ("(tss)", current_page_id (wk_editor), selector, attribute),
-               NULL);
-
-       return result;*/
-       printf ("%s: sel:'%s' attr:'%s'\n", __FUNCTION__, selector, attribute);
-       return NULL;
-}
-
-static void
-webkit_editor_set_element_attribute (EWebKitEditor *wk_editor,
-                                     const gchar *selector,
-                                     const gchar *attribute,
-                                     const gchar *value)
-{
-       /*guint64 page_id;
-
-       page_id = current_page_id (wk_editor);
-
-       e_web_extension_container_call_simple (wk_editor->priv->container, page_id, wk_editor->priv->stamp,
-               "ElementSetAttributeBySelector", g_variant_new ("(tsss)", page_id, selector, attribute, 
value));*/
-       printf ("%s: sel:'%s' attr:%s val:'%s'\n", __FUNCTION__, selector, attribute, value);
-}
-
-static void
-webkit_editor_remove_element_attribute (EWebKitEditor *wk_editor,
-                                        const gchar *selector,
-                                        const gchar *attribute)
-{
-       /*guint64 page_id;
-
-       page_id = current_page_id (wk_editor);
-
-       e_web_extension_container_call_simple (wk_editor->priv->container, page_id, wk_editor->priv->stamp,
-               "ElementRemoveAttributeBySelector", g_variant_new ("(tss)", page_id, selector, attribute));*/
-       printf ("%s: sel:'%s' attr:'%s'\n", __FUNCTION__, selector, attribute);
-}
-
 static void
 webkit_editor_queue_post_reload_operation (EWebKitEditor *wk_editor,
                                            PostReloadOperationFunc func,
@@ -1605,17 +1720,17 @@ webkit_editor_add_color_style (GString *css,
 }
 
 static void
-webkit_editor_set_color_attribute (EContentEditor *editor,
-                                  GString *script, /* serves two purposes, also says whether write to body 
or not */
-                                  const gchar *attr_name,
-                                  const GdkRGBA *value)
+webkit_editor_set_page_color_attribute (EContentEditor *editor,
+                                       GString *script, /* serves two purposes, also says whether write to 
body or not */
+                                       const gchar *attr_name,
+                                       const GdkRGBA *value)
 {
        EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
        if (value && value->alpha > 1e-9) {
                gchar color[64];
 
-               g_snprintf (color, 63, "#%06x", e_rgba_to_value (value));
+               webkit_editor_utils_color_to_string (color, sizeof (color), value);
 
                if (script) {
                        e_web_view_jsc_printf_script_gstring (script,
@@ -1643,7 +1758,7 @@ static void
 webkit_editor_page_set_text_color (EContentEditor *editor,
                                    const GdkRGBA *value)
 {
-       webkit_editor_set_color_attribute (editor, NULL, "text", value);
+       webkit_editor_set_page_color_attribute (editor, NULL, "text", value);
 }
 
 static void
@@ -1664,7 +1779,7 @@ static void
 webkit_editor_page_set_background_color (EContentEditor *editor,
                                          const GdkRGBA *value)
 {
-       webkit_editor_set_color_attribute (editor, NULL, "bgcolor", value);
+       webkit_editor_set_page_color_attribute (editor, NULL, "bgcolor", value);
 }
 
 static void
@@ -1685,7 +1800,7 @@ static void
 webkit_editor_page_set_link_color (EContentEditor *editor,
                                    const GdkRGBA *value)
 {
-       webkit_editor_set_color_attribute (editor, NULL, "link", value);
+       webkit_editor_set_page_color_attribute (editor, NULL, "link", value);
 }
 
 static void
@@ -1709,7 +1824,7 @@ static void
 webkit_editor_page_set_visited_link_color (EContentEditor *editor,
                                            const GdkRGBA *value)
 {
-       webkit_editor_set_color_attribute (editor, NULL, "vlink", value);
+       webkit_editor_set_page_color_attribute (editor, NULL, "vlink", value);
 }
 
 static void
@@ -1845,10 +1960,10 @@ webkit_editor_style_updated_cb (EWebKitEditor *wk_editor)
        css = g_string_sized_new (160);
        script = g_string_sized_new (256);
 
-       webkit_editor_set_color_attribute (cnt_editor, script, "x-evo-bgcolor", &bgcolor);
-       webkit_editor_set_color_attribute (cnt_editor, script, "x-evo-text", &fgcolor);
-       webkit_editor_set_color_attribute (cnt_editor, script, "x-evo-link", &link_color);
-       webkit_editor_set_color_attribute (cnt_editor, script, "x-evo-vlink", &vlink_color);
+       webkit_editor_set_page_color_attribute (cnt_editor, script, "x-evo-bgcolor", &bgcolor);
+       webkit_editor_set_page_color_attribute (cnt_editor, script, "x-evo-text", &fgcolor);
+       webkit_editor_set_page_color_attribute (cnt_editor, script, "x-evo-link", &link_color);
+       webkit_editor_set_page_color_attribute (cnt_editor, script, "x-evo-vlink", &vlink_color);
 
        webkit_editor_add_color_style (css, "html", "background-color", &bgcolor);
        webkit_editor_add_color_style (css, "html", "color", &fgcolor);
@@ -2423,30 +2538,13 @@ webkit_editor_selection_unindent (EContentEditor *editor)
 static void
 webkit_editor_cut (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       wk_editor->priv->copy_cut_actions_triggered = TRUE;
-
-       webkit_editor_call_simple_extension_function_sync (
-               wk_editor, "EEditorActionsSaveHistoryForCut");
-
-       webkit_web_view_execute_editing_command (
-               WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_CUT);
+       webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (editor), WEBKIT_EDITING_COMMAND_CUT);
 }
 
 static void
 webkit_editor_copy (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       wk_editor->priv->copy_cut_actions_triggered = TRUE;
-
-       webkit_web_view_execute_editing_command (
-               WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_COPY);
+       webkit_web_view_execute_editing_command (WEBKIT_WEB_VIEW (editor), WEBKIT_EDITING_COMMAND_COPY);
 }
 
 static ESpellChecker *
@@ -2460,13 +2558,9 @@ webkit_editor_get_spell_checker (EWebKitEditor *wk_editor)
 static gchar *
 webkit_editor_get_caret_word (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (editor), NULL);
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       return NULL;
+       return webkit_editor_extract_and_free_jsc_string (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), "EvoEditor.GetCaretWord();"),
+               NULL);
 }
 
 static void
@@ -2684,40 +2778,6 @@ webkit_editor_insert_signature (EContentEditor *editor,
        return ret_val;
 }
 
-static void
-webkit_editor_get_caret_position (EContentEditor *editor,
-                                 GCancellable *cancellable,
-                                 GAsyncReadyCallback callback,
-                                 gpointer user_data)
-{
-       EWebKitEditor *wk_editor;
-
-       g_return_if_fail (E_IS_WEBKIT_EDITOR (editor));
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       /* TODO */
-}
-
-static gboolean
-webkit_editor_get_caret_position_finish (EContentEditor *editor,
-                                        GAsyncResult *result,
-                                        guint *out_position,
-                                        guint *out_offset,
-                                        GError **error)
-{
-       EWebKitEditor *wk_editor;
-       gboolean success = FALSE;
-
-       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (editor), FALSE);
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       /* TODO */
-
-       return success;
-}
-
 static void
 webkit_editor_clear_undo_redo_history (EContentEditor *editor)
 {
@@ -3037,144 +3097,80 @@ webkit_editor_on_dialog_close (EContentEditor *editor,
 static void
 webkit_editor_delete_cell_contents (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogDeleteCellContents");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableDeleteCellContent();");
 }
 
 static void
 webkit_editor_delete_column (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogDeleteColumn");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableDeleteColumn();");
 }
 
 static void
 webkit_editor_delete_row (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogDeleteRow");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableDeleteRow();");
 }
 
 static void
 webkit_editor_delete_table (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogDeleteTable");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableDelete();");
 }
 
 static void
 webkit_editor_insert_column_after (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogInsertColumnAfter");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableInsert(%s, %d);", "column", +1);
 }
 
 static void
 webkit_editor_insert_column_before (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogInsertColumnBefore");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableInsert(%s, %d);", "column", -1);
 }
 
-
 static void
 webkit_editor_insert_row_above (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogInsertRowAbove");
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableInsert(%s, %d);", "row", -1);
 }
 
 static void
 webkit_editor_insert_row_below (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       webkit_editor_call_simple_extension_function (
-               wk_editor, "EEditorDialogInsertRowBelow");
-}
-
-static void
-webkit_editor_dialog_utils_set_attribute (EWebKitEditor *wk_editor,
-                                         const gchar *name,
-                                         const gchar *value)
-{
-       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
-       g_return_if_fail (name != NULL);
-
-       if (value) {
-               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
-                       "EvoEditor.DialogUtilsSetAttribute(%s, %s);",
-                       name, value);
-       } else {
-               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
-                       "EvoEditor.DialogUtilsSetAttribute(%s, null);",
-                       name);
-       }
-}
-
-static gchar *
-webkit_editor_dialog_utils_get_attribute (EWebKitEditor *wk_editor,
-                                         const gchar *name)
-{
-       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), NULL);
-       g_return_val_if_fail (name != NULL, NULL);
-
-       return webkit_editor_extract_and_free_jsc_string (
-               webkit_editor_call_jsc_sync (wk_editor,
-                       "EvoEditor.DialogUtilsGetAttribute(%s);",
-                       name),
-               NULL);
-}
-
-static gboolean
-webkit_editor_dialog_utils_has_attribute (EWebKitEditor *wk_editor,
-                                         const gchar *name)
-{
-       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       return webkit_editor_extract_and_free_jsc_boolean (
-               webkit_editor_call_jsc_sync (wk_editor,
-                       "EvoEditor.DialogUtilsHasAttribute(%s);",
-                       name),
-               FALSE);
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableInsert(%s, %d);", "row", +1);
 }
 
 static void
 webkit_editor_h_rule_set_align (EContentEditor *editor,
                                 const gchar *value)
 {
-       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), "align", value);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "align", value);
 }
 
 static gchar *
@@ -3182,7 +3178,7 @@ webkit_editor_h_rule_get_align (EContentEditor *editor)
 {
        gchar *value;
 
-       value = webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), "align");
+       value = webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "align");
 
        if (!value || !*value) {
                g_free (value);
@@ -3196,30 +3192,18 @@ static void
 webkit_editor_h_rule_set_size (EContentEditor *editor,
                                gint value)
 {
-       gchar size[64];
-
-       g_snprintf (size, sizeof (size), "%d", value);
-
-       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), "size", size);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "size", value);
 }
 
 static gint
 webkit_editor_h_rule_get_size (EContentEditor *editor)
 {
-       gint size = 2;
-       gchar *value;
-
-       value = webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), "size");
+       gint size;
 
-       if (value) {
-               if (*value)
-                       size = atoi (value);
-
-               if (!size)
-                       size = 2;
-       }
+       size = webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "size", 2);
 
-       g_free (value);
+       if (!size)
+               size = 2;
 
        return size;
 }
@@ -3229,35 +3213,18 @@ webkit_editor_h_rule_set_width (EContentEditor *editor,
                                 gint value,
                                 EContentEditorUnit unit)
 {
-       gchar width[64];
-
-       g_snprintf (width, sizeof (width), "%d%s",
-               value,
-               (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
-
-       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), "width", width);
+       webkit_editor_dialog_utils_set_attribute_with_unit (E_WEBKIT_EDITOR (editor), NULL, "width", value, 
unit);
 }
 
 static gint
 webkit_editor_h_rule_get_width (EContentEditor *editor,
                                 EContentEditorUnit *unit)
 {
-       gchar *width;
-       gint value = 0;
-
-       width = webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), "width");
-
-       *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+       gint value;
 
-       if (width) {
-               if (*width) {
-                       value = atoi (width);
+       value = webkit_editor_dialog_utils_get_attribute_with_unit (E_WEBKIT_EDITOR (editor), NULL, "width", 
0, unit);
 
-                       if (strstr (width, "%"))
-                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
-               }
-               g_free (width);
-       } else {
+       if (!value && *unit == E_CONTENT_EDITOR_UNIT_AUTO) {
                *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
                value = 100;
        }
@@ -3269,7 +3236,7 @@ static void
 webkit_editor_h_rule_set_no_shade (EContentEditor *editor,
                                    gboolean value)
 {
-       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), "noshade", value ? "" : NULL);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "noshade", value ? "" : 
NULL);
 }
 
 static gboolean
@@ -3282,20 +3249,7 @@ static void
 webkit_editor_insert_image (EContentEditor *editor,
                             const gchar *image_uri)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "DOMSelectionInsertImage",
-               g_variant_new ("(ts)", current_page_id (wk_editor), image_uri),
-               wk_editor->priv->cancellable);
+       webkit_web_view_execute_editing_command_with_argument (WEBKIT_WEB_VIEW (editor), "InsertImage", 
image_uri);
 }
 
 static void
@@ -3303,485 +3257,167 @@ webkit_editor_replace_image_src (EWebKitEditor *wk_editor,
                                  const gchar *selector,
                                  const gchar *image_uri)
 {
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "DOMReplaceImageSrc",
-               g_variant_new ("(tss)", current_page_id (wk_editor), selector, image_uri),
-               wk_editor->priv->cancellable);
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.ReplaceImageSrc(%s, %s);",
+               selector,
+               image_uri);
 }
 
 static void
 webkit_editor_image_set_src (EContentEditor *editor,
                              const gchar *value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       webkit_editor_replace_image_src (
-               wk_editor, "img#-x-evo-current-img", value);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "src", value);
 }
 
 static gchar *
 webkit_editor_image_get_src (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-img", "data-uri");
-
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "src");
 }
 
 static void
 webkit_editor_image_set_alt (EContentEditor *editor,
                              const gchar *value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-img", "alt", value);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "alt", value);
 }
 
 static gchar *
 webkit_editor_image_get_alt (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-img", "alt");
-
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "alt");
 }
 
 static void
 webkit_editor_image_set_url (EContentEditor *editor,
                              const gchar *value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorImageDialogSetElementUrl",
-               g_variant_new ("(ts)", current_page_id (wk_editor), value),
-               wk_editor->priv->cancellable);
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsSetImageUrl(%s);",
+               value);
 }
 
 static gchar *
 webkit_editor_image_get_url (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gchar *value = NULL;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return NULL;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorImageDialogGetElementUrl",
-               g_variant_new ("(t)", current_page_id (wk_editor)),
+       return webkit_editor_extract_and_free_jsc_string (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), "EvoEditor.DialogUtilsGetImageUrl();"),
                NULL);
-
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
 }
 
 static void
 webkit_editor_image_set_vspace (EContentEditor *editor,
                                 gint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementSetVSpace",
-               g_variant_new (
-                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "vspace", value);
 }
 
 static gint
 webkit_editor_image_get_vspace (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetVSpace",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "vspace", 0);
 }
 
 static void
 webkit_editor_image_set_hspace (EContentEditor *editor,
                                         gint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementSetHSpace",
-               g_variant_new (
-                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "hspace", value);
 }
 
 static gint
 webkit_editor_image_get_hspace (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetHSpace",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "hspace", 0);
 }
 
 static void
 webkit_editor_image_set_border (EContentEditor *editor,
                                 gint value)
 {
-       EWebKitEditor *wk_editor;
-       gchar *border;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       border = g_strdup_printf ("%d", value);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-img", "border", border);
-
-       g_free (border);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "border", value);
 }
 
 static gint
 webkit_editor_image_get_border (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gint value = 0;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-img", "border");
-
-       if (result) {
-               const gchar *border;
-               g_variant_get (result, "(&s)", &border);
-               if (border && *border)
-                       value = atoi (border);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "border", 0);
 }
 
 static void
 webkit_editor_image_set_align (EContentEditor *editor,
                                const gchar *value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-img", "align", value);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "align", value);
 }
 
 static gchar *
 webkit_editor_image_get_align (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-img", "align");
-
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "align");
 }
 
 static gint32
 webkit_editor_image_get_natural_width (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint32 value = 0;
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsGetImageWidth(true);"),
+               0);
+}
 
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetNaturalWidth",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
-}
-
-static gint32
-webkit_editor_image_get_natural_height (EContentEditor *editor)
-{
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint32 value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetNaturalHeight",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
-}
+static gint32
+webkit_editor_image_get_natural_height (EContentEditor *editor)
+{
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsGetImageHeight(true);"),
+               0);
+}
 
 static void
 webkit_editor_image_set_height (EContentEditor *editor,
                                 gint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementSetHeight",
-               g_variant_new (
-                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "height", value);
 }
 
 static void
 webkit_editor_image_set_width (EContentEditor *editor,
                                gint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementSetWidth",
-               g_variant_new (
-                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "width", value);
 }
 
 static void
 webkit_editor_image_set_height_follow (EContentEditor *editor,
                                       gboolean value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (value)
-               webkit_editor_set_element_attribute (
-                       wk_editor, "#-x-evo-current-img", "style", "height: auto;");
-       else
-               webkit_editor_remove_element_attribute (
-                       wk_editor, "#-x-evo-current-img", "style");
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "style", value ? "height: 
auto;" : NULL);
 }
 
 static void
 webkit_editor_image_set_width_follow (EContentEditor *editor,
                                      gboolean value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (value)
-               webkit_editor_set_element_attribute (
-                       wk_editor, "#-x-evo-current-img", "style", "width: auto;");
-       else
-               webkit_editor_remove_element_attribute (
-                       wk_editor, "#-x-evo-current-img", "style");
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "style", value ? "width: 
auto;" : NULL);
 }
 
 static gint32
 webkit_editor_image_get_width (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint32 value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetWidth",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsGetImageWidth(false);"),
+               0);
 }
 
 static gint32
 webkit_editor_image_get_height (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint32 value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ImageElementGetHeight",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsGetImageHeight(false);"),
+               0);
 }
 
 static void
@@ -3868,7 +3504,7 @@ static void
 webkit_editor_set_background_color (EWebKitEditor *wk_editor,
                                     const GdkRGBA *value)
 {
-       gchar *color;
+       gchar color[64];
 
        g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
 
@@ -3877,18 +3513,16 @@ webkit_editor_set_background_color (EWebKitEditor *wk_editor,
                return;
 
        if (value && value->alpha > 1e-9) {
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+               webkit_editor_utils_color_to_string (color, sizeof (color), value);
                g_clear_pointer (&wk_editor->priv->background_color, gdk_rgba_free);
                wk_editor->priv->background_color = gdk_rgba_copy (value);
        } else {
-               color = NULL;
+               g_snprintf (color, sizeof (color), "inherit");
                g_clear_pointer (&wk_editor->priv->background_color, gdk_rgba_free);
                wk_editor->priv->background_color = NULL;
        }
 
-       webkit_web_view_execute_editing_command_with_argument (WEBKIT_WEB_VIEW (wk_editor), "BackColor", 
color ? color : "inherit");
-
-       g_free (color);
+       webkit_web_view_execute_editing_command_with_argument (WEBKIT_WEB_VIEW (wk_editor), "BackColor", 
color);
 }
 
 static const GdkRGBA *
@@ -3928,7 +3562,7 @@ static void
 webkit_editor_set_font_color (EWebKitEditor *wk_editor,
                               const GdkRGBA *value)
 {
-       gchar *color;
+       gchar color[64];
 
        g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
 
@@ -3936,14 +3570,10 @@ webkit_editor_set_font_color (EWebKitEditor *wk_editor,
            (value && wk_editor->priv->font_color && gdk_rgba_equal (value, wk_editor->priv->font_color)))
                return;
 
-       if (value)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
-       else
-               color = NULL;
-
-       webkit_web_view_execute_editing_command_with_argument (WEBKIT_WEB_VIEW (wk_editor), "ForeColor", 
color ? color : "");
+       webkit_editor_utils_color_to_string (color, sizeof (color), value);
 
-       g_free (color);
+       webkit_web_view_execute_editing_command_with_argument (WEBKIT_WEB_VIEW (wk_editor), "ForeColor",
+               webkit_editor_utils_color_to_string (color, sizeof (color), value));
 }
 
 static const GdkRGBA *
@@ -4034,45 +3664,14 @@ webkit_editor_get_style_flag (EWebKitEditor *wk_editor,
 static gchar *
 webkit_editor_page_get_background_image_uri (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (wk_editor, "body", "data-uri");
-       if (result) {
-               gchar *value;
-
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return NULL;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), "body", "background");
 }
 
 static void
 webkit_editor_page_set_background_image_uri (EContentEditor *editor,
                                              const gchar *uri)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (uri && *uri)
-               webkit_editor_replace_image_src (wk_editor, "body", uri);
-       else {
-               e_util_invoke_g_dbus_proxy_call_with_error_check (
-                       wk_editor->priv->web_extension_proxy,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new ("(ts)", current_page_id (wk_editor), "body"),
-                       wk_editor->priv->cancellable);
-       }
+       webkit_editor_replace_image_src (E_WEBKIT_EDITOR (editor), "body", uri);
 }
 
 static void
@@ -4080,45 +3679,13 @@ webkit_editor_cell_set_v_align (EContentEditor *editor,
                                 const gchar *value,
                                 EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementVAlign",
-               g_variant_new ("(tsi)", current_page_id (wk_editor), value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "valign", value && 
*value ? value : NULL);
 }
 
 static gchar *
 webkit_editor_cell_get_v_align (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-cell", "valign");
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "valign");
 }
 
 static void
@@ -4126,45 +3693,13 @@ webkit_editor_cell_set_align (EContentEditor *editor,
                               const gchar *value,
                               EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementAlign",
-               g_variant_new ("(tsi)", current_page_id (wk_editor), value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "align", value && 
*value ? value : NULL);
 }
 
 static gchar *
 webkit_editor_cell_get_align (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-cell", "align");
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "align");
 }
 
 static void
@@ -4172,53 +3707,19 @@ webkit_editor_cell_set_wrap (EContentEditor *editor,
                              gboolean value,
                              EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementNoWrap",
-               g_variant_new ("(tbi)", current_page_id (wk_editor), !value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "nowrap", !value ? 
"" : NULL);
 }
 
 static gboolean
 webkit_editor_cell_get_wrap (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
        gboolean value = FALSE;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return FALSE;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return FALSE;
-       }
+       gchar *nowrap;
 
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "TableCellElementGetNoWrap",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
-               NULL);
+       nowrap = webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "nowrap");
+       value = !nowrap;
 
-       if (result) {
-               g_variant_get (result, "(b)", &value);
-               value = !value;
-               g_variant_unref (result);
-       }
+       g_free (nowrap);
 
        return value;
 }
@@ -4230,205 +3731,54 @@ webkit_editor_cell_set_header_style (EContentEditor *editor,
 {
        EWebKitEditor *wk_editor;
 
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (editor));
 
-       if (!wk_editor->priv->html_mode)
-               return;
+       wk_editor = E_WEBKIT_EDITOR (editor);
 
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementHeaderStyle",
-               g_variant_new ("(tbi)", current_page_id (wk_editor), value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableSetHeader(%d, %x);",
+               scope, value);
 }
 
 static gboolean
 webkit_editor_cell_is_header (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gboolean value = FALSE;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return FALSE;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return FALSE;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "ElementGetTagName",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
-               NULL);
-
-       if (result) {
-               const gchar *tag_name;
-
-               g_variant_get (result, "(&s)", &tag_name);
-               value = g_ascii_strncasecmp (tag_name, "TH", 2) == 0;
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_extract_and_free_jsc_boolean (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor),
+                       "EvoEditor.DialogUtilsTableGetCellIsHeader();"),
+               FALSE);
 }
 
 static gint
 webkit_editor_cell_get_width (EContentEditor *editor,
                               EContentEditorUnit *unit)
 {
-       EWebKitEditor *wk_editor;
-       gint value = 0;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       *unit = E_CONTENT_EDITOR_UNIT_AUTO;
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-cell", "width");
-
-       if (result) {
-               const gchar *width;
-
-               g_variant_get (result, "(&s)", &width);
-               if (width && *width) {
-                       value = atoi (width);
-                       if (strstr (width, "%"))
-                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
-                       else if (g_ascii_strncasecmp (width, "auto", 4) != 0)
-                               *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
-               }
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_with_unit (E_WEBKIT_EDITOR (editor), NULL, "width", 
0, unit);
 }
 
 static gint
 webkit_editor_cell_get_row_span (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gint value = 0;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "TableCellElementGetRowSpan",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "rowspan", 0);
 }
 
 static gint
 webkit_editor_cell_get_col_span (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gint value = 0;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "TableCellElementGetColSpan",
-               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(i)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "colspan", 0);
 }
 
 static gchar *
 webkit_editor_cell_get_background_image_uri (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-cell", "data-uri");
-       if (result) {
-               gchar *value;
-
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return NULL;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "background");
 }
 
 static void
 webkit_editor_cell_get_background_color (EContentEditor *editor,
                                          GdkRGBA *color)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               goto exit;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-cell", "bgcolor");
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (!value || !*value || !gdk_rgba_parse (color, value)) {
-                       g_variant_unref (result);
-                       goto exit;
-               }
-               g_variant_unref (result);
-               return;
-       }
-
- exit:
-       *color = transparent;
+       webkit_editor_dialog_utils_get_attribute_color (E_WEBKIT_EDITOR (editor), NULL, "bgcolor", color);
 }
 
 static void
@@ -4436,23 +3786,10 @@ webkit_editor_cell_set_row_span (EContentEditor *editor,
                                  gint value,
                                  EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
+       gchar str_value[64];
 
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementRowSpan",
-               g_variant_new ("(tii)", current_page_id (wk_editor), value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "rowspan",
+               webkit_editor_utils_int_to_string (str_value, sizeof (str_value), value));
 }
 
 static void
@@ -4460,23 +3797,10 @@ webkit_editor_cell_set_col_span (EContentEditor *editor,
                                  gint value,
                                  EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
+       gchar str_value[64];
 
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementColSpan",
-               g_variant_new ("(tii)", current_page_id (wk_editor), value, (gint32) scope),
-               wk_editor->priv->cancellable);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "colspan",
+               webkit_editor_utils_int_to_string (str_value, sizeof (str_value), value));
 }
 
 static void
@@ -4485,34 +3809,10 @@ webkit_editor_cell_set_width (EContentEditor *editor,
                               EContentEditorUnit unit,
                               EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-       gchar *width;
+       gchar str_value[64];
 
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (unit == E_CONTENT_EDITOR_UNIT_AUTO)
-               width = g_strdup ("auto");
-       else
-               width = g_strdup_printf (
-                       "%d%s",
-                       value,
-                       (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementWidth",
-               g_variant_new ("(tsi)", current_page_id (wk_editor), width, (gint32) scope),
-               wk_editor->priv->cancellable);
-
-       g_free (width);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "width",
+               webkit_editor_utils_int_with_unit_to_string (str_value, sizeof (str_value), value, unit));
 }
 
 static void
@@ -4520,163 +3820,55 @@ webkit_editor_cell_set_background_color (EContentEditor *editor,
                                          const GdkRGBA *value,
                                          EContentEditorScope scope)
 {
-       EWebKitEditor *wk_editor;
-       gchar *color;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (value && value->alpha > 1e-9)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
-       else
-               color = g_strdup ("");
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorCellDialogSetElementBgColor",
-               g_variant_new ("(tsi)", current_page_id (wk_editor), color, (gint32) scope),
-               wk_editor->priv->cancellable);
+       gchar str_value[64];
 
-       g_free (color);
+       webkit_editor_dialog_utils_set_table_attribute (E_WEBKIT_EDITOR (editor), scope, "bgcolor",
+               webkit_editor_utils_color_to_string (str_value, sizeof (str_value), value));
 }
 
 static void
 webkit_editor_cell_set_background_image_uri (EContentEditor *editor,
                                              const gchar *uri)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (uri && *uri)
-               webkit_editor_replace_image_src (wk_editor, "#-x-evo-current-cell", uri);
-       else {
-               e_util_invoke_g_dbus_proxy_call_with_error_check (
-                       wk_editor->priv->web_extension_proxy,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new ("(ts)", current_page_id (wk_editor), "#-x-evo-current-cell"),
-                       wk_editor->priv->cancellable);
-       }
+       webkit_editor_replace_image_src (E_WEBKIT_EDITOR (editor), NULL, uri);
 }
 
 static void
 webkit_editor_table_set_row_count (EContentEditor *editor,
                                    guint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorTableDialogSetRowCount",
-               g_variant_new ("(tu)", current_page_id (wk_editor), value),
-               wk_editor->priv->cancellable);
-}
-
-static guint
-webkit_editor_table_get_row_count (EContentEditor *editor)
-{
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       guint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorTableDialogGetRowCount",
-               g_variant_new ("(t)", current_page_id (wk_editor)),
-               NULL);
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       if (result) {
-               g_variant_get (result, "(u)", &value);
-               g_variant_unref (result);
-       }
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableSetRowCount(%d);",
+               value);
+}
 
-       return value;
+static guint
+webkit_editor_table_get_row_count (EContentEditor *editor)
+{
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsTableGetRowCount();"),
+               0);
 }
 
 static void
 webkit_editor_table_set_column_count (EContentEditor *editor,
                                       guint value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (editor);
 
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorTableDialogSetColumnCount",
-               g_variant_new ("(tu)", current_page_id (wk_editor), value),
-               wk_editor->priv->cancellable);
+       e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+               "EvoEditor.DialogUtilsTableSetColumnCount(%d);",
+               value);
 }
 
 static guint
 webkit_editor_table_get_column_count (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       guint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return 0;
-       }
-
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "EEditorTableDialogGetColumnCount",
-               g_variant_new ("(t)", current_page_id (wk_editor)),
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(u)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_extract_and_free_jsc_int32 (
+               webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), 
"EvoEditor.DialogUtilsTableGetColumnCount();"),
+               0);
 }
 
 static void
@@ -4684,330 +3876,93 @@ webkit_editor_table_set_width (EContentEditor *editor,
                                gint value,
                                EContentEditorUnit unit)
 {
-       EWebKitEditor *wk_editor;
-       gchar *width;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (unit == E_CONTENT_EDITOR_UNIT_AUTO)
-               width = g_strdup ("auto");
-       else
-               width = g_strdup_printf (
-                       "%d%s",
-                       value,
-                       (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "width", width);
-
-       g_free (width);
+       webkit_editor_dialog_utils_set_attribute_with_unit (E_WEBKIT_EDITOR (editor), NULL, "width", value, 
unit);
 }
 
 static guint
 webkit_editor_table_get_width (EContentEditor *editor,
                                EContentEditorUnit *unit)
 {
-       EWebKitEditor *wk_editor;
-       guint value = 0;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
-
-       if (!wk_editor->priv->html_mode)
-               return 0;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "width");
-
-       if (result) {
-               const gchar *width;
-
-               g_variant_get (result, "(&s)", &width);
-               if (width && *width) {
-                       value = atoi (width);
-                       if (strstr (width, "%"))
-                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
-                       else if (g_ascii_strncasecmp (width, "auto", 4) != 0)
-                               *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
-               }
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_with_unit (E_WEBKIT_EDITOR (editor), NULL, "width", 
0, unit);
 }
 
 static void
 webkit_editor_table_set_align (EContentEditor *editor,
                                const gchar *value)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "align", value);
+       webkit_editor_dialog_utils_set_attribute (E_WEBKIT_EDITOR (editor), NULL, "align", value);
 }
 
 static gchar *
 webkit_editor_table_get_align (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       gchar *value = NULL;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "align");
-       if (result) {
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "align");
 }
 
 static void
 webkit_editor_table_set_padding (EContentEditor *editor,
                                  gint value)
 {
-       EWebKitEditor *wk_editor;
-       gchar *padding;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       padding = g_strdup_printf ("%d", value);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "cellpadding", padding);
-
-       g_free (padding);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "cellpadding", value);
 }
 
 static gint
 webkit_editor_table_get_padding (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "cellpadding");
-
-       if (result) {
-               const gchar *padding;
-
-               g_variant_get (result, "(&s)", &padding);
-               if (padding && *padding)
-                       value = atoi (padding);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "cellpadding", 
0);
 }
 
 static void
 webkit_editor_table_set_spacing (EContentEditor *editor,
                                  gint value)
 {
-       EWebKitEditor *wk_editor;
-       gchar *spacing;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       spacing = g_strdup_printf ("%d", value);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "cellspacing", spacing);
-
-       g_free (spacing);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "cellspacing", value);
 }
 
 static gint
 webkit_editor_table_get_spacing (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "cellspacing");
-
-       if (result) {
-               const gchar *spacing;
-
-               g_variant_get (result, "(&s)", &spacing);
-               if (spacing && *spacing)
-                       value = atoi (spacing);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "cellspacing", 
0);
 }
 
 static void
 webkit_editor_table_set_border (EContentEditor *editor,
                                 gint value)
 {
-       EWebKitEditor *wk_editor;
-       gchar *border;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       border = g_strdup_printf ("%d", value);
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "border", border);
-
-       g_free (border);
+       webkit_editor_dialog_utils_set_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "border", value);
 }
 
 static gint
 webkit_editor_table_get_border (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-       gint value = 0;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "border");
-
-       if (result) {
-               const gchar *border;
-
-               g_variant_get (result, "(&s)", &border);
-               if (border && *border)
-                       value = atoi (border);
-               g_variant_unref (result);
-       }
-
-       return value;
+       return webkit_editor_dialog_utils_get_attribute_int (E_WEBKIT_EDITOR (editor), NULL, "border", 0);
 }
 
 static void
 webkit_editor_table_get_background_color (EContentEditor *editor,
                                           GdkRGBA *color)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               goto exit;
-
-       result = webkit_editor_get_element_attribute (
-               wk_editor, "#-x-evo-current-table", "bgcolor");
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (!value || !*value || !gdk_rgba_parse (color, value)) {
-                       g_variant_unref (result);
-                       goto exit;
-               }
-               g_variant_unref (result);
-               return;
-       }
-
- exit:
-       *color = transparent;
+       webkit_editor_dialog_utils_get_attribute_color (E_WEBKIT_EDITOR (editor), NULL, "bgcolor", color);
 }
 
 static void
 webkit_editor_table_set_background_color (EContentEditor *editor,
                                           const GdkRGBA *value)
 {
-       EWebKitEditor *wk_editor;
-       gchar *color;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (value->alpha != 0.0)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
-       else
-               color = g_strdup ("");
-
-       webkit_editor_set_element_attribute (
-               wk_editor, "#-x-evo-current-table", "bgcolor", color);
-
-       g_free (color);
+       webkit_editor_dialog_utils_set_attribute_color (E_WEBKIT_EDITOR (editor), NULL, "bgcolor", value);
 }
 
 static gchar *
 webkit_editor_table_get_background_image_uri (EContentEditor *editor)
 {
-       EWebKitEditor *wk_editor;
-       GVariant *result;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->html_mode)
-               return NULL;
-
-       result = webkit_editor_get_element_attribute (wk_editor, "#-x-evo-current-table", "data-uri");
-       if (result) {
-               gchar *value;
-
-               g_variant_get (result, "(s)", &value);
-               g_variant_unref (result);
-       }
-
-       return NULL;
+       return webkit_editor_dialog_utils_get_attribute (E_WEBKIT_EDITOR (editor), NULL, "background");
 }
 
 static void
 webkit_editor_table_set_background_image_uri (EContentEditor *editor,
                                               const gchar *uri)
 {
-       EWebKitEditor *wk_editor;
-
-       wk_editor = E_WEBKIT_EDITOR (editor);
-
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
-       if (!wk_editor->priv->html_mode)
-               return;
-
-       if (uri && *uri)
-               webkit_editor_replace_image_src (wk_editor, "#-x-evo-current-table", uri);
-       else {
-               e_util_invoke_g_dbus_proxy_call_with_error_check (
-                       wk_editor->priv->web_extension_proxy,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new ("(ts)", current_page_id (wk_editor), "#-x-evo-current-table"),
-                       wk_editor->priv->cancellable);
-       }
+       webkit_editor_replace_image_src (E_WEBKIT_EDITOR (editor), NULL, uri);
 }
 
 static gchar *
@@ -5951,75 +4906,6 @@ webkit_editor_load_changed_cb (EWebKitEditor *wk_editor,
        }
 }
 
-static void
-webkit_editor_clipboard_owner_change_cb (GtkClipboard *clipboard,
-                                         GdkEventOwnerChange *event,
-                                         EWebKitEditor *wk_editor)
-{
-       if (!E_IS_WEBKIT_EDITOR (wk_editor))
-               return;
-
-       if (!wk_editor->priv->web_extension_proxy)
-               return;
-
-       if (wk_editor->priv->copy_cut_actions_triggered && event->owner)
-               wk_editor->priv->copy_paste_clipboard_in_view = TRUE;
-       else
-               wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
-
-       if (wk_editor->priv->copy_paste_clipboard_in_view == 
wk_editor->priv->pasting_from_itself_extension_value)
-               return;
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "SetPastingContentFromItself",
-               g_variant_new (
-                       "(tb)",
-                       current_page_id (wk_editor),
-                       wk_editor->priv->copy_paste_clipboard_in_view),
-               wk_editor->priv->cancellable);
-
-       wk_editor->priv->copy_cut_actions_triggered = FALSE;
-
-       wk_editor->priv->pasting_from_itself_extension_value = wk_editor->priv->copy_paste_clipboard_in_view;
-}
-
-static void
-webkit_editor_primary_clipboard_owner_change_cb (GtkClipboard *clipboard,
-                                                 GdkEventOwnerChange *event,
-                                                 EWebKitEditor *wk_editor)
-{
-       if (!E_IS_WEBKIT_EDITOR (wk_editor) ||
-           !wk_editor->priv->web_extension_proxy)
-               return;
-
-       if (!event->owner || !wk_editor->priv->can_copy)
-               wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
-
-       if (wk_editor->priv->copy_paste_clipboard_in_view == 
wk_editor->priv->pasting_from_itself_extension_value)
-               return;
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "SetPastingContentFromItself",
-               g_variant_new (
-                       "(tb)",
-                       current_page_id (wk_editor),
-                       wk_editor->priv->copy_paste_clipboard_in_view),
-               wk_editor->priv->cancellable);
-
-       wk_editor->priv->pasting_from_itself_extension_value = wk_editor->priv->copy_paste_clipboard_in_view;
-}
-
-static gboolean
-webkit_editor_paste_prefer_text_html (EWebKitEditor *wk_editor)
-{
-       if (wk_editor->priv->pasting_primary_clipboard)
-               return wk_editor->priv->copy_paste_primary_in_view;
-       else
-               return wk_editor->priv->copy_paste_clipboard_in_view;
-}
-
 static void
 webkit_editor_paste_clipboard_targets_cb (GtkClipboard *clipboard,
                                           GdkAtom *targets,
@@ -6045,8 +4931,7 @@ webkit_editor_paste_clipboard_targets_cb (GtkClipboard *clipboard,
         * with SRCSET attribute in clipboard correctly). And if this fails the
         * source application can cancel the content and we could not fallback
         * to at least some content. */
-       if (wk_editor->priv->html_mode ||
-           webkit_editor_paste_prefer_text_html (wk_editor)) {
+       if (wk_editor->priv->html_mode) {
                if (e_targets_include_html (targets, n_targets)) {
                        content = e_clipboard_wait_for_html (clipboard);
                        is_html = TRUE;
@@ -6115,10 +5000,6 @@ webkit_editor_paste_primary (EContentEditor *editor)
 
        wk_editor = E_WEBKIT_EDITOR (editor);
 
-       /* Remember, that we are pasting primary clipboard to return
-        * correct value in e_html_editor_view_is_pasting_content_from_itself. */
-       wk_editor->priv->pasting_primary_clipboard = TRUE;
-
        webkit_editor_move_caret_on_current_coordinates (GTK_WIDGET (wk_editor));
 
        clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
@@ -6139,8 +5020,6 @@ webkit_editor_paste (EContentEditor *editor)
 
        wk_editor = E_WEBKIT_EDITOR (editor);
 
-       wk_editor->priv->pasting_primary_clipboard = FALSE;
-
        clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
        if (gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets)) {
@@ -6234,8 +5113,6 @@ webkit_editor_drag_data_received_cb (GtkWidget *widget,
                } else {
                        GTK_WIDGET_CLASS (e_webkit_editor_parent_class)->drag_leave(widget, context, time);
                        g_signal_stop_emission_by_name (widget, "drag-data-received");
-                       if (!is_move)
-                               webkit_editor_call_simple_extension_function (wk_editor, 
"DOMLastDropOperationDidCopy");
                        e_content_editor_emit_drop_handled (E_CONTENT_EDITOR (widget));
                }
                return;
@@ -6707,14 +5584,6 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
                wk_editor, "state-flags-changed",
                G_CALLBACK (webkit_editor_style_updated_cb), NULL);
 
-       wk_editor->priv->owner_change_primary_clipboard_cb_id = g_signal_connect (
-               gtk_clipboard_get (GDK_SELECTION_PRIMARY), "owner-change",
-               G_CALLBACK (webkit_editor_primary_clipboard_owner_change_cb), wk_editor);
-
-       wk_editor->priv->owner_change_clipboard_cb_id = g_signal_connect (
-               gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), "owner-change",
-               G_CALLBACK (webkit_editor_clipboard_owner_change_cb), wk_editor);
-
        g_settings = e_util_ref_settings ("org.gnome.desktop.interface");
        g_signal_connect (
                g_settings, "changed::font-name",
@@ -6750,11 +5619,6 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
        wk_editor->priv->can_paste = FALSE;
        wk_editor->priv->can_undo = FALSE;
        wk_editor->priv->can_redo = FALSE;
-       wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
-       wk_editor->priv->copy_paste_primary_in_view = FALSE;
-       wk_editor->priv->copy_cut_actions_triggered = FALSE;
-       wk_editor->priv->pasting_primary_clipboard = FALSE;
-       wk_editor->priv->pasting_from_itself_extension_value = FALSE;
        wk_editor->priv->current_user_stylesheet = NULL;
 
        wk_editor->priv->font_color = NULL;
@@ -6801,8 +5665,6 @@ e_webkit_editor_content_editor_init (EContentEditorInterface *iface)
        iface->selection_save = webkit_editor_selection_save;
        iface->selection_restore = webkit_editor_selection_restore;
        iface->selection_wrap = webkit_editor_selection_wrap;
-       iface->get_caret_position = webkit_editor_get_caret_position;
-       iface->get_caret_position_finish = webkit_editor_get_caret_position_finish;
        iface->get_current_signature_uid =  webkit_editor_get_current_signature_uid;
        iface->is_ready = webkit_editor_is_ready;
        iface->insert_signature = webkit_editor_insert_signature;
diff --git a/src/plugins/external-editor/external-editor.c b/src/plugins/external-editor/external-editor.c
index f53d7140ea..cdc2671a52 100644
--- a/src/plugins/external-editor/external-editor.c
+++ b/src/plugins/external-editor/external-editor.c
@@ -409,28 +409,6 @@ finished:
        return NULL;
 }
 
-static void
-launch_editor_caret_position_ready_cb (GObject *source_object,
-                                      GAsyncResult *result,
-                                      gpointer user_data)
-{
-       struct ExternalEditorData *eed = user_data;
-       GThread *editor_thread;
-       GError *error = NULL;
-
-       g_return_if_fail (E_IS_CONTENT_EDITOR (source_object));
-       g_return_if_fail (eed != NULL);
-
-       if (!e_content_editor_get_caret_position_finish (E_CONTENT_EDITOR (source_object),
-               result, &eed->cursor_position, &eed->cursor_offset, &error)) {
-               g_warning ("%s: Failed to get caret position: %s", G_STRFUNC, error ? error->message : 
"Unknown error");
-       }
-
-       editor_thread = g_thread_new (NULL, external_editor_thread, eed);
-       g_thread_unref (editor_thread);
-       g_clear_error (&error);
-}
-
 static void
 launch_editor_content_ready_cb (GObject *source_object,
                                GAsyncResult *result,
@@ -439,6 +417,7 @@ launch_editor_content_ready_cb (GObject *source_object,
        struct ExternalEditorData *eed = user_data;
        EContentEditor *cnt_editor;
        EContentEditorContentHash *content_hash;
+       GThread *editor_thread;
        GError *error = NULL;
 
        g_return_if_fail (E_IS_CONTENT_EDITOR (source_object));
@@ -453,8 +432,8 @@ launch_editor_content_ready_cb (GObject *source_object,
 
        eed->content = content_hash ? e_content_editor_util_get_content_data (content_hash, 
E_CONTENT_EDITOR_GET_TO_SEND_PLAIN) : NULL;
 
-       e_content_editor_get_caret_position (cnt_editor, NULL,
-               launch_editor_caret_position_ready_cb, eed);
+       editor_thread = g_thread_new (NULL, external_editor_thread, eed);
+       g_thread_unref (editor_thread);
 
        e_content_editor_util_free_content_hash (content_hash);
        g_clear_error (&error);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]