Work around rendering quote controller buttons, enable expanding quotes.

* ui/conversation-web-view.js (ConversationPageState): Add
  ::updatePreferredHeight method to waitch for and update the web view's
  preferred height when it changes.
  (ConversationPageState::createControllableQuotes): Create quote
  controllers using the DOM so we can easily attach click handlers to
  it. Attach handlers to toggle the hide class and updated the preferred
  height.

* ui/client-web-view.js (PageState): Add ::getPreferredHeight method, use
  that to determine the preferred height of the page.

* ui/conversation-web-view.css: Import GTK+4 Adwaita button CSS to work
  around WebKitGTK+ Bug 166648. Tweak quote style a bit.
This commit is contained in:
Michael James Gratton 2017-01-04 01:10:38 +11:00
parent 5e114cfcac
commit 8864e2b7a7
3 changed files with 90 additions and 23 deletions

View file

@ -25,6 +25,9 @@ PageState.prototype = {
}
}, 50);
},
getPreferredHeight: function() {
return window.document.documentElement.offsetHeight;
},
loaded: function() {
this.is_loaded = true;
},
@ -42,7 +45,7 @@ PageState.prototype = {
window.webkit.messageHandlers.remoteImageLoadBlocked.postMessage(null);
},
preferredHeightChanged: function() {
var height = window.document.documentElement.offsetHeight;
let height = this.getPreferredHeight();
if (height > 0) {
window.webkit.messageHandlers.preferredHeightChanged.postMessage(
height

View file

@ -55,7 +55,7 @@ hr {
}
blockquote {
margin: 0.5em 16px;
margin: 0.3em 16px;
border: 0;
border-left: 3px #aaa solid;
padding: 0 8px;
@ -116,7 +116,7 @@ pre {
}
.geary-quote-container.geary-controllable.geary-hide > .geary-quote {
/* Use a fraction value to cut the last visible line off half way. */
max-height: 7.75em;
max-height: calc(6em - 8px);
}
.geary-quote-container.geary-controllable > .geary-quote > blockquote {
@ -130,24 +130,51 @@ pre {
display: none;
left: 0;
right: 0;
bottom: -8px;
bottom: -4px;
z-index: 1;
-webkit-user-select: none;
-webkit-user-drag: none;
}
.geary-quote-container > .geary-shower > input,
.geary-quote-container > .geary-hider > input {
.geary-quote-container .geary-button,
.geary-quote-container .geary-button {
display: block;
width: 100%;
height: 16px;
min-height: 0;
margin: 0;
margin-bottom: 4px;
padding: 0;
font-size: 8px; /* Absolute size in pixels for graphics */
color: #888;
font-size: 8px; /* Absolute size in pixels for graphics */
white-space: pre;
/* All futher properties below are a workaround for WK Bug 166648
* <https://bugs.webkit.org/show_bug.cgi?id=166648>. The result is
* we need to manually style these buttons outselves. */
-webkit-appearance: none;
box-sizing: border-box;
/* The following was taken from GTK+4 trunk Adwaita theme:
* gtk/theme/Adwaita/gtk-contained.css */
border: 1px solid;
border-radius: 3px;
transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
color: #2e3436;
outline-color: rgba(46, 52, 54, 0.3);
border-color: #b6b6b3;
border-bottom-color: #91918c;
background-image: linear-gradient(to bottom, #e8e8e7, #dededd 60%, #cfcfcd);
text-shadow: 0 1px rgba(255, 255, 255, 0.76923);
box-shadow: inset 0 1px rgba(255, 255, 255, 0.8); }
}
.geary-quote-container > .geary-shower:hover > input,
.geary-quote-container > .geary-hider:hover > input {
color: #000;
.geary-quote-container .geary-button:hover {
/* Likewise the properties below also workaround WK Bug 166648,
* and taken from gtk/theme/Adwaita/gtk-contained.css. */
color: #2e3436;
outline-color: rgba(46, 52, 54, 0.3);
border-color: #b6b6b3;
border-bottom-color: #91918c;
text-shadow: 0 1px rgba(255, 255, 255, 0.76923);
box-shadow: inset 0 1px white;
background-image: linear-gradient(to bottom, #f7f7f7, #e8e8e7 60%, #dededd);
}
.geary-quote-container.geary-controllable.geary-hide > .geary-hider {

View file

@ -14,6 +14,7 @@ var ConversationPageState = function() {
};
ConversationPageState.QUOTE_CONTAINER_CLASS = "geary-quote-container";
ConversationPageState.QUOTE_HIDE_CLASS = "geary-hide";
ConversationPageState.prototype = {
__proto__: PageState.prototype,
@ -39,6 +40,20 @@ ConversationPageState.prototype = {
document.documentElement.dir = "auto";
}
},
/**
* Starts looking for changes to the page's height.
*/
updatePreferredHeight: function() {
let height = this.getPreferredHeight();
let state = this;
let timeoutId = window.setInterval(function() {
let newHeight = state.getPreferredHeight();
if (height != newHeight) {
state.preferredHeightChanged();
window.clearTimeout(timeoutId);
}
}, 50);
},
/**
* Add top level blockquotes to hide/show container.
*/
@ -58,26 +73,48 @@ ConversationPageState.prototype = {
);
// Only make it controllable if the quote is tall enough
if (blockquote.offsetHeight > 60) {
if (blockquote.offsetHeight > 120) {
quoteContainer.classList.add("geary-controllable");
quoteContainer.classList.add("geary-hide");
quoteContainer.classList.add(
ConversationPageState.QUOTE_HIDE_CLASS
);
}
// New lines are preserved within blockquotes, so this
// string needs to be new-line free.
quoteContainer.innerHTML =
"<div class=\"geary-shower\">" +
"<input type=\"button\" value=\"▼ ▼ ▼\" />" +
"</div>" +
"<div class=\"geary-hider\">" +
"<input type=\"button\" value=\"▲ ▲ ▲\" />" +
"</div>";
var quoteDiv = document.createElement("DIV");
let script = this;
function newControllerButton(styleClass, text) {
let button = document.createElement("BUTTON");
button.classList.add("geary-button");
button.type = "button";
button.onclick = function() {
quoteContainer.classList.toggle(
ConversationPageState.QUOTE_HIDE_CLASS
);
script.updatePreferredHeight();
};
button.appendChild(document.createTextNode(text));
let container = document.createElement("DIV");
container.classList.add(styleClass);
container.appendChild(button);
return container;
}
quoteContainer.appendChild(newControllerButton(
"geary-shower", "▼ ▼ ▼"
));
quoteContainer.appendChild(newControllerButton(
"geary-hider", "▲ ▲ ▲"
));
let quoteDiv = document.createElement("DIV");
quoteDiv.classList.add("geary-quote");
quoteDiv.appendChild(blockquote);
quoteContainer.appendChild(quoteDiv);
parent.insertBefore(quoteContainer, nextSibling);
this.updatePreferredHeight();
}
}
},