Prefix CSS classes in message HTML to avoid collisions with HTML messages.
* ui/conversation-web-view.css: Prefix the names of base Geary-internal elements with "geary_" to reduce the odds of them colliding with class names in HTML messages. Chase the name changes in classes that generate them. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage): Use constants for class names and WebKit.DOMElement::class_list to add/remove them.
This commit is contained in:
parent
b5e7c27c58
commit
5ea4b0a051
3 changed files with 64 additions and 51 deletions
|
|
@ -251,7 +251,7 @@ public class ConversationFindBar : Gtk.Layout {
|
||||||
|
|
||||||
private void switch_to_search_selection_color() {
|
private void switch_to_search_selection_color() {
|
||||||
try {
|
try {
|
||||||
web_view.get_dom_document().get_body().get_class_list().add("search_coloring");
|
web_view.get_dom_document().get_body().get_class_list().add("geary_search_coloring");
|
||||||
} catch (Error error) {
|
} catch (Error error) {
|
||||||
warning("Error setting body class for search selection coloring: %s", error.message);
|
warning("Error setting body class for search selection coloring: %s", error.message);
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +259,7 @@ public class ConversationFindBar : Gtk.Layout {
|
||||||
|
|
||||||
private void switch_to_usual_selection_color() {
|
private void switch_to_usual_selection_color() {
|
||||||
try {
|
try {
|
||||||
web_view.get_dom_document().get_body().get_class_list().remove("search_coloring");
|
web_view.get_dom_document().get_body().get_class_list().remove("geary_search_coloring");
|
||||||
} catch (Error error) {
|
} catch (Error error) {
|
||||||
warning("Error setting body class for search selection coloring: %s", error.message);
|
warning("Error setting body class for search selection coloring: %s", error.message);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,12 @@ public class ConversationMessage : Gtk.Box {
|
||||||
"image/x-xbitmap",
|
"image/x-xbitmap",
|
||||||
"image/x-xbm"
|
"image/x-xbm"
|
||||||
};
|
};
|
||||||
private const string REPLACED_IMAGE_CLASS = "replaced_inline_image";
|
private const string QUOTE_CONTAINER_CLASS = "geary_quote_container";
|
||||||
private const string DATA_IMAGE_CLASS = "data_inline_image";
|
private const string QUOTE_CONTROLLABLE_CLASS = "controllable";
|
||||||
|
private const string QUOTE_HIDE_CLASS = "hide";
|
||||||
|
private const string SIGNATURE_CONTAINER_CLASS = "geary_signature";
|
||||||
|
private const string REPLACED_IMAGE_CLASS = "geary_replaced_inline_image";
|
||||||
|
private const string DATA_IMAGE_CLASS = "geary_data_inline_image";
|
||||||
private const int MAX_INLINE_IMAGE_MAJOR_DIM = 1024;
|
private const int MAX_INLINE_IMAGE_MAJOR_DIM = 1024;
|
||||||
private const float QUOTE_SIZE_THRESHOLD = 2.0f;
|
private const float QUOTE_SIZE_THRESHOLD = 2.0f;
|
||||||
|
|
||||||
|
|
@ -421,14 +425,22 @@ public class ConversationMessage : Gtk.Box {
|
||||||
error.message);
|
error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Util.DOM.bind_event(this.web_view, "html", "contextmenu",
|
Util.DOM.bind_event(
|
||||||
(Callback) on_context_menu, this);
|
this.web_view, "html", "contextmenu",
|
||||||
Util.DOM.bind_event(this.web_view, "body a", "click",
|
(Callback) on_context_menu, this
|
||||||
(Callback) on_link_clicked, this);
|
);
|
||||||
Util.DOM.bind_event(this.web_view, ".quote_container > .shower", "click",
|
Util.DOM.bind_event(
|
||||||
(Callback) on_show_quote_clicked, this);
|
this.web_view, "body a", "click",
|
||||||
Util.DOM.bind_event(this.web_view, ".quote_container > .hider", "click",
|
(Callback) on_link_clicked, this
|
||||||
(Callback) on_hide_quote_clicked, this);
|
);
|
||||||
|
Util.DOM.bind_event(
|
||||||
|
this.web_view, ".%s > .shower".printf(QUOTE_CONTAINER_CLASS),
|
||||||
|
"click",
|
||||||
|
(Callback) on_show_quote_clicked, this);
|
||||||
|
Util.DOM.bind_event(
|
||||||
|
this.web_view, ".%s > .hider".printf(QUOTE_CONTAINER_CLASS),
|
||||||
|
"click",
|
||||||
|
(Callback) on_hide_quote_clicked, this);
|
||||||
|
|
||||||
// XXX Not actually true since remote images will
|
// XXX Not actually true since remote images will
|
||||||
// still be loading.
|
// still be loading.
|
||||||
|
|
@ -500,7 +512,7 @@ public class ConversationMessage : Gtk.Box {
|
||||||
// Remove the chrome we put around quotes, leaving
|
// Remove the chrome we put around quotes, leaving
|
||||||
// only the blockquote element.
|
// only the blockquote element.
|
||||||
WebKit.DOM.NodeList quotes =
|
WebKit.DOM.NodeList quotes =
|
||||||
dummy.query_selector_all(".quote_container");
|
dummy.query_selector_all("." + QUOTE_CONTAINER_CLASS);
|
||||||
for (int i = 0; i < quotes.length; i++) {
|
for (int i = 0; i < quotes.length; i++) {
|
||||||
WebKit.DOM.Element div = (WebKit.DOM.Element) quotes.item(i);
|
WebKit.DOM.Element div = (WebKit.DOM.Element) quotes.item(i);
|
||||||
WebKit.DOM.Element blockquote = div.query_selector("blockquote");
|
WebKit.DOM.Element blockquote = div.query_selector("blockquote");
|
||||||
|
|
@ -821,10 +833,6 @@ public class ConversationMessage : Gtk.Box {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parent
|
|
||||||
// quote_container
|
|
||||||
// blockquote
|
|
||||||
// sibling
|
|
||||||
WebKit.DOM.Element quote_container = create_quote_container();
|
WebKit.DOM.Element quote_container = create_quote_container();
|
||||||
Util.DOM.select(quote_container, ".quote").append_child(blockquote_node);
|
Util.DOM.select(quote_container, ".quote").append_child(blockquote_node);
|
||||||
if (next_sibling == null) {
|
if (next_sibling == null) {
|
||||||
|
|
@ -878,7 +886,7 @@ public class ConversationMessage : Gtk.Box {
|
||||||
// and the ALT to its filename, if supplied
|
// and the ALT to its filename, if supplied
|
||||||
img.remove_attribute("src"); // Work around a WebKitGTK+ crash. Bug 764152
|
img.remove_attribute("src"); // Work around a WebKitGTK+ crash. Bug 764152
|
||||||
img.set_attribute("src", Util.DOM.assemble_data_uri(mimetype, image_content));
|
img.set_attribute("src", Util.DOM.assemble_data_uri(mimetype, image_content));
|
||||||
img.set_attribute("class", DATA_IMAGE_CLASS);
|
img.class_list.add(DATA_IMAGE_CLASS);
|
||||||
if (!Geary.String.is_empty(filename))
|
if (!Geary.String.is_empty(filename))
|
||||||
img.set_attribute("alt", filename);
|
img.set_attribute("alt", filename);
|
||||||
|
|
||||||
|
|
@ -911,12 +919,12 @@ public class ConversationMessage : Gtk.Box {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebKit.DOM.HTMLElement create_quote_container() throws Error {
|
private WebKit.DOM.HTMLElement create_quote_container() throws Error {
|
||||||
WebKit.DOM.HTMLElement quote_container = web_view.create("div");
|
WebKit.DOM.HTMLElement quote_container = web_view.create("div");
|
||||||
quote_container.set_attribute(
|
quote_container.class_list.add(QUOTE_CONTAINER_CLASS);
|
||||||
"class", "quote_container controllable hide"
|
quote_container.class_list.add(QUOTE_CONTROLLABLE_CLASS);
|
||||||
);
|
quote_container.class_list.add(QUOTE_HIDE_CLASS);
|
||||||
// New lines are preserved within blockquotes, so this string
|
// New lines are preserved within blockquotes, so this string
|
||||||
// needs to be new-line free.
|
// needs to be new-line free.
|
||||||
quote_container.set_inner_html("""<div class="shower"><input type="button" value="▼ ▼ ▼" /></div><div class="hider"><input type="button" value="▲ ▲ ▲" /></div><div class="quote"></div>""");
|
quote_container.set_inner_html("""<div class="shower"><input type="button" value="▼ ▼ ▼" /></div><div class="hider"><input type="button" value="▲ ▲ ▲" /></div><div class="quote"></div>""");
|
||||||
|
|
@ -952,7 +960,7 @@ public class ConversationMessage : Gtk.Box {
|
||||||
WebKit.DOM.Node elem = div_list.item(i) as WebKit.DOM.Node;
|
WebKit.DOM.Node elem = div_list.item(i) as WebKit.DOM.Node;
|
||||||
WebKit.DOM.Element parent = elem.get_parent_element();
|
WebKit.DOM.Element parent = elem.get_parent_element();
|
||||||
WebKit.DOM.HTMLElement signature_container = web_view.create("div");
|
WebKit.DOM.HTMLElement signature_container = web_view.create("div");
|
||||||
signature_container.set_attribute("class", "signature");
|
signature_container.class_list.add(SIGNATURE_CONTAINER_CLASS);
|
||||||
do {
|
do {
|
||||||
// Get its sibling _before_ we move it into the signature div.
|
// Get its sibling _before_ we move it into the signature div.
|
||||||
WebKit.DOM.Node? sibling = elem.get_next_sibling();
|
WebKit.DOM.Node? sibling = elem.get_next_sibling();
|
||||||
|
|
@ -963,8 +971,9 @@ public class ConversationMessage : Gtk.Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unset_controllable_quotes(WebKit.DOM.HTMLElement element) throws GLib.Error {
|
private void unset_controllable_quotes(WebKit.DOM.HTMLElement element) throws GLib.Error {
|
||||||
WebKit.DOM.NodeList quote_list =
|
WebKit.DOM.NodeList quote_list = element.query_selector_all(
|
||||||
element.query_selector_all(".quote_container.controllable");
|
".%s.%s".printf(QUOTE_CONTAINER_CLASS, QUOTE_CONTROLLABLE_CLASS)
|
||||||
|
);
|
||||||
for (int i = 0; i < quote_list.length; ++i) {
|
for (int i = 0; i < quote_list.length; ++i) {
|
||||||
WebKit.DOM.Element quote_container = quote_list.item(i) as WebKit.DOM.Element;
|
WebKit.DOM.Element quote_container = quote_list.item(i) as WebKit.DOM.Element;
|
||||||
long outer_client_height = quote_container.client_height;
|
long outer_client_height = quote_container.client_height;
|
||||||
|
|
@ -974,8 +983,8 @@ public class ConversationMessage : Gtk.Box {
|
||||||
// substantial amount hidden.
|
// substantial amount hidden.
|
||||||
if (scroll_height > 0 &&
|
if (scroll_height > 0 &&
|
||||||
scroll_height <= outer_client_height * QUOTE_SIZE_THRESHOLD) {
|
scroll_height <= outer_client_height * QUOTE_SIZE_THRESHOLD) {
|
||||||
quote_container.class_list.remove("controllable");
|
quote_container.class_list.remove(QUOTE_CONTROLLABLE_CLASS);
|
||||||
quote_container.class_list.remove("hide");
|
quote_container.class_list.remove(QUOTE_HIDE_CLASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1108,7 +1117,9 @@ public class ConversationMessage : Gtk.Box {
|
||||||
private static void on_show_quote_clicked(WebKit.DOM.Element element,
|
private static void on_show_quote_clicked(WebKit.DOM.Element element,
|
||||||
WebKit.DOM.Event event) {
|
WebKit.DOM.Event event) {
|
||||||
try {
|
try {
|
||||||
((WebKit.DOM.HTMLElement) element.parent_node).class_list.remove("hide");
|
((WebKit.DOM.HTMLElement) element.parent_node).class_list.remove(
|
||||||
|
QUOTE_HIDE_CLASS
|
||||||
|
);
|
||||||
} catch (Error error) {
|
} catch (Error error) {
|
||||||
warning("Error showing quote: %s", error.message);
|
warning("Error showing quote: %s", error.message);
|
||||||
}
|
}
|
||||||
|
|
@ -1118,7 +1129,9 @@ public class ConversationMessage : Gtk.Box {
|
||||||
WebKit.DOM.Event event,
|
WebKit.DOM.Event event,
|
||||||
ConversationMessage message) {
|
ConversationMessage message) {
|
||||||
try {
|
try {
|
||||||
((WebKit.DOM.HTMLElement) element.parent_node).class_list.add("hide");
|
((WebKit.DOM.HTMLElement) element.parent_node).class_list.add(
|
||||||
|
QUOTE_HIDE_CLASS
|
||||||
|
);
|
||||||
message.web_view.queue_resize();
|
message.web_view.queue_resize();
|
||||||
} catch (Error error) {
|
} catch (Error error) {
|
||||||
warning("Error toggling quote: %s", error.message);
|
warning("Error toggling quote: %s", error.message);
|
||||||
|
|
|
||||||
|
|
@ -66,19 +66,19 @@ pre {
|
||||||
* Message chrome style.
|
* Message chrome style.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.signature {
|
.geary_signature {
|
||||||
color: #777;
|
color: #777;
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature a,
|
.geary_signature a,
|
||||||
.quote_container a {
|
.geary_quote_container a {
|
||||||
color: #5fb2e7;
|
color: #5fb2e7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen {
|
@media screen {
|
||||||
|
|
||||||
.replaced_inline_image {
|
.geary_replaced_inline_image {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
|
|
@ -86,7 +86,7 @@ pre {
|
||||||
|
|
||||||
/* Inline collapsable quote blocks */
|
/* Inline collapsable quote blocks */
|
||||||
|
|
||||||
.quote_container {
|
.geary_quote_container {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
@ -94,11 +94,11 @@ pre {
|
||||||
color: #303030;
|
color: #303030;
|
||||||
background-color: #e8e8e8;/* recv-quoted */
|
background-color: #e8e8e8;/* recv-quoted */
|
||||||
}
|
}
|
||||||
.sent .quote_container {
|
.geary_sent .geary_quote_container {
|
||||||
background-color: #e8e8e8;/* sent-quoted */
|
background-color: #e8e8e8;/* sent-quoted */
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote_container > .quote {
|
.geary_quote_container > .quote {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|
@ -106,18 +106,18 @@ pre {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
.quote_container.controllable.hide > .quote {
|
.geary_quote_container.controllable.hide > .quote {
|
||||||
/* Use a fraction value to cut the last visible line off half way. */
|
/* Use a fraction value to cut the last visible line off half way. */
|
||||||
max-height: 7.75em;
|
max-height: 7.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote_container.controllable > .quote > blockquote {
|
.geary_quote_container.controllable > .quote > blockquote {
|
||||||
/* Add space between the quote and the hider button */
|
/* Add space between the quote and the hider button */
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote_container > .shower,
|
.geary_quote_container > .shower,
|
||||||
.quote_container > .hider {
|
.geary_quote_container > .hider {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
@ -128,30 +128,30 @@ pre {
|
||||||
-webkit-user-drag: none;
|
-webkit-user-drag: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote_container > .shower > input,
|
.geary_quote_container > .shower > input,
|
||||||
.quote_container > .hider > input {
|
.geary_quote_container > .hider > input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 8px; /* Absolute size in pixels for graphics */
|
font-size: 8px; /* Absolute size in pixels for graphics */
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
.quote_container > .shower:hover > input,
|
.geary_quote_container > .shower:hover > input,
|
||||||
.quote_container > .hider:hover > input {
|
.geary_quote_container > .hider:hover > input {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote_container.controllable.hide > .hider {
|
.geary_quote_container.controllable.hide > .hider {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.quote_container.controllable.hide > .shower,
|
.geary_quote_container.controllable.hide > .shower,
|
||||||
.quote_container.controllable > .hider {
|
.geary_quote_container.controllable > .hider {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Highlight search terms */
|
/* Highlight search terms */
|
||||||
|
|
||||||
.search_coloring *::selection {
|
.geary_search_coloring *::selection {
|
||||||
background-color: #00ddff;
|
background-color: #00ddff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,14 +161,14 @@ pre {
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#part_container {
|
#geary_part_container {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
#print_container {
|
#geary_print_container {
|
||||||
display: inline-block !important;
|
display: inline-block !important;
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
#print_container .preview {
|
#geary_print_container .preview {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue