Commit 0160cd00 authored by Michael Gratton's avatar Michael Gratton 🤞

Merge branch 'wip/geary-is-descendant-of' into 'master'

Fix whitespace not being preserved sometimes when select-quote-relying to a plain text message

See merge request !94
parents 44d871f6 0f554d23
Pipeline #55480 passed with stages
in 9 minutes and 54 seconds
......@@ -17,6 +17,10 @@ class ConversationPageStateTest : ClientWebViewTestCase<ConversationWebView> {
add_test("is_deceptive_text_deceptive_href", is_deceptive_text_deceptive_href);
add_test("is_deceptive_text_non_matching_subdomain", is_deceptive_text_non_matching_subdomain);
add_test("is_deceptive_text_different_domain", is_deceptive_text_different_domain);
add_test("is_descendant_of", is_descendant_of);
add_test("is_descendant_of_with_class", is_descendant_of_with_class);
add_test("is_descendant_of_no_match", is_descendant_of_no_match);
add_test("is_descendant_of_lax", is_descendant_of_lax);
try {
ConversationWebView.load_resources(File.new_for_path(""));
......@@ -73,6 +77,59 @@ class ConversationPageStateTest : ClientWebViewTestCase<ConversationWebView> {
ConversationWebView.DeceptiveText.DECEPTIVE_DOMAIN);
}
public void is_descendant_of() throws GLib.Error {
load_body_fixture("<blockquote><div id='test'>ohhai</div></blockquote>");
assert(
WebKitUtil.to_bool(
run_javascript("""
ConversationPageState.isDescendantOf(
document.getElementById('test'), "BLOCKQUOTE"
);
""")
)
);
}
public void is_descendant_of_with_class() throws GLib.Error {
load_body_fixture("<blockquote class='test-class'><div id='test'>ohhai</div></blockquote>");
assert(
WebKitUtil.to_bool(
run_javascript("""
ConversationPageState.isDescendantOf(
document.getElementById('test'), "BLOCKQUOTE", "test-class"
);
""")
)
);
}
public void is_descendant_of_no_match() throws GLib.Error {
load_body_fixture("<blockquote class='test-class'><div id='test'>ohhai</div></blockquote>");
assert(
WebKitUtil.to_bool(
run_javascript("""
ConversationPageState.isDescendantOf(
document.getElementById('test'), "DIV"
);
""")
)
);
}
public void is_descendant_of_lax() throws GLib.Error {
load_body_fixture("<blockquote class='test-class'><div id='test'>ohhai</div></blockquote>");
assert(
WebKitUtil.to_bool(
run_javascript("""
ConversationPageState.isDescendantOf(
document.getElementById('test'), "DIV", null, false
);
""")
)
);
}
protected override ConversationWebView set_up_test_view() {
return new ConversationWebView(this.config);
}
......
......@@ -82,7 +82,7 @@ ConversationPageState.prototype = {
// Only insert into a quote container if the element is a
// top level blockquote
if (!ConversationPageState.isDescendantOf(blockquote, "blockquote")) {
if (!ConversationPageState.isDescendantOf(blockquote, "BLOCKQUOTE")) {
let quoteHeight = blockquote.offsetHeight;
// Only make the quote it controllable if it is tall enough
......@@ -171,7 +171,7 @@ ConversationPageState.prototype = {
let div = possibleSigs.item(i);
let innerHTML = div.innerHTML;
if ((sigRegex.test(innerHTML) || alternateSigRegex.test(innerHTML)) &&
!ConversationPageState.isDescendantOf(div, "blockquote")) {
!ConversationPageState.isDescendantOf(div, "BLOCKQUOTE")) {
break;
}
}
......@@ -201,12 +201,15 @@ ConversationPageState.prototype = {
ancestor = ancestor.parentNode;
}
// If the selection is part of a plain text message,
// we have to stick it in an appropriately styled div,
// so that new lines are preserved.
// If the selection is part of a plain text message, we
// have to stick it in an appropriately styled div, so
// that new lines are preserved. Do a non-strict ancestor
// check since the common ancestor may well be the plain
// text DIV itself
let dummy = document.createElement("DIV");
let includeDummy = false;
if (ConversationPageState.isDescendantOf(ancestor, "div", "plaintext")) {
if (ConversationPageState.isDescendantOf(
ancestor, "DIV", "plaintext", false)) {
dummy.classList.add("plaintext");
dummy.setAttribute("style", "white-space: pre-wrap;");
includeDummy = true;
......@@ -324,17 +327,21 @@ ConversationPageState.isDeceptiveText = function(text, href) {
/**
* See if this element has an ancestor with the given tag and class.
*
* ancestorTag must be all lowercase.
* The value of ancestorTag must be all uppercase.
*
* If ancestorClass is null, no class checking is done.
* If strict is is true, the given node will not be checked.
*/
ConversationPageState.isDescendantOf = function(node, ancestorTag, ancestorClass = null) {
let ancestor = node.parentNode;
ConversationPageState.isDescendantOf = function(node,
ancestorTag,
ancestorClass = null,
strict = true) {
let ancestor = strict ? node.parentNode : node;
while (ancestor != null) {
if (ancestor.tagName.toLowerCase() == ancestorTag) {
if (!ancestorClass || ancestor.classList.contains(ancestorClass)) {
return true;
}
if (ancestor.nodeName.toUpperCase() == ancestorTag &&
(ancestorClass == null ||
ancestor.classList.contains(ancestorClass))) {
return true;
}
ancestor = ancestor.parentNode;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment