[evolution/wip/mcrha/webkit-jsc-api] Indent/Unindent in lists (UL/OL)
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/mcrha/webkit-jsc-api] Indent/Unindent in lists (UL/OL)
- Date: Fri, 29 Nov 2019 08:57:26 +0000 (UTC)
commit 52e095a9c7b948a0f83494fb6c19c34e2c88421c
Author: Milan Crha <mcrha redhat com>
Date: Fri Nov 29 09:58:23 2019 +0100
Indent/Unindent in lists (UL/OL)
data/webkit/e-convert.js | 14 +-
data/webkit/e-editor.js | 391 +++++++++++++++++++++++-----
data/webkit/e-undo-redo.js | 233 ++++++++++-------
src/e-util/test-html-editor-units-utils.c | 4 +-
src/e-util/test-html-editor-units.c | 145 ++++++-----
src/modules/webkit-editor/e-webkit-editor.c | 96 ++++---
6 files changed, 620 insertions(+), 263 deletions(-)
---
diff --git a/data/webkit/e-convert.js b/data/webkit/e-convert.js
index 9701f70ae8..50a67d592a 100644
--- a/data/webkit/e-convert.js
+++ b/data/webkit/e-convert.js
@@ -177,10 +177,18 @@ EvoConvert.replaceList = function(element, tagName)
level++;
}
- if (!(level % 2))
+ switch (level % 2) {
+ default:
+ case 0:
prefixSuffix = " * ";
- else
- prefixSuffix = " # ";
+ break;
+ case 1:
+ prefixSuffix = " - ";
+ break;
+ case 2:
+ prefixSuffix = " + ";
+ break;
+ }
indent = 3;
} else {
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 7068339ed2..9d4c5eb45f 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -322,6 +322,9 @@ EvoEditor.maybeUpdateFormattingState = function(force)
if (Number.isInteger(tmp)) {
obj.indented = tmp > 0;
}
+
+ if (parent.tagName == "UL" || parent.tagName == "OL")
+ obj.indented = true;
}
if (obj.bgColor == null && parent.style.backgroundColor != "") {
@@ -414,18 +417,18 @@ EvoEditor.foreachChildRecur = function(topParent, parent, firstChildIndex, lastC
while (child && ii >= 0) {
next = child.nextElementSibling;
- if (!traversar.onlyBlockElements || EvoEditor.IsBlockNode(child)) {
- if (!traversar.exec(topParent, child)) {
- return false;
- }
- }
-
if (child.children.length > 0 &&
!traversar.flat &&
!EvoEditor.foreachChildRecur(topParent, child, 0, child.children.length - 1, traversar)) {
return false;
}
+ if (!traversar.onlyBlockElements || EvoEditor.IsBlockNode(child)) {
+ if (!traversar.exec(topParent, child)) {
+ return false;
+ }
+ }
+
child = next;
ii--;
}
@@ -651,6 +654,12 @@ EvoEditor.RestoreSelection = function()
}
}
+EvoEditor.removeEmptyStyleAttribute = function(element)
+{
+ if (element && !element.style.length)
+ element.removeAttribute("style");
+}
+
EvoEditor.applySetAlignment = function(record, isUndo)
{
if (record.changes) {
@@ -662,14 +671,23 @@ EvoEditor.applySetAlignment = function(record, isUndo)
}
for (ii = 0; ii < record.changes.length; ii++) {
- var change = record.changes[ii];
+ var change = record.changes[isUndo ? (record.changes.length - ii - 1) : ii];
child = EvoSelection.FindElementByPath(parent, change.path);
if (!child) {
throw "EvoEditor.applySetAlignment: Cannot find child";
}
- child.style.textAlign = isUndo ? change.before : record.applyValueAfter;
+ if (isUndo) {
+ child.style.textAlign = change.before;
+ } else if ((record.applyValueAfter == "left" && child.style.direction != "rtl" &&
window.getComputedStyle(child).direction != "rtl") ||
+ (record.applyValueAfter == "right" && (child.style.direction == "rtl" ||
window.getComputedStyle(child).direction == "rtl"))) {
+ child.style.textAlign = "";
+ } else {
+ child.style.textAlign = record.applyValueAfter;
+ }
+
+ EvoEditor.removeEmptyStyleAttribute(child);
}
}
}
@@ -699,7 +717,15 @@ EvoEditor.SetAlignment = function(alignment)
}
traversar.anyChanged = true;
- element.style.textAlign = traversar.toSet;
+
+ if ((traversar.toSet == "left" && element.style.direction != "rtl" &&
window.getComputedStyle(element).direction != "rtl") ||
+ (traversar.toSet == "right" && (element.style.direction == "rtl" ||
window.getComputedStyle(element).direction == "rtl"))) {
+ element.style.textAlign = "";
+ } else {
+ element.style.textAlign = traversar.toSet;
+ }
+
+ EvoEditor.removeEmptyStyleAttribute(element);
}
return true;
@@ -993,6 +1019,91 @@ EvoEditor.SetBlockFormat = function(format)
}
}
+EvoEditor.allChildrenInSelection = function(element, allowPartial, affected)
+{
+ if (!element || !element.firstChild)
+ return false;
+
+ var selection = document.getSelection(), all;
+
+ all = selection.containsNode(element.firstElementChild, allowPartial) &&
+ selection.containsNode(element.lastElementChild, allowPartial);
+
+ var node;
+
+ affected.length = 0;
+
+ for (node = element.firstElementChild; node; node = node.nextElementSibling) {
+ if (all || selection.containsNode(node, allowPartial))
+ affected[affected.length] = node;
+ }
+
+ return all;
+}
+
+EvoEditor.splitList = function(element, nParents, onlyAffected)
+{
+ var parent, from;
+
+ if (onlyAffected && onlyAffected.length)
+ from = onlyAffected[onlyAffected.length - 1].nextElementSibling;
+ else
+ from = element.nextElementSibling;
+
+ if (nParents == -1) {
+ nParents = 0;
+
+ for (parent = from; parent && parent.tagName != "BODY"; parent = parent.parentElement) {
+ nParents++;
+ }
+ }
+
+ var nextFrom, clone;
+
+ parent = from ? from.parentElement : element.parentElement;
+
+ while (nParents > 0 && parent && parent.tagName != "HTML") {
+ nParents--;
+ nextFrom = null;
+
+ if (from) {
+ clone = from.parentElement.cloneNode(false);
+ from.parentElement.parentElement.insertBefore(clone,
from.parentElement.nextElementSibling);
+
+ nextFrom = clone;
+
+ while (from.nextElementSibling) {
+ clone.appendChild(from.nextElementSibling);
+ }
+
+ clone.insertBefore(from, clone.firstElementChild);
+ }
+
+ from = nextFrom;
+ parent = parent.parentElement;
+ }
+
+ if (nextFrom)
+ return nextFrom;
+
+ return parent.nextElementSibling;
+}
+
+EvoEditor.insertListChildBefore = function(child, parent, insBefore)
+{
+ if (child.tagName == "LI") {
+ var node = document.createElement("DIV");
+
+ while(child.firstChild)
+ node.appendChild(child.firstChild);
+
+ parent.insertBefore(node, insBefore);
+ child.parentElement.removeChild(child);
+ } else {
+ parent.insertBefore(child, insBefore);
+ }
+}
+
EvoEditor.applyIndent = function(record, isUndo)
{
if (record.changes) {
@@ -1004,13 +1115,18 @@ EvoEditor.applyIndent = function(record, isUndo)
}
for (ii = 0; ii < record.changes.length; ii++) {
- var change = record.changes[ii];
+ var change = record.changes[isUndo ? (record.changes.length - ii - 1) : ii];
- child = EvoSelection.FindElementByPath(parent, change.path);
+ child = EvoSelection.FindElementByPath(change.pathIsFromBody ? document.body :
parent, change.path);
if (!child) {
throw "EvoEditor.applyIndent: Cannot find child";
}
+ if (change.isList) {
+ EvoUndoRedo.RestoreChildren(change, child, isUndo);
+ continue;
+ }
+
if (isUndo) {
child.style.marginLeft = change.beforeMarginLeft;
child.style.marginRight = change.beforeMarginRight;
@@ -1018,6 +1134,8 @@ EvoEditor.applyIndent = function(record, isUndo)
child.style.marginLeft = change.afterMarginLeft;
child.style.marginRight = change.afterMarginRight;
}
+
+ EvoEditor.removeEmptyStyleAttribute(child);
}
}
}
@@ -1026,63 +1144,203 @@ EvoEditor.Indent = function(increment)
{
var traversar = {
record : null,
+ selectionUpdater : null,
increment : increment,
- flat : false,
+ flat : true,
onlyBlockElements : true,
exec : function(parent, element) {
- var change = null;
+ var change = null, isList = element.tagName == "UL" || element.tagName == "OL";
+ var isNested = isList && (element.parentElement.tagName == "UL" ||
element.parentElement.tagName == "OL");
if (traversar.record) {
if (!traversar.record.changes)
traversar.record.changes = [];
change = {};
- change.path = EvoSelection.GetChildPath(parent, element);
- change.beforeMarginLeft = element.style.marginLeft;
- change.beforeMarginRight = element.style.marginRight;
+
+ change.pathIsFromBody = false;
+
+ if (isList) {
+ change.isList = isList;
+ change.path = EvoSelection.GetChildPath(parent, element);
+ } else {
+ change.path = EvoSelection.GetChildPath(parent, element);
+ change.beforeMarginLeft = element.style.marginLeft;
+ change.beforeMarginRight = element.style.marginRight;
+ }
traversar.record.changes[traversar.record.changes.length] = change;
}
- var currValue = null, dir;
+ if (isList) {
+ var elemParent = null, all, affected = [], jj;
- dir = window.getComputedStyle(element).direction;
+ all = EvoEditor.allChildrenInSelection(element, true, affected);
- if (dir == "rtl") {
- if (element.style.marginRight.endsWith("ch"))
- currValue = element.style.marginRight;
- } else { // "ltr" or other
- if (element.style.marginLeft.endsWith("ch"))
- currValue = element.style.marginLeft;
- }
+ if (this.increment) {
+ var clone;
+
+ clone = element.cloneNode(false);
+
+ if (all) {
+ if (change) {
+ var childIndex =
EvoEditor.GetChildIndex(element.parentElement, element);
+ EvoUndoRedo.BackupChildrenBefore(change,
element.parentElement, childIndex, childIndex);
+ change.path = EvoSelection.GetChildPath(parent,
element.parentElement);
+ }
+
+ element.parentElement.insertBefore(clone, element);
+ clone.appendChild(element);
+
+ if (change)
+ EvoUndoRedo.BackupChildrenAfter(change,
clone.parentElement);
+ } else if (affected.length > 0) {
+ if (change) {
+ EvoUndoRedo.BackupChildrenBefore(change, element,
+ EvoEditor.GetChildIndex(element, affected[0]),
+ EvoEditor.GetChildIndex(element,
affected[affected.length - 1]));
+ }
+
+ element.insertBefore(clone, affected[0]);
+
+ for (jj = 0; jj < affected.length; jj++) {
+ clone.appendChild(affected[jj]);
+ }
+
+ if (change)
+ EvoUndoRedo.BackupChildrenAfter(change, element);
+ }
+ } else {
+ var insBefore = null;
+
+ elemParent = element.parentElement;
+
+ // decrease indent in nested lists of the same type will merge items
into one list
+ if (isNested && elemParent.tagName == element.tagName &&
+ elemParent.getAttribute("type") == element.getAttribute("type")) {
+ if (change) {
+ var childIndex = EvoEditor.GetChildIndex(elemParent,
element);
+ EvoUndoRedo.BackupChildrenBefore(change, elemParent,
childIndex, childIndex);
+ change.path = EvoSelection.GetChildPath(parent,
elemParent);
+ }
+
+ if (!all && affected.length > 0 && !(affected[0] ===
element.firstElementChild)) {
+ insBefore = EvoEditor.splitList(element, 1, affected);
+ } else {
+ insBefore = element;
+ }
+
+ for (jj = 0; jj < affected.length; jj++) {
+ elemParent.insertBefore(affected[jj], insBefore);
+ }
+
+ if (!element.childElementCount) {
+ this.selectionUpdater.beforeRemove(element);
+
+ element.parentElement.removeChild(element);
+
+ this.selectionUpdater.afterRemove(affected[0]);
+ }
+
+ if (change)
+ EvoUndoRedo.BackupChildrenAfter(change, elemParent);
+ } else {
+ var tmpElement = element;
+
+ if (isNested) {
+ tmpElement = elemParent;
+ elemParent = elemParent.parentElement;
+ }
+
+ if (change) {
+ var childIndex = EvoEditor.GetChildIndex(elemParent,
tmpElement);
+ EvoUndoRedo.BackupChildrenBefore(change, elemParent,
childIndex, childIndex);
+ if (isNested) {
+ change.pathIsFromBody = true;
+ change.path =
EvoSelection.GetChildPath(document.body, elemParent);
+ } else {
+ change.path =
EvoSelection.GetChildPath(parent, elemParent);
+ }
+ }
+
+ if (isNested) {
+ var clone;
+
+ insBefore = EvoEditor.splitList(element, 2, affected);
+
+ clone = element.cloneNode(false);
+ elemParent.insertBefore(clone, insBefore);
- if (!currValue) {
- currValue = 0;
+ for (jj = 0; jj < affected.length; jj++) {
+ clone.appendChild(affected[jj]);
+ }
+ } else {
+ if (!all && affected.length > 0 && !(affected[0] ===
element.firstElementChild)) {
+ insBefore = EvoEditor.splitList(element, 1,
affected);
+ } else {
+ insBefore = element.nextElementSibling;
+ }
+
+ for (jj = 0; jj < affected.length; jj++) {
+ EvoEditor.insertListChildBefore(affected[jj],
insBefore ? insBefore.parentElement : elemParent, insBefore);
+ }
+ }
+
+ if (!element.childElementCount) {
+ this.selectionUpdater.beforeRemove(element);
+
+ element.parentElement.removeChild(element);
+
+ this.selectionUpdater.afterRemove(insBefore ?
insBefore.previousElementSibling : elemParent.lastElementChild);
+ }
+
+ if (change)
+ EvoUndoRedo.BackupChildrenAfter(change, elemParent);
+ }
+ }
} else {
- currValue = parseInt(currValue.slice(0, -2));
- if (!Number.isInteger(currValue))
+ var currValue = null, dir;
+
+ dir = window.getComputedStyle(element).direction;
+
+ if (dir == "rtl") {
+ if (element.style.marginRight.endsWith("ch"))
+ currValue = element.style.marginRight;
+ } else { // "ltr" or other
+ if (element.style.marginLeft.endsWith("ch"))
+ currValue = element.style.marginLeft;
+ }
+
+ if (!currValue) {
currValue = 0;
- }
+ } else {
+ currValue = parseInt(currValue.slice(0, -2));
+ if (!Number.isInteger(currValue))
+ currValue = 0;
+ }
- if (traversar.increment) {
- currValue = (currValue + EvoEditor.TEXT_INDENT_SIZE) + "ch";
- } else if (currValue > EvoEditor.TEXT_INDENT_SIZE) {
- currValue = (currValue - EvoEditor.TEXT_INDENT_SIZE) + "ch";
- } else if (currValue > 0) {
- currValue = "";
- }
+ if (traversar.increment) {
+ currValue = (currValue + EvoEditor.TEXT_INDENT_SIZE) + "ch";
+ } else if (currValue > EvoEditor.TEXT_INDENT_SIZE) {
+ currValue = (currValue - EvoEditor.TEXT_INDENT_SIZE) + "ch";
+ } else if (currValue > 0) {
+ currValue = "";
+ }
- if (dir == "rtl") {
- element.style.marginRight = currValue;
- } else { // "ltr" or other
- element.style.marginLeft = currValue;
- }
+ if (dir == "rtl") {
+ element.style.marginRight = currValue;
+ } else { // "ltr" or other
+ element.style.marginLeft = currValue;
+ }
+
+ if (change) {
+ change.afterMarginLeft = element.style.marginLeft;
+ change.afterMarginRight = element.style.marginRight;
+ }
- if (change) {
- change.afterMarginLeft = element.style.marginLeft;
- change.afterMarginRight = element.style.marginRight;
+ EvoEditor.removeEmptyStyleAttribute(element);
}
return true;
@@ -1092,6 +1350,7 @@ EvoEditor.Indent = function(increment)
var affected = EvoEditor.ClaimAffectedContent(null, null,
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE);
traversar.record = EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, increment ? "Indent" :
"Outdent", null, null, EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE);
+ traversar.selectionUpdater = EvoSelection.CreateUpdaterObject();
try {
EvoEditor.ForeachChildInAffectedContent(affected, traversar);
@@ -1100,6 +1359,8 @@ EvoEditor.Indent = function(increment)
traversar.record.applyIncrement = increment;
traversar.record.apply = EvoEditor.applyIndent;
}
+
+ traversar.selectionUpdater.restore();
} finally {
EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, increment ? "Indent" : "Outdent");
EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
@@ -1163,8 +1424,10 @@ EvoEditor.applySetBodyFontName = function(record, isUndo)
{
EvoEditor.UpdateStyleSheet("x-evo-body-fontname", isUndo ? record.beforeCSS : record.afterCSS);
- if (record.beforeStyle != record.afterStyle)
+ if (record.beforeStyle != record.afterStyle) {
document.body.style.fontFamily = isUndo ? record.beforeStyle : record.afterStyle;
+ EvoEditor.removeEmptyStyleAttribute(body.document);
+ }
}
EvoEditor.SetBodyFontName = function(name)
@@ -1197,6 +1460,8 @@ EvoEditor.SetBodyFontName = function(name)
if (record.beforeCSS == record.afterCSS && record.beforeStyle == record.afterStyle)
record.ignore = true;
}
+
+ EvoEditor.removeEmptyStyleAttribute(document.body);
} finally {
EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "setBodyFontName");
EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_YES);
@@ -1238,6 +1503,7 @@ EvoEditor.convertParagraphs = function(parent, wrapWidth)
if (child.tagName == "DIV") {
if (wrapWidth == -1) {
child.style.width = "";
+ EvoEditor.removeEmptyStyleAttribute(child);
} else {
child.style.width = wrapWidth + "ch";
}
@@ -1253,6 +1519,7 @@ EvoEditor.convertParagraphs = function(parent, wrapWidth)
} else if (child.tagName == "UL") {
if (wrapWidth == -1) {
child.style.width = "";
+ EvoEditor.removeEmptyStyleAttribute(child);
} else {
var innerWrapWidth = wrapWidth;
@@ -1267,10 +1534,11 @@ EvoEditor.convertParagraphs = function(parent, wrapWidth)
if (wrapWidth == -1) {
child.style.width = "";
child.style.paddingInlineStart = "";
+ EvoEditor.removeEmptyStyleAttribute(child);
} else {
var innerWrapWidth = wrapWidth, olNeedWidth;
- olNeedWidth = EvoEditor.GetOLMaxLetters(child.getAttribute("type"),
child.children.length) + 2; // length of ". " suffix
+ olNeedWidth = EvoConvert.GetOLMaxLetters(child.getAttribute("type"),
child.children.length) + 2; // length of ". " suffix
if (olNeedWidth < EvoConvert.MIN_OL_WIDTH)
olNeedWidth = EvoConvert.MIN_OL_WIDTH;
@@ -1339,28 +1607,15 @@ EvoEditor.applyFontReset = function(record, isUndo)
if (record.changes) {
var ii;
- if (isUndo) {
- for (ii = record.changes.length - 1; ii >= 0; ii--) {
- var change = record.changes[ii];
- var parent = EvoSelection.FindElementByPath(document.body, change.parentPath);
-
- if (!parent) {
- throw "EvoEditor.applyFontReset: Cannot find node at path " +
change.path;
- }
+ for (ii = 0; ii < record.changes.length; ii++) {
+ var change = record.changes[isUndo ? (record.changes.length - ii - 1) : ii];
+ var parent = EvoSelection.FindElementByPath(document.body, change.parentPath);
- parent.innerHTML = change.htmlBefore;
+ if (!parent) {
+ throw "EvoEditor.applyFontReset: Cannot find node at path " + change.path;
}
- } else {
- for (ii = 0; ii < record.changes.length; ii++) {
- var change = record.changes[ii];
- var parent = EvoSelection.FindElementByPath(document.body, change.parentPath);
- if (!parent) {
- throw "EvoEditor.applyFontReset: Cannot find node at path " +
change.path;
- }
-
- parent.innerHTML = change.htmlAfter;
- }
+ parent.innerHTML = isUndo ? change.htmlBefore : change.htmlAfter;
}
}
}
@@ -1485,6 +1740,8 @@ EvoEditor.SetFontName = function(name)
EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_GROUP, "SetFontName");
EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
EvoEditor.EmitContentChanged();
+
+ EvoEditor.removeEmptyStyleAttribute(document.body);
}
}
@@ -1689,7 +1946,7 @@ EvoEditor.GetContent = function(flags, cid_uid_prefix)
content_data["to-send-html"] = EvoEditor.convertHtmlToSend();
if ((flags & EvoEditor. E_CONTENT_EDITOR_GET_TO_SEND_PLAIN) != 0) {
- content_data["to-send-plain"] = EvoConvert.ToPlainText(document.body);
+ content_data["to-send-plain"] = EvoConvert.ToPlainText(document.body,
EvoEditor.NORMAL_PARAGRAPH_WIDTH);
}
} finally {
try {
diff --git a/data/webkit/e-undo-redo.js b/data/webkit/e-undo-redo.js
index 8d907644e4..3f22f36d61 100644
--- a/data/webkit/e-undo-redo.js
+++ b/data/webkit/e-undo-redo.js
@@ -498,23 +498,13 @@ EvoUndoRedo.applyRecord = function(record, isUndo, withSelection)
records = record.records;
if (records && records.length) {
- if (isUndo) {
- for (ii = records.length - 1; ii >= 0; ii--) {
- EvoUndoRedo.applyRecord(records[ii], isUndo, false);
- }
- } else {
- for (ii = 0; ii < records.length; ii++) {
- EvoUndoRedo.applyRecord(records[ii], isUndo, false);
- }
+ for (ii = 0; ii < records.length; ii++) {
+ EvoUndoRedo.applyRecord(records[isUndo ? (records.length - ii - 1) : ii],
isUndo, false);
}
}
if (withSelection) {
- if (isUndo) {
- EvoSelection.Restore(document, record.selectionBefore);
- } else {
- EvoSelection.Restore(document, record.selectionAfter);
- }
+ EvoSelection.Restore(document, isUndo ? record.selectionBefore :
record.selectionAfter);
}
return;
@@ -536,67 +526,18 @@ EvoUndoRedo.applyRecord = function(record, isUndo, withSelection)
} else if (kind == EvoUndoRedo.RECORD_KIND_CUSTOM && record.apply != null) {
record.apply(record, isUndo);
} else {
- var commonParent, first, last, ii;
+ var commonParent;
commonParent = EvoSelection.FindElementByPath(document.body, record.path);
if (!commonParent) {
throw "EvoUndoRedo::applyRecord: Cannot find parent at path " + record.path;
}
- first = record.firstChildIndex;
-
- if (first == -1) {
- if (isUndo) {
- commonParent.innerHTML = record.htmlBefore;
- } else {
- commonParent.innerHTML = record.htmlAfter;
- }
- } else {
- // it can equal to the children.length, when the node had been removed
- if (first < 0 || first > commonParent.children.length) {
- throw "EvoUndoRedo::applyRecord: firstChildIndex (" + first + ") out
of bounds (" + commonParent.children.length + ")";
- }
-
- last = commonParent.children.length - record.restChildrenCount;
- if (last < 0 || last < first) {
- throw "EvoUndoRedo::applyRecord: restChildrenCount (" +
record.restChildrenCount + ") out of bounds (length:" +
- commonParent.children.length + " first:" + first + " last:" +
last + ")";
- }
-
- for (ii = last - 1; ii >= first; ii--) {
- if (ii >= 0 && ii < commonParent.children.length) {
- commonParent.removeChild(commonParent.children.item(ii));
- }
- }
-
- var tmpNode = document.createElement("evo-tmp");
-
- if (isUndo) {
- tmpNode.innerHTML = record.htmlBefore;
- } else {
- tmpNode.innerHTML = record.htmlAfter;
- }
-
- if (first < commonParent.children.length) {
- first = commonParent.children.item(first);
-
- while(tmpNode.firstElementChild) {
- commonParent.insertBefore(tmpNode.firstElementChild, first);
- }
- } else {
- while(tmpNode.children.length) {
- commonParent.appendChild(tmpNode.children.item(0));
- }
- }
- }
+ EvoUndoRedo.RestoreChildren(record, commonParent, isUndo);
}
if (withSelection) {
- if (isUndo) {
- EvoSelection.Restore(document, record.selectionBefore);
- } else {
- EvoSelection.Restore(document, record.selectionAfter);
- }
+ EvoSelection.Restore(document, isUndo ? record.selectionBefore :
record.selectionAfter);
}
} finally {
EvoUndoRedo.Enable();
@@ -647,6 +588,7 @@ EvoUndoRedo.StopRecord = function(kind, opType)
var record = EvoUndoRedo.ongoingRecordings[EvoUndoRedo.ongoingRecordings.length - 1];
+ // Events can overlap sometimes, like when doing drag&drop inside web view
if (record.kind != kind || record.opType != opType) {
var ii;
@@ -688,7 +630,7 @@ EvoUndoRedo.StopRecord = function(kind, opType)
if (kind == EvoUndoRedo.RECORD_KIND_DOCUMENT) {
record.htmlAfter = document.documentElement.innerHTML;
} else if (record.htmlBefore != window.undefined) {
- var commonParent, first, last, ii, html = "";
+ var commonParent;
commonParent = EvoSelection.FindElementByPath(document.body, record.path);
@@ -696,39 +638,16 @@ EvoUndoRedo.StopRecord = function(kind, opType)
throw "EvoUndoRedo.StopRecord:: Failed to stop '" + opType + "', cannot find common
parent";
}
- first = record.firstChildIndex;
-
- if (first == -1) {
- html = commonParent.innerHTML;
- } else {
- // it can equal to the children.length, when the node had been removed
- if (first < 0 || first > commonParent.children.length) {
- throw "EvoUndoRedo::StopRecord: firstChildIndex (" + first + ") out of bounds
(" + commonParent.children.length + ")";
- }
-
- last = commonParent.children.length - record.restChildrenCount;
- if (last < 0 || last < first) {
- throw "EvoUndoRedo::StopRecord: restChildrenCount (" +
record.restChildrenCount + ") out of bounds (length:" +
- commonParent.children.length + " first:" + first + " last:" + last +
")";
- }
-
- for (ii = first; ii < last; ii++) {
- if (ii >= 0 && ii < commonParent.children.length) {
- html += commonParent.children.item(ii).outerHTML;
- }
- }
- }
+ EvoUndoRedo.BackupChildrenAfter(record, commonParent);
// some formatting commands do not change HTML structure immediately, thus ignore those
- if (kind == EvoUndoRedo.RECORD_KIND_EVENT && record.htmlBefore == html) {
+ if (kind == EvoUndoRedo.RECORD_KIND_EVENT && record.htmlBefore == record.htmlAfter) {
if (!EvoUndoRedo.ongoingRecordings.length && record.opType != "insertText") {
EvoUndoRedo.stack.maybeMergeInsertText(false);
}
return false;
}
-
- record.htmlAfter = html;
}
record.selectionAfter = EvoSelection.Store(document);
@@ -824,4 +743,136 @@ EvoUndoRedo.GroupTopRecords = function(nRecords, opType)
}
}
+/* Backs up all the children elements between firstChildIndex and lastChildIndex inclusive,
+ saving their HTML content into record.htmlBefore; it stores only element children,
+ not text or other nodes. Use also EvoUndoRedo.BackupChildrenAfter() to save all data
+ needed by EvoUndoRedo.RestoreChildren(), which is used to restore saved data.
+ The firstChildIndex can be -1, to back up parent's innerHTML.
+*/
+EvoUndoRedo.BackupChildrenBefore = function(record, parent, firstChildIndex, lastChildIndex)
+{
+ record.firstChildIndex = firstChildIndex;
+
+ if (firstChildIndex == -1) {
+ record.htmlBefore = parent.innerHTML;
+ return;
+ }
+
+ record.htmlBefore = "";
+
+ var ii;
+
+ for (ii = firstChildIndex; ii < parent.children.length; ii++) {
+ record.htmlBefore += parent.children[ii].outerHTML;
+
+ if (ii == lastChildIndex) {
+ ii++;
+ break;
+ }
+ }
+
+ record.restChildrenCount = parent.children.length - ii;
+}
+
+EvoUndoRedo.BackupChildrenAfter = function(record, parent)
+{
+ if (record.firstChildIndex == undefined)
+ throw "EvoUndoRedo.BackupChildrenAfter: 'record' doesn't contain 'firstChildIndex' property";
+ if (record.firstChildIndex != -1 && record.restChildrenCount == undefined)
+ throw "EvoUndoRedo.BackupChildrenAfter: 'record' doesn't contain 'restChildrenCount'
property";
+ if (record.htmlBefore == undefined)
+ throw "EvoUndoRedo.BackupChildrenAfter: 'record' doesn't contain 'htmlBefore' property";
+
+ if (record.firstChildIndex == -1) {
+ record.htmlAfter = parent.innerHTML;
+ return;
+ }
+
+ record.htmlAfter = "";
+
+ var ii, first, last;
+
+ first = record.firstChildIndex;
+
+ // it can equal to the children.length, when the node had been removed
+ if (first < 0 || first > parent.children.length) {
+ throw "EvoUndoRedo.BackupChildrenAfter: firstChildIndex (" + first + ") out of bounds (" +
parent.children.length + ")";
+ }
+
+ last = parent.children.length - record.restChildrenCount;
+ if (last < 0 || last < first) {
+ throw "EvoUndoRedo::BackupChildrenAfter: restChildrenCount (" + record.restChildrenCount + ")
out of bounds (length:" +
+ parent.children.length + " first:" + first + " last:" + last + ")";
+ }
+
+ for (ii = first; ii < last; ii++) {
+ if (ii >= 0 && ii < parent.children.length) {
+ record.htmlAfter += parent.children[ii].outerHTML;
+ }
+ }
+}
+
+// restores content of 'parent' based on the information saved by EvoUndoRedo.BackupChildrenBefore()
+// and EvoUndoRedo.BackupChildrenAfter()
+EvoUndoRedo.RestoreChildren = function(record, parent, isUndo)
+{
+ var first, last, ii;
+
+ if (record.firstChildIndex == undefined)
+ throw "EvoUndoRedo.RestoreChildren: 'record' doesn't contain 'firstChildIndex' property";
+ if (record.firstChildIndex != -1 && record.restChildrenCount == undefined)
+ throw "EvoUndoRedo.RestoreChildren: 'record' doesn't contain 'restChildrenCount' property";
+ if (record.htmlBefore == undefined)
+ throw "EvoUndoRedo.RestoreChildren: 'record' doesn't contain 'htmlBefore' property";
+ if (record.htmlAfter == undefined)
+ throw "EvoUndoRedo.RestoreChildren: 'record' doesn't contain 'htmlAfter' property";
+
+ first = record.firstChildIndex;
+
+ if (first == -1) {
+ if (isUndo) {
+ parent.innerHTML = record.htmlBefore;
+ } else {
+ parent.innerHTML = record.htmlAfter;
+ }
+ } else {
+ // it can equal to the children.length, when the node had been removed
+ if (first < 0 || first > parent.children.length) {
+ throw "EvoUndoRedo::RestoreChildren: firstChildIndex (" + first + ") out of bounds ("
+ parent.children.length + ")";
+ }
+
+ last = parent.children.length - record.restChildrenCount;
+ if (last < 0 || last < first) {
+ throw "EvoUndoRedo::RestoreChildren: restChildrenCount (" + record.restChildrenCount
+ ") out of bounds (length:" +
+ parent.children.length + " first:" + first + " last:" + last + ")";
+ }
+
+ for (ii = last - 1; ii >= first; ii--) {
+ if (ii >= 0 && ii < parent.children.length) {
+ parent.removeChild(parent.children[ii]);
+ }
+ }
+
+ var tmpNode = document.createElement("evo-tmp");
+
+ if (isUndo) {
+ tmpNode.innerHTML = record.htmlBefore;
+ } else {
+ tmpNode.innerHTML = record.htmlAfter;
+ }
+
+ if (first < parent.children.length) {
+ first = parent.children[first];
+
+ while(tmpNode.firstElementChild) {
+ parent.insertBefore(tmpNode.firstElementChild, first);
+ }
+ } else {
+ while(tmpNode.firstElementChild) {
+ parent.appendChild(tmpNode.firstElementChild);
+ }
+ }
+ }
+}
+
EvoUndoRedo.Attach();
diff --git a/src/e-util/test-html-editor-units-utils.c b/src/e-util/test-html-editor-units-utils.c
index 609cfd0a56..03eae0de20 100644
--- a/src/e-util/test-html-editor-units-utils.c
+++ b/src/e-util/test-html-editor-units-utils.c
@@ -685,8 +685,8 @@ test_utils_html_equal (TestFixture *fixture,
" var elem1, elem2;\n"
" elem1 = document.createElement(\"testHtmlEqual\");\n"
" elem2 = document.createElement(\"testHtmlEqual\");\n"
- " elem1.innerHTML = html1.replace(\" \", \" \").replace(\" \", \" \");\n"
- " elem2.innerHTML = html2.replace(\" \", \" \").replace(\" \", \" \");\n"
+ " elem1.innerHTML = html1.replace(/ /g, \" \").replace(/ /g, \" \");\n"
+ " elem2.innerHTML = html2.replace(/ /g, \" \").replace(/ /g, \" \");\n"
" elem1.normalize();\n"
" elem2.normalize();\n"
" return elem1.isEqualNode(elem2);\n"
diff --git a/src/e-util/test-html-editor-units.c b/src/e-util/test-html-editor-units.c
index 41e4bb793b..734be71187 100644
--- a/src/e-util/test-html-editor-units.c
+++ b/src/e-util/test-html-editor-units.c
@@ -193,13 +193,14 @@ test_justify_selection (TestFixture *fixture)
"seq:d\n"
"action:justify-left\n",
HTML_PREFIX
- "<div style=\"text-align: center\">center</div>"
- "<div style=\"text-align: right\">right</div>"
+ "<div style=\"text-align: center;\">center</div>"
+ "<div style=\"text-align: right;\">right</div>"
"<div>left</div><div><br></div>"
HTML_SUFFIX,
" center\n"
" right\n"
- "left\n"))
+ "left\n"
+ "\n"))
g_test_fail ();
}
@@ -215,13 +216,14 @@ test_justify_typed (TestFixture *fixture)
"action:justify-left\n"
"type:left\\n\n",
HTML_PREFIX
- "<div style=\"text-align: center\">center</div>"
- "<div style=\"text-align: right\">right</div>"
+ "<div style=\"text-align: center;\">center</div>"
+ "<div style=\"text-align: right;\">right</div>"
"<div>left</div><div><br></div>"
HTML_SUFFIX,
" center\n"
" right\n"
- "left\n"))
+ "left\n"
+ "\n"))
g_test_fail ();
}
@@ -245,16 +247,16 @@ test_indent_selection (TestFixture *fixture)
"action:unindent\n",
HTML_PREFIX
"<div>level 0</div>"
- "<div style=\"margin-left: 3ch;\">"
- "<div>level 1</div>"
- "<div style=\"margin-left: 3ch;\"><div>level 2</div></div>"
- "<div>level 1</div>"
- "</div><div><br></div>"
+ "<div style=\"margin-left: 3ch;\">level 1</div>"
+ "<div style=\"margin-left: 6ch;\">level 2</div>"
+ "<div style=\"margin-left: 3ch;\">level 1</div>"
+ "<div><br></div>"
HTML_SUFFIX,
"level 0\n"
" level 1\n"
" level 2\n"
- " level 1\n"))
+ " level 1\n"
+ "\n"))
g_test_fail ();
}
@@ -273,16 +275,16 @@ test_indent_typed (TestFixture *fixture)
"action:unindent\n",
HTML_PREFIX
"<div>level 0</div>"
- "<div style=\"margin-left: 3ch;\">"
- "<div>level 1</div>"
- "<div style=\"margin-left: 3ch;\"><div>level 2</div></div>"
- "<div>level 1</div>"
- "</div><div><br></div>"
+ "<div style=\"margin-left: 3ch;\">level 1</div>"
+ "<div style=\"margin-left: 6ch;\">level 2</div>"
+ "<div style=\"margin-left: 3ch;\">level 1</div>"
+ "<div><br></div>"
HTML_SUFFIX,
"level 0\n"
" level 1\n"
" level 2\n"
- " level 1\n"))
+ " level 1\n"
+ "\n"))
g_test_fail ();
}
@@ -306,9 +308,9 @@ test_font_size_selection (TestFixture *fixture)
"action:size-plus-three\n"
"seq:rrCSrcs\n"
"action:size-plus-four\n",
- HTML_PREFIX "<div><font size=\"1\">FontM2</font> <font size=\"2\">FontM1</font> Font0 <font
size=\"4\">FontP1</font> "
+ HTML_PREFIX "<div><font size=\"1\">FontM2</font> <font size=\"2\">FontM1</font> <font
size=\"3\">Font0</font> <font size=\"4\">FontP1</font> "
"<font size=\"5\">FontP2</font> <font size=\"6\">FontP3</font> <font
size=\"7\">FontP4</font></div>" HTML_SUFFIX,
- "FontM2 FontM1 Font0 FontP1 FontP2 FontP3 FontP4"))
+ "FontM2 FontM1 Font0 FontP1 FontP2 FontP3 FontP4\n"))
g_test_fail ();
}
@@ -343,9 +345,10 @@ test_font_size_typed (TestFixture *fixture)
"action:size-plus-four\n"
"type:FontP4\n"
"action:size-plus-zero\n",
- HTML_PREFIX "<div><font size=\"1\">FontM2</font> <font size=\"2\">FontM1</font> Font0 <font
size=\"4\">FontP1</font> "
- "<font size=\"5\">FontP2</font> <font size=\"6\">FontP3</font> <font
size=\"7\">FontP4</font><br></div>" HTML_SUFFIX,
- "FontM2 FontM1 Font0 FontP1 FontP2 FontP3 FontP4"))
+ HTML_PREFIX "<div><font size=\"1\">FontM2</font><font size=\"3\"> </font><font
size=\"2\">FontM1</font><font size=\"3\"> Font0 </font>"
+ "<font size=\"4\">FontP1</font><font size=\"3\"> </font><font size=\"5\">FontP2</font><font
size=\"3\"> </font>"
+ "<font size=\"6\">FontP3</font><font size=\"3\"> </font><font size=\"7\">FontP4</font></div>"
HTML_SUFFIX,
+ "FontM2 FontM1 Font0 FontP1 FontP2 FontP3 FontP4\n"))
g_test_fail ();
}
@@ -405,7 +408,7 @@ test_font_color_selection (TestFixture *fixture)
if (!test_utils_run_simple_test (fixture, "",
HTML_PREFIX "<div>default <font color=\"#ff0000\">red</font> <font
color=\"#00ff00\">green</font> "
"<font color=\"#0000ff\">blue</font></div>" HTML_SUFFIX,
- "default red green blue"))
+ "default red green blue\n"))
g_test_fail ();
}
@@ -470,7 +473,7 @@ test_font_color_typed (TestFixture *fixture)
if (!test_utils_run_simple_test (fixture, "",
HTML_PREFIX "<div>default <font color=\"#ff0000\">red </font><font color=\"#00ff00\">green
</font>"
"<font color=\"#0000ff\">blue</font></div>" HTML_SUFFIX,
- "default red green blue"))
+ "default red green blue\n"))
g_test_fail ();
}
@@ -489,7 +492,7 @@ test_list_bullet_plain (TestFixture *fixture)
" * item 1\n"
" * item 2\n"
" * item 3\n"
- "text"))
+ "text\n"))
g_test_fail ();
}
@@ -517,9 +520,9 @@ test_list_bullet_html (TestFixture *fixture)
"<div>text</div>"
HTML_SUFFIX,
" * item 1\n"
- " * item 2\n"
+ " - item 2\n"
" * item 3\n"
- "text"))
+ "text\n"))
g_test_fail ();
}
@@ -531,7 +534,7 @@ test_list_bullet_change (TestFixture *fixture)
"action:style-list-bullet\n"
"action:style-list-number\n",
NULL,
- " 1. "))
+ " 1. \n"))
g_test_fail ();
}
@@ -559,7 +562,7 @@ test_list_bullet_html_from_block (TestFixture *fixture)
" * item 1\n"
" * item 2\n"
" * item 3\n"
- " * "))
+ " * \n"))
g_test_fail ();
}
@@ -589,7 +592,7 @@ test_list_alpha_html (TestFixture *fixture)
" A. item 1\n"
" A. item 2\n"
" B. item 3\n"
- "text"))
+ "text\n"))
g_test_fail ();
}
@@ -610,7 +613,7 @@ test_list_alpha_plain (TestFixture *fixture)
" A. item 1\n"
" A. item 2\n"
" B. item 3\n"
- "text"))
+ "text\n"))
g_test_fail ();
}
@@ -643,24 +646,24 @@ test_list_roman_html (TestFixture *fixture)
"<li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li>"
"<li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li>"
"</ol>" HTML_SUFFIX,
- " I. 1\n"
- " II. 2\n"
- " III. 3\n"
- " IV. 4\n"
- " V. 5\n"
- " VI. 6\n"
- " VII. 7\n"
- "VIII. 8\n"
- " IX. 9\n"
- " X. 10\n"
- " XI. 11\n"
- " XII. 12\n"
- "XIII. 13\n"
- " XIV. 14\n"
- " XV. 15\n"
- " XVI. 16\n"
- "XVII. 17\n"
- "XVIII. 18"))
+ " I. 1\n"
+ " II. 2\n"
+ " III. 3\n"
+ " IV. 4\n"
+ " V. 5\n"
+ " VI. 6\n"
+ " VII. 7\n"
+ " VIII. 8\n"
+ " IX. 9\n"
+ " X. 10\n"
+ " XI. 11\n"
+ " XII. 12\n"
+ " XIII. 13\n"
+ " XIV. 14\n"
+ " XV. 15\n"
+ " XVI. 16\n"
+ " XVII. 17\n"
+ "XVIII. 18\n"))
g_test_fail ();
}
@@ -689,24 +692,24 @@ test_list_roman_plain (TestFixture *fixture)
"type:17\\n\n"
"type:18\n",
NULL,
- " I. 1\n"
- " II. 2\n"
- " III. 3\n"
- " IV. 4\n"
- " V. 5\n"
- " VI. 6\n"
- " VII. 7\n"
- "VIII. 8\n"
- " IX. 9\n"
- " X. 10\n"
- " XI. 11\n"
- " XII. 12\n"
- "XIII. 13\n"
- " XIV. 14\n"
- " XV. 15\n"
- " XVI. 16\n"
- "XVII. 17\n"
- "XVIII. 18"))
+ " I. 1\n"
+ " II. 2\n"
+ " III. 3\n"
+ " IV. 4\n"
+ " V. 5\n"
+ " VI. 6\n"
+ " VII. 7\n"
+ " VIII. 8\n"
+ " IX. 9\n"
+ " X. 10\n"
+ " XI. 11\n"
+ " XII. 12\n"
+ " XIII. 13\n"
+ " XIV. 14\n"
+ " XV. 15\n"
+ " XVI. 16\n"
+ " XVII. 17\n"
+ "XVIII. 18\n"))
g_test_fail ();
}
@@ -737,7 +740,7 @@ test_list_multi_html (TestFixture *fixture)
" * item 2\n"
" I. item 3\n"
" II. item 4\n"
- " III. "))
+ " III. \n"))
g_test_fail ();
}
@@ -758,7 +761,7 @@ test_list_multi_plain (TestFixture *fixture)
" * item 2\n"
" I. item 3\n"
" II. item 4\n"
- " III. "))
+ " III. \n"))
g_test_fail ();
}
@@ -789,7 +792,7 @@ test_list_multi_change_html (TestFixture *fixture)
" 2. item 2\n"
" 3. item 3\n"
" 4. item 4\n"
- " 5. "))
+ " 5. \n"))
g_test_fail ();
}
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 1a50733a84..4f9c5a4bb1 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -63,7 +63,9 @@ enum {
PROP_STRIKETHROUGH,
PROP_SUBSCRIPT,
PROP_SUPERSCRIPT,
- PROP_UNDERLINE
+ PROP_UNDERLINE,
+
+ PROP_NORMAL_PARAGRAPH_WIDTH
};
struct _EWebKitEditorPrivate {
@@ -73,7 +75,6 @@ struct _EWebKitEditorPrivate {
GCancellable *cancellable;
EWebExtensionContainer *container;
GDBusProxy *web_extension_proxy;
- guint web_extension_user_changed_default_colors_cb_id;
gboolean html_mode;
gboolean changed;
@@ -110,6 +111,7 @@ struct _EWebKitEditorPrivate {
gchar *body_font_name;
guint font_size;
+ gint normal_paragraph_width;
EContentEditorBlockFormat block_format;
EContentEditorAlignment alignment;
@@ -1056,7 +1058,7 @@ webkit_editor_update_styles (EContentEditor *editor)
" border-collapse: collapse;\n"
" width: %dch;\n"
"}\n",
- g_settings_get_int (wk_editor->priv->mail_settings, "composer-word-wrap-length"));
+ wk_editor->priv->normal_paragraph_width);
g_string_append (
stylesheet,
@@ -1085,7 +1087,7 @@ webkit_editor_update_styles (EContentEditor *editor)
stylesheet,
"body[data-evo-plain-text] ul > li::before "
"{\n"
- " content: \"*"UNICODE_NBSP"\";\n"
+ " content: \"*" UNICODE_NBSP "\";\n"
"}\n");
g_string_append_printf (
@@ -1123,27 +1125,6 @@ webkit_editor_update_styles (EContentEditor *editor)
" -webkit-padding-start: %dch; \n"
"}\n", SPACES_PER_LIST_LEVEL);
- g_string_append (
- stylesheet,
- ".-x-evo-align-left "
- "{\n"
- " text-align: left; \n"
- "}\n");
-
- g_string_append (
- stylesheet,
- ".-x-evo-align-center "
- "{\n"
- " text-align: center; \n"
- "}\n");
-
- g_string_append (
- stylesheet,
- ".-x-evo-align-right "
- "{\n"
- " text-align: right; \n"
- "}\n");
-
g_string_append (
stylesheet,
"ol,ul "
@@ -2192,7 +2173,7 @@ webkit_editor_selection_indent (EContentEditor *editor)
wk_editor = E_WEBKIT_EDITOR (editor);
e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
- "EvoEditor.Indent(+1);");
+ "EvoEditor.Indent(true);");
}
static void
@@ -2203,7 +2184,7 @@ webkit_editor_selection_unindent (EContentEditor *editor)
wk_editor = E_WEBKIT_EDITOR (editor);
e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
- "EvoEditor.Indent(-1);");
+ "EvoEditor.Indent(false);");
}
static void
@@ -5139,6 +5120,31 @@ webkit_editor_process_uri_request_cb (WebKitURISchemeRequest *request,
webkit_editor_uri_request_done_cb, g_object_ref (request));
}
+static void
+webkit_editor_set_normal_paragraph_width (EWebKitEditor *wk_editor,
+ gint value)
+{
+ g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+
+ if (wk_editor->priv->normal_paragraph_width != value) {
+ wk_editor->priv->normal_paragraph_width = value;
+
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+ "EvoEditor.SetNormalParagraphWidth(%d);",
+ value);
+
+ g_object_notify (G_OBJECT (wk_editor), "normal-paragraph-width");
+ }
+}
+
+static gint
+webkit_editor_get_normal_paragraph_width (EWebKitEditor *wk_editor)
+{
+ g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), -1);
+
+ return wk_editor->priv->normal_paragraph_width;
+}
+
static void
e_webkit_editor_initialize_web_extensions_cb (WebKitWebContext *web_context,
gpointer user_data)
@@ -5160,6 +5166,7 @@ webkit_editor_constructed (GObject *object)
WebKitSettings *web_settings;
WebKitWebView *web_view;
WebKitUserContentManager *manager;
+ GSettings *settings;
wk_editor = E_WEBKIT_EDITOR (object);
web_view = WEBKIT_WEB_VIEW (wk_editor);
@@ -5206,6 +5213,13 @@ webkit_editor_constructed (GObject *object)
webkit_settings_set_allow_file_access_from_file_urls (web_settings, TRUE);
webkit_settings_set_enable_developer_extras (web_settings, e_util_get_webkit_developer_mode_enabled
());
+ settings = e_util_ref_settings ("org.gnome.evolution.mail");
+ g_settings_bind (
+ settings, "composer-word-wrap-length",
+ wk_editor, "normal-paragraph-width",
+ G_SETTINGS_BIND_GET);
+ g_object_unref (settings);
+
e_webkit_editor_load_data (wk_editor, "");
}
@@ -5386,6 +5400,12 @@ webkit_editor_set_property (GObject *object,
g_value_get_boolean (value));
return;
+ case PROP_NORMAL_PARAGRAPH_WIDTH:
+ webkit_editor_set_normal_paragraph_width (
+ E_WEBKIT_EDITOR (object),
+ g_value_get_int (value));
+ return;
+
case PROP_ALIGNMENT:
webkit_editor_set_alignment (
E_WEBKIT_EDITOR (object),
@@ -5559,6 +5579,11 @@ webkit_editor_get_property (GObject *object,
E_WEBKIT_EDITOR (object)));
return;
+ case PROP_NORMAL_PARAGRAPH_WIDTH:
+ g_value_set_int (value,
+ webkit_editor_get_normal_paragraph_width (E_WEBKIT_EDITOR (object)));
+ return;
+
case PROP_ALIGNMENT:
g_value_set_enum (
value,
@@ -6417,6 +6442,20 @@ e_webkit_editor_class_init (EWebKitEditorClass *class)
object_class, PROP_LAST_ERROR, "last-error");
g_object_class_override_property (
object_class, PROP_SPELL_CHECKER, "spell-checker");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_NORMAL_PARAGRAPH_WIDTH,
+ g_param_spec_int (
+ "normal-paragraph-width",
+ NULL,
+ NULL,
+ G_MININT32,
+ G_MAXINT32,
+ 71, /* Should be the same as e-editor.js:EvoEditor.NORMAL_PARAGRAPH_WIDTH */
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -6539,8 +6578,7 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
wk_editor->priv->start_bottom = E_THREE_STATE_INCONSISTENT;
wk_editor->priv->top_signature = E_THREE_STATE_INCONSISTENT;
-
- wk_editor->priv->web_extension_user_changed_default_colors_cb_id = 0;
+ wk_editor->priv->normal_paragraph_width = 71; /* Should be the same as
e-editor.js:EvoEditor.NORMAL_PARAGRAPH_WIDTH */
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]