Return the scroll height of the HTML element since the BODY
may have margin/border/padding and we want to know
precisely how high the widget needs to be to avoid
scrolling.
Only send an updated height change when the width has changed on
receiving a JavaScript resize event to avoid getting into a feedback
loop, as was happening with email from Mastodon instances.
This default instance was causing double the number of preferred height
events, which was likely creating a race for ConversationWebView. This
might (should?) fix plain text email with quotes sometimes showing up
with a vastly incorrect height.
To ensure that a PageState is constructed properly, make ClientWebView
abstract and use replace the one direct use of the class in the accounts
editor for the signature with a new subclass.
See #283
Don't allow any preferred heigh updates to be sent until DOM has been
fully loaded and manupliated (in particular by ConversaionWebView) so
it is vaugely correct when first resized and takes a collapsed quote
heights into account.
Remove the first/last child hacks from ConversationListBox since the
GTK+ fix for :first-class and :last-class landed in early 3.22.x
releases. Ensure the first expanded email is properly size-allocated
before loading others, that it remains unmoving in the list as other
rows are added, add a loading bar above it when there are more email to
load below it.
This allows using the same code for editing account signatures as for the
composer.
* src/client/components/client-web-view.vala (ClientWebView): Move both
command_stack_changed and document_modified signals here from
ComposerWebView, since they use the same underlying machinery to
emit. Move get_html() from ComposerWebView since we want to get to the
HTML when editing signatures. Override WebView.set_editable() so we can
enable/disable the signal machinery and hence not get change signals
emitted when enabling/disabling editing.
* ui/client-web-view.js (PageState): Mirror the changes above made to
ClientWebView.
* src/meson.build (geary_web_process): Ensure C args are passed through
web compiling the web extension.
This seems to be a bit more accurate than the previous calculation.
Force the doc element's border to zero as well to make using
scrollHeight more reliable.
Queue a preferred height check on resize and transition end so we catch
cases where the user resizes the window and transitions cause a height
change after loading has completed, etc.
* src/client/components/client-web-view.vala (ClientWebView): Add
is_content_loaded property and content_loaded signal, update and fire
when getting a contentLoaded message from the WebProcess.
* ui/client-web-view.js: Fire the contentLoaded message when loading is
complete. Add ClientPageStateTest test case to ensure it is working
fine.
* test/client/components/client-web-view-test-case.vala
(ClientWebViewTestCase::load_body_fixture): Use is_content_loaded
rather than is_loading as the test for loading having finished, since
we're actually interested in when the JS has finished loaded, not the
resources.
Should help/fix Bug 778025.
* ui/client-web-view.js (PageView::init): Also add a load handler to the
window, to (strangely) catch the final load event on the
document. Expand and correct comments a bit.
* ui/conversation-web-view.js (ConversationPageState::createControllableQuotes):
Since WK does not want to seem to reduce the value of offsetHeight for
the HTML element when a quote is collapsed, calculate the difference
and manually update the preferred height.
* ui/client-web-view.js (PageState::updatePreferredHeight): Allow the new
preferred height to be passed in as a param.
* ui/client-web-view.js (PageState::getPreferredHeight): Compute and use
top and bottom when determining the height value.
* ui/conversation-web-view.css: Remove onerous style defaults now we
can deal with HTML elements with margins.
* ui/client-web-view.js (PageState): Use event listeners to send
coalesced preferred height changes, rather than using polling. Call
::load on DOM loaded, not on complete page loaded, so in-place
mutations take affect ASAP. Replace ::preferredHeightChanged with
::updatePreferredHeight method that checks that the height has changed
before sending the message to the app.
* ui/composer-web-view.js: Remove loaded event handler, it's managed by
the base class now.
* ui/conversation-web-view.js (ConversationPageState): Rename
::updatePreferredHeight to ::pollPreferredHeightUpdate to avoid name
clash with parent class. Stop polling if no change has occurred after a
number of repeated checks. Remove loaded event handler, it's managed by
the base class now.
(ComposerPageState::createControllableQuotes): Don't update preferred
height at the end of the call since it will be handled by the DOM load
event handler.
* src/client/components/client-web-view.vala (ClientWebView): Make some
unnecessarily internal methods private.
* ui/*.js: Replace "var" with "let" where appropriate - i.e. almost
everywhere.
* 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.
* ui/conversation-web-view.js: New script, port old HTML cleaning code in
vala to Javascript as new subclass of PageState. Instantiate that on
page load.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView): Load and add new JS script for conversations.
* src/client/web-process/util-conversation.vala (Util.Conversation):
Remove migrated and obsolete code.
* ui/client-web-view.js (PageState): Allow on-load behaviour to be
overridden in subclasses.
* ui/CMakeLists.txt: Include new JS script.
* ui/conversation-web-view.css: Chase CSS class name changes.
Add a "has_selection" param to avoid a second round-trip to the web
process to determine that.
* src/client/components/client-web-view.vala (ClientWebView): Add a
selection_changed signal, register a JS message handler for the JS
equivalent hook up firing the signal.
* src/client/web-process/web-process-extension.vala (GearyWebExtension):
Send a JS selectionChanged message when the page's selection changes.
* src/client/composer/composer-widget.vala,
src/client/conversation-viewer/conversation-email.vala,
src/client/conversation-viewer/conversation-message.vala: Uncomment
code that relied on the WK1 selection_changed signal, use signal param
rather than DOM calls.
* ui/client-web-view.js: Implement sending the selectionChanged message.
* ui/client-web-view.js: Move emitPreferredHeightChanged() into PageState
as ::preferredHeightChanged(). Add a explicit constructor, move
instance properties into that. Add an interval timer to periodically
update the preferred height until loaded.
* src/client/components/client-web-view.vala (ClientWebView): Register
for new remoteImageLoadBlocked message from JS. Add new
::remote_image_load_blocked signal to notify when a remote image load
was blocked. Add ::allow_remote_image_loading and ::load_remote_images
methods to allow th app to manage image loading state.
* src/client/conversation-viewer/conversation-email.vala
(ConversationEmail): Determine up front whether the message view should
load remote images and flag that, rather than passing through the email
flag and the contact store.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage): Rmeove contact_store and
always_load_remote_images properties and related code, just let the
parent email view advise whether remote images should be initially
loaded and act accordingly. Look up to ClientWebView signal and methods
to handle manual remote image loading management by the user. Remove
some obsolete code.
* src/client/web-process/web-process-extension.vala (GearyWebExtension):
Replace allow_prefix implementation for remote image management with
explicit signalling to/from the application via JavaScript.
* ui/client-web-view.js: Add a new PageState object, add props and method
to implement remote image loading management.
* ui/client-web-view-allow-remote-images.js: Monkeypatch to be used when
remote images should be loaded by default.
* ui/CMakeLists.txt: Include new JS file.
* src/client/conversation-viewer/conversation-web-view.vala,
src/client/web-process/util-conversation.vala,
src/client/web-process/util-webkit.vala: Remove obsolete code.
* src/client/components/client-web-view.vala
(ClientWebView::load_app_script): Set script injection time to the
start of the document load.
* ui/client-web-view.js: Set an onload handler to report back the
preferred height.
* bindings/vapi/javascriptcore-4.0.vapi: Add some methods to
GlobalContext for accessing JSValues as ints.
* src/client/components/client-web-view.vala
(ClientWebView): Hook up UserContentManager script messages handler and
handler implementation for "preferredHeightChanged", update the new
preferred_height prop on the class, and queue a resize. Hook those
values up to the GTK allocation machinery.
(ClientWebView::get_int_result): Convenience method for getting an int
from a JavascriptResult.
(ClientWebView::get_preferred_height): Report back values as reported
by messages from the script handler.
(ClientWebView::register_message_handler): Convenience method for
registering script messages handlers.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView): Remove now-redundant GTK allocation machinery.
* ui/client-web-view.js: Post a message to preferredHeightChanged when
the page is sorta-kinda loaded.
* src/client/application/geary-controller.vala
(GearyController::open_async): Load the app script for ClientWebView at
startup.
* src/client/components/client-web-view.vala
(ClientWebView::ClientWebView): Ensure we actually have a
UserContentManager instance to work with, add the app script to the
manager for the instance.
(ClientWebView::load_scripts): Actually load client-web-view.js.
(ClientWebView::load_user_stylesheet): Helper method for this class and
subsclasses for doing the actual script load from the app.
* ui/client-web-view.js: Add boilerplaye for new file.
* ui/CMakeLists.txt: Include client-web-view.js.