* 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.
We can't easily wrap ComposerWebView in a GtkScrolledWindow, since we
don't any notifications that the cursor has moved offscreen and hence the
view needs to be scrolled, so let the view do its own scrolling.
* ui/composer-widget.ui: Replace editor_scrolled with editor_container,
update uses.
* src/client/components/client-web-view.vala
(ClientWebView::preferred_height): Make preferred_height a public
property so it can be accessed outside the class. Move
::get_preferred_height and ::get_preferred_width to
ConversationWebView. Tidy up ::on_preferred_height_changed a bit.
* ui/composer-web-view.js (ComposerPageState): Break any blockquote
elements under the cursor when Enter is pressed, unless Shift is also
down.
* src/client/web-process/util-composer.vala: Removed, no longer used.
* src/client/composer/composer-web-view.vala (ComposerWebView): Rename
::linkify_document since it really only applies to editor content. Make
an asyc method so we can wait until its finished. Update call
sites. Thunk call to JS.
* src/client/web-process/util-composer.vala,
src/client/web-process/util-webkit.vala: Remove unused code.
* ui/composer-web-view.js (ComposerPageState): Add ::linkifyContent
method and ::linkify static method. Add unit tests.
* src/client/composer/composer-web-view.vala (ClientWebView): Replace
::undo_blockquote_style with ::indent_line.
* src/client/composer/composer-widget.vala (ComposerWidget::on_indent):
Call new ::indent_line method, rather than doing a execCommand and a
second JS thunking call to fix the markup.
* ui/composer-web-view.js: Also replace ::undoBlockquoteStyle with new
::indentLine method. Add unit test.
* src/client/composer/composer-web-view.vala (ComposerWebView): Add
::contains_attachment_keywords that thunks to JS, remove uneeded
::get_block_quote_representation method.
* src/client/composer/composer-widget.vala (ComposerWidget): Remove
attachment keywork checking related code, just call new method on
editor to do the check.
* src/client/web-process/util-composer.vala,
src/client/web-process/util-webkit.vala: Remove uneeded code.
* ui/composer-web-view.js (ComposerPageState): Implement new
::containsAttachmentKeyword method based on previous code. Add unit
tests.
The main gist of this is to ensure that the composer's widgets are
constructed seperately to loading its content, and that we only ever call
ComposerWebView::load_html precisely once per composer instance.
* src/client/composer/composer-widget.vala: Remove referred message,
quote text and draft flag param from constructor signature, move any
calls that loaded data from them to new load method. Don't load
anything into the editor here. Make loading the signature file async,
and call new ComposerWebView::updateSignature method on the editor to
update it.
(ComposerWidget::load): New async message for loading content into the
composer. Move related code from the constructor and GearyController
here, make methods that were previously public for that private
again. Tidy up calls a bit now that we have a single place from which
to do it all, and can understand the process a bit better.
(ComposerWidget::on_editor_key_press_event): Don't reload the editor to
remove the quoted text, call new ComposerWebView::delete_quoted_message
method on it instead.
* src/client/composer/composer-web-view.vala
(ComposerWebView): Add ::delete_quoted_message ::update_signature
methods, thunk to JS.
(ComposerWebView::load_html): Add quote and is_draft parameters,
construct HTML for the composer using apporporate spacing here, instead
of relying on all the disparate parts from doing the right thing.
* src/client/application/geary-controller.vala
(GearyController::create_compose_widget_async): Load composer content
after adding it to the widget hierarchy, set focus only after
everything is set up.
* src/engine/rfc822/rfc822-utils.vala (quote_email_for_reply,
quote_email_for_forward): Don't add extra padding around quoted parts -
let callers manage their own whitespace.
* test/client/components/client-web-view-test-case.vala
(TestCase:load_body_fixture): Make HTML param non-nullable, update
subclasses.
* ui/composer-web-view.js (ComposerPageState): Add ::updateSignature and
::deleteQuotedMessage method stubs.
* 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.
* bindings/vapi/javascriptcore-4.0.vapi (Object::get_property): Fix
return type.
* src/client/conversation-viewer/conversation-message.vala (GtkTemplate):
Hook up to new deceptive_link_clicked signal, remove old DOM-based
implementation.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView): Add new deceptive_link_clicked signal and
DeceptiveText enum, listen for deceptiveLinkClicked JS message and fire
signal when received.
* src/client/util/util-webkit.vala (WebKitUtil): Add to_object util function.
* src/engine/util/util-js.vala (Geary.JS): Add to_object and get_property
util functions.
* ui/conversation-web-view.js (ConversationPageState) Listen for link
clicks, check for deceptive text and send message if found. Add unit
tests for deceptive text check.
* test/js/composer-page-state-test.vala: Move ::run_javascript to parent
class so new ConversationPageStateTest class can use it, adapt call
sites to different parent signature.
* src/client/util/util-webkit.vala (to_number, to_string): Move code for
extracting actual vales to functions in engine/util/util-js.vala,
rework to use those functions.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::on_mouse_target_changed): Unset the tooltip text
when pointer exits a link.
* src/client/composer/composer-widget.vala
(ComposerWidget::on_button_press): Show a link popover on button
release.
* src/client/composer/composer-web-view.vala (ComposerWebView): Add
button_release_event_done signal to work around WK eating mouse events,
fire it after default processing has occurred.
* ui/composer-web-view.js: Don't bother selecting a link on click, we
are handling insertion and deletion without it fine now. Just cancel
the event's default so link clicks are not activated.
* src/client/composer/composer-web-view.vala (ComposerWebView): Call
new ComposerPageState methods for ::insert_link and ::delete_link.
* ui/composer-web-view.js (ComposerPageState): Add new ::insertLink
and ::deleteLink methods, handle linking/unlinking both the
current selection and the link under the text cursor, if nothing
is selected.
* 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.
This lets us notify of more cursor editing context state in the future
without changing the signal signature.
* src/client/composer/composer-web-view.vala (ComposerWebView): Replace
cursor_style_changed signal and cursorStyleChanged JS message with
cursor_context_changed signal and cursorContextChanged message, add new
EditContext inner class and pass as arg to new signal, update call
sites. Move parsing of JS message to new inner class. Add unit tests,
fix a font-family bug revealed by tests.
* ui/composer-web-view.js (ComposerPageState): Replace cursorFontFamily
and cursorFontSize with a cursor context and new EditContext object to
encapsulate them, update them from a node and serialise them. Add unit
tests.
* src/client/composer/composer-widget.vala (ComposerWidget): Rename
on_selection_changed to update_selection_actions, call as needed. Tidy
action init methods a bit.
* src/client/components/client-web-view.vala (ClientWebView): Add new
has_selection property and keep it updated.
* src/client/composer/composer-widget.vala
(ComposerWidget::initialize_actions): Disable close-and-save by
default, opening draft manager will enable it if needed.
(ComposerWidget::restore_draft_state_async): Update doc comment noting
use constraints, remove account param since we should be using the
instance's instead. Update call site.
(ComposerWidget::open_draft_manager_async): Don't try to close the
manager beforehand, we should be able to manage that externally.
(ComposerWidget::reopen_draft_manager_async): New async method to
handle closing and reopening the draft manager in the appropriate
order, since it's one caller is not async.
(ComposerWidget::discard_and_exit_async): Only attempt to discard the
draft if we have a draft manager. We need the guard since this may also
get called even if drafts are not being saved.
(ComposerWidget::set_header_recipients): Don't flag draft as having
changed, these issues should only be cosmetic.
(ComposerWidget::on_from_changed): Move to a more appropriate location
in the source, just call ::reopen_draft_manager_async instead of trying
to handle it here.
* src/client/composer/composer-widget.vala (ComposerWidget): Rename
subject changed handler to something more generic, hook that up to the
to/cc/bcc & reply_to entries.
* ui/composer-widget.ui: Hook up multiple to on_envelope_changed, make
subject entry use that as well.
* src/client/composer/composer-widget.vala (ComposerWidget): Add
`can_save` property that defined what the composer's reqwuirements for
being able to save a draft.
(ComposerWidget::should_close): Use can_save rather than should_save to
determine which confirmation dialog to show. When keeping, only save if
we need to. Split up handling responses from 2 and 3 button dialogs so
it's more clear what is going on in each case.
* src/client/composer/composer-widget.vala (ComposerWidget): Add
::is_draft_saved field, update it as the draft manager's state changes,
or if the message has been changed. Rename ::can_save to ::should_save
to better reflect what it is used for, don't allow saving if a draft
has been saved. Rename update_draft_state as a proper method, use it
update initial state after opening draft manager, tidy up location of
draft signal handlers.
* src/client/components/client-web-view.vala (ClientWebView): Introduce
new JavaScriptMessageHandler delegate for JS message handler callbacks.
(ClientWebView::register_message_handler): Add delegate as second param
and register it as the callback for the handler. Update call sites to
use this form, do not have them explicitly unref the JavascriptResult
since WK2 is doing the right thing, and clean them up in general.
* src/client/components/client-web-view.vala (ClientWebView): Remove
now-unsed ;;allow_prefix property. Add ::insert_image method.
* src/client/composer/composer-widget.vala (ComposerWidget): Split up
"attachment" handling into inline and attached parts so we can require
a Content ID be passed in for inline parts. Convert ::inline_files set
into a map, so we can be explict about the IMG SRC URL that was used to
refer to the inline part, either cid or geary, and update call sites.
(ComposerWidget::on_insert_image): Simply add the image as a new inline
part with a geary URL, and insert it via the editor.
* src/engine/api/geary-composed-email.vala (ComposedEmail): Also use a
map of inline parts, for the same reason as ComposerWidget. Update call
sites.
* src/engine/rfc822/rfc822-message.vala (Message.from_composed_email):
Use the given URL for inline parts when assigning Content IDs and
replacing the internal URL in the source.
* src/client/components/client-web-view.vala (ClientWebView): Rename
members referring to inline resources to internal resources, update
call sites.
(ClientWebView::handle_cid_request,
ClientWebView::handle_internal_request): Rework to use new common
::handle_internal_response method.
* src/client/web-process/web-process-extension.vala: Permit by default
any geary, cid, or data URI request.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::on_resource_load_started): Always store loaded
resources for saving, not only if they have internal URLs.
* src/client/composer/composer-web-view.vala (ClientWebView): Add a
::document_modified signal and a documentModified JS message listener,
fire it when the JS message is receieved. Update value of ::is_empty
based on whether a non-empty HTML body was provided in the first place,
and if it has been subsequently modified. Update related doc comments a
bit.
* src/client/composer/composer-widget.vala (ComposerWidget): Rename
`blank` property to `is_blank`, fix sense of editor.is_blank check,
update call sites. Convert ::can_save method into a property, include
the this.is_blank check since there's no point saving a blank message,
updtae call sites. Replace use of GLib.Timeout with
Geary.TimeoutManager, tidy up resulting code, hook up timer to new
document_modified signal.
* ui/composer-web-view.js: Use body mutation observer to send
documentModified messages to the client, coalescing consecutive events
over a period of 1s into a single message.
* src/client/composer/composer-widget.vala (ComposerWidget::save_draft):
Make this method async, so we can yield when calling
::get_composed_email instead of starting it with begin(). This means
that in ::save_and_exit_async, we can in turn yield to ::save_draft, to
ensure the message is saved before closing the draft manager.
(ComposerWidget::on_from_changed): Don't blindly reset the draft timer
after starting to open the draft manager, it will fail if opening the
draft manager takes longer than the timer. Instead, reset the timer in
an async callback.
* src/client/application/geary-controller.vala
(GearyController::create_compose_widget_async): Explictly set the focus
once the composer has been added to the widget hierarchy.
* src/client/components/main-window.vala (MainWindow): Convert
on_key_press_event handler to override Gtk.Window's key_press_event
virtual method. Reimplement that so that single keystroke shortcuts
work, but also so GtkWindow.propagate_key_event only gets called once,
and the WebKit event loop is avoided. See source comments for
details. Also clean up shift up/down handling to not update when any
GtkEntry or ComposerWebView is focused.
* src/client/composer/composer-web-view.vala (ComposerWebView:): Rmeove
is_shift_down property and key handling that updates it. We aren't
gonna need it.
* src/client/composer/composer-widget.vala (ComposerWidget): Split out
Ctrl+Return check for sending into a seperate method, so the editor key
press handler doesn't end up calling ComposerWidget's parent's
key_press_event implementation. Use Gdk.EVENT_FOO constants.
* ui/composer-web-view.js (ComposerPageState): Add tabOut/tabIn
functions, listen to key Tab key pressess on the body and invoke the
appropriate method if found.
* src/client/web-process/util-composer.vala: Removed old vala
implementation of same.
* src/client/components/client-web-view.vala
(ClientWebView::load_user_stylesheet): Don't warn when we can't load
the user CSS file, since that's likely to be the case.