* 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.
* 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-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.
* 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/composer/composer-web-view.vala (ComposerWebView): Add new
::cursor_style_changed signal, hook it up to the JS cursorStyleChanged
message and interpret the raw results from the web view before passing
it on.
* src/client/composer/composer-widget.vala (ComposerWidget): Replace
remainder of old ::update_actions method with a listener for
ComposerWebView::cursor_style_changed. Reimplement in terms of that
signal.
* ui/composer-web-view.js: Keep track of font family and size changes,
send a cursorStyleChanged message when they change.
* src/client/composer/composer-web-view.vala (ComposerWebView): Add new
::command_stack_changed signal to manage undo/redo enabled state, hook
it up to a JS callback. Add ::is_empty property as a non-functioning
shim in lieu of can_undo going away. Remove ::can_undo and ::can_redo,
replace them with methods to actually fire an undo and redo.
* src/client/composer/composer-widget.vala (ComposerWidget): Use
ClientWebView::is_empty rather inplace of can_redo for determining
editing state. Remove old undo/redo signal hookups, replace with
::command_stack_changed and manage action enable state from there.
(ComposerWidget::action_entries): Add explicit actions for undo/redo,
since they need some custom code over on on the web process side.
(ComposerWidget::on_compose_as_html_toggled): Explciitly manage the
visibility of rich text toolbar buttons, don't rely on obscure
GtkBuilder magic that Glade doesn't support.
* ui/composer-web-view.js: Add a mutation observer for the message body
and explcit methods for firing undo/redo commands, so we can keep track
of how the command stack changes. As it does, fire commandStackChanged
messages back to the client process. Explicity set the message body as
content-editable after the document has been mutated for quotes, etc.
* ui/composer-widget.ui: Add bonus undo/redo toobar buttons for the
composer.
* 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.
This ensures that non-breaking space chars (not HTML entities) are
removed from text obtainined from the composer, and moves the F=F text
formatting from JS back to Vala, to minimimse the JS footprint and return
to using the old (working) version again.
* src/client/composer/composer-web-view.vala (ClientWebView::get_text):
Restore the old F=F formatting code previously in webkit-util, apply it
to plain text obtained from the composer.
* test/client/components/client-web-view-test-case.vala: New base class
for tests involving ClientWebView.
* test/client/composer/composer-web-view-test.vala: New tests for
ComposerWebView::get_html and ::get_text.
* test/js/composer-page-state-test.vala: Reworked to use
ClientWebViewTestCase, updated tests now that JS is returning
QUOTE_MARKER-delinated text, not F=F text.
* test/testcase.vala (TestCase): Move ::async_complete and ::async_result
from ComposerPageStateTest so all test cases can test async code.
* test/CMakeLists.txt: Add new source files.
* test/main.vala (main): Add new test.
* ui/composer-web-view.js: Update doc comments, remove F=F code, break
out non-breaking space replacement so it can be tested.
* ui/composer-web-view.js (ComposerPageState::resolveNesting): Apply JS
RegExp globally, to match default GLib RegEx behaviour.
* test/js/composer-page-state-test.vala: New tests covering generation of
HTML and F=F text from JS ComposerPageState object.
* test/CMakeLists.txt: Add the new test.
* test/main.vala (main): Add a test suite for JS tests, add the new test
to it.
* src/client/components/client-web-view.vala (ClientWebView): Add a
reason to the JSError domain for when a JS exception is thrown.
* bindings/vapi/javascriptcore-4.0.vapi (JS::Context): Add JS.Type and
some additional methods needed for the unit tests. Move most
GlobalContext methods to Context so we can pass the lowest common
demominator around.
* src/client/composer/composer-web-view.vala (ComposerWebView): Implement
both ::get_html and ::get_text as async JS calls, make the methods
async and update cal sites to handle that.
* src/client/composer/composer-widget.vala: Make saving deafts and
sending message async, to handle editor returning message body text
async. Remove uneeded ::get_html and ::get_text functions, update call
sites to call same directly on the on editor instead.
* src/client/web-process/util-composer.vala: Remove obsolete ::get_html
and ::get_text functions.
* ui/composer-web-view.js (ComposerPageState): Initial implementation of
getHtml and getText methods.
* src/client/application/geary-controller.vala (GearyController::open_async):
Load ComposerWebView resources.
* src/client/composer/composer-web-view.vala (ComposerWebView): Move
HTML/CSS template here from ComposerWidget. Load composer-web-view.js
on app init and add it to the web view's user content manager.
(ComposerWebView::load_html): Overridden to require HTML body and
signature, assemble complete HTML as appropriate before chaining up to
the default impl.
(ComposerWebView::load_finished_and_realised): Remove redundant method.
* src/client/composer/composer-widget.vala (ComposerWidget):
Remove 'message' prop since it is unused and onerous. Cache current
account's signature as a field so it can be passed through to the
editor as needed. Port on_link_clicked to composer-web-view.js.
* src/client/web-process/util-composer.vala: Remove function ported to JS
in composer-web-view.js
* ui/CMakeLists.txt: Include new ComposerWebView JS resource.
* ui/composer-web-view.js: Port composer HTML sanitisation methods to JS,
add to a custom subclass of PageState. Instantiate it and hook it up to
onload.