* src/client/composer/composer-link-popover.vala: New GtkPopover subclass for creating/editing links. * src/client/composer/composer-web-view.vala (EditContext): Add is_link and link_uri properties, decode them from the message string, add decoding tests. (ComposerWebView): Add some as-yet un-implemented methods for inserting/deleting links. * src/client/composer/composer-widget.vala (ComposerWidget): Add cursor_url for storing current text cursor link, update it from the cursor_context_changed signal param, rename hover_url to pointer_url to match. Add link_activated signal to let user's open links they are adding, hook that up in the controller. Rename ::update_selection_actions to ::update_cursor_actions, since that's a little more apt now, also enable insert link action if there is a cursor_url set as well as a selection. Remove ::link_dialog, replace with ::new_link_popover, hook up the new popover's signals there as appropriate. (ComposerWidget::on_insert_link): Create and show a lin popover instead of a dialog. * ui/composer-web-view.js: Take note of whther the context node is a link and if so, also it's href. Include both when serialsing for the cursorContextChanged message. Add serialisation tests. * ui/composer-link-popover.ui: New UI for link popover.
178 lines
7.3 KiB
Vala
178 lines
7.3 KiB
Vala
/*
|
|
* Copyright 2016 Michael Gratton <mike@vee.net>
|
|
*
|
|
* This software is licensed under the GNU Lesser General Public License
|
|
* (version 2.1 or later). See the COPYING file in this distribution.
|
|
*/
|
|
|
|
public class ComposerWebViewTest : ClientWebViewTestCase<ComposerWebView> {
|
|
|
|
public ComposerWebViewTest() {
|
|
base("ComposerWebViewTest");
|
|
add_test("edit_context", edit_context);
|
|
add_test("get_html", get_html);
|
|
add_test("get_text", get_text);
|
|
add_test("get_text_with_quote", get_text_with_quote);
|
|
add_test("get_text_with_nested_quote", get_text_with_nested_quote);
|
|
add_test("get_text_with_long_line", get_text_with_long_line);
|
|
add_test("get_text_with_long_quote", get_text_with_long_quote);
|
|
add_test("get_text_with_nbsp", get_text_with_nbsp);
|
|
}
|
|
|
|
public void edit_context() {
|
|
assert(!(new ComposerWebView.EditContext("0,,,").is_link));
|
|
assert(new ComposerWebView.EditContext("1,,,").is_link);
|
|
assert(new ComposerWebView.EditContext("1,url,,").link_url == "url");
|
|
|
|
assert(new ComposerWebView.EditContext("0,,Helvetica,").font_family == "sans");
|
|
assert(new ComposerWebView.EditContext("0,,Times New Roman,").font_family == "serif");
|
|
assert(new ComposerWebView.EditContext("0,,Courier,").font_family == "monospace");
|
|
|
|
assert(new ComposerWebView.EditContext("0,,,12").font_size == 12);
|
|
}
|
|
|
|
public void get_html() {
|
|
string html = "<p>para</p>";
|
|
load_body_fixture(html);
|
|
this.test_view.get_html.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_html.end(async_result()) == html + "<br><br>");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text() {
|
|
load_body_fixture("<p>para</p>");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) == "para\n\n\n\n\n");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text_with_quote() {
|
|
load_body_fixture("<p>pre</p> <blockquote><p>quote</p></blockquote> <p>post</p>");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) ==
|
|
"pre\n\n> quote\n> \npost\n\n\n\n\n");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text_with_nested_quote() {
|
|
load_body_fixture("<p>pre</p> <blockquote><p>quote1</p> <blockquote><p>quote2</p></blockquote></blockquote> <p>post</p>");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) ==
|
|
"pre\n\n> quote1\n> \n>> quote2\n>> \npost\n\n\n\n\n");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text_with_long_line() {
|
|
load_body_fixture("""
|
|
<p>A long, long, long, long, long, long para. Well, longer than MAX_BREAKABLE_LEN
|
|
at least. Really long, long, long, long, long long, long long, long long, long.</p>
|
|
""");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) ==
|
|
"""A long, long, long, long, long, long para. Well, longer than
|
|
MAX_BREAKABLE_LEN at least. Really long, long, long, long, long long,
|
|
long long, long long, long.
|
|
|
|
|
|
|
|
|
|
""");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text_with_long_quote() {
|
|
load_body_fixture("""
|
|
<blockquote><p>A long, long, long, long, long, long line. Well, longer than MAX_BREAKABLE_LEN at least.</p></blockquote>
|
|
|
|
<p>A long, long, long, long, long, long para. Well, longer than MAX_BREAKABLE_LEN
|
|
at least. Really long, long, long, long, long long, long long, long long, long.</p>""");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) ==
|
|
"""> A long, long, long, long, long, long line. Well, longer than
|
|
> MAX_BREAKABLE_LEN at least.
|
|
>
|
|
A long, long, long, long, long, long para. Well, longer than
|
|
MAX_BREAKABLE_LEN at least. Really long, long, long, long, long long,
|
|
long long, long long, long.
|
|
|
|
|
|
|
|
|
|
""");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
public void get_text_with_nbsp() {
|
|
load_body_fixture("""On Sun, Jan 1, 2017 at 9:55 PM, Michael Gratton <mike@vee.net> wrote:<br>
|
|
<blockquote type="cite">long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long,
|
|
</blockquote><br>long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, <div style="white-space: pre;">
|
|
</div>
|
|
|
|
""");
|
|
this.test_view.get_text.begin((obj, ret) => { async_complete(ret); });
|
|
try {
|
|
assert(this.test_view.get_text.end(async_result()) ==
|
|
"""On Sun, Jan 1, 2017 at 9:55 PM, Michael Gratton <mike@vee.net> wrote:
|
|
> long, long, long, long, long, long, long, long, long, long, long,
|
|
> long, long, long, long, long, long, long, long, long, long, long,
|
|
> long, long, long, long, long, long, long, long, long, long, long,
|
|
> long, long, long, long, long, long, long, long, long, long, long,
|
|
> long, long, long, long, long,
|
|
|
|
long, long, long, long, long, long, long, long, long, long, long, long,
|
|
long, long, long, long, long, long, long, long, long, long, long, long,
|
|
long, long, long, long, long, long, long, long, long, long, long, long,
|
|
long, long, long, long, long, long, long, long, long, long, long, long,
|
|
long, long, long, long, long, long, long, long, long, long,
|
|
|
|
|
|
|
|
|
|
""");
|
|
} catch (Error err) {
|
|
print("Error: %s\n", err.message);
|
|
assert_not_reached();
|
|
}
|
|
}
|
|
|
|
protected override ComposerWebView set_up_test_view() {
|
|
try {
|
|
ComposerWebView.load_resources();
|
|
} catch (Error err) {
|
|
assert_not_reached();
|
|
}
|
|
return new ComposerWebView(this.config);
|
|
}
|
|
|
|
protected override void load_body_fixture(string? html = null) {
|
|
this.test_view.load_html(html, null, false);
|
|
while (this.test_view.is_loading) {
|
|
Gtk.main_iteration();
|
|
}
|
|
}
|
|
|
|
}
|