Commit graph

57 commits

Author SHA1 Message Date
Daniel Yahalom
e84611d41d new links no longer apply to entire paragraph 2023-07-08 22:12:06 +00:00
Michael Gratton
ec3057daf7 ConversationWebView: Fix plain text emails sometimes being too wide
Using `whitespace: pre-wrap` to format plain text email sometimes
causes additional width to be allocated by the plain text blocks that
then does not get used due to the constraints on the HTML element.
The allocated space remains however and hence an un-needed horizontal
scrollbar appears.

Using `break-spaces` instead seems to help since it allows breaks after
a space character, leading to the additional space not otherwise being
allocated.
2020-10-17 15:08:10 +11:00
Michael Gratton
1d80ed2034 ComposerPageState: Use CSS for managing focus with composer body parts
Now that the `:focus-within` pseudoclass is supported, use this rather
than some custom JS to update custom HTML classes. This also prevents
spurious mutation events from firing.
2020-10-13 00:02:09 +11:00
Michael Gratton
3655f4896f Composer.WebView: Convert to using messages for JS → client comms 2020-10-13 00:02:09 +11:00
Daniel Kahn Gillmor
74e37a46cc Avoid overlong regex line in javascript.
The regex line in this javascript was > 256 characters, which triggers
the following warning from debian's "lintian" source-checking tool:

    https://lintian.debian.org/tags/source-is-missing.html
    https://lintian.debian.org/tags/source-contains-prebuilt-javascript-object.html

This offers no functional change, but avoids some needless warnings
going forward.
2020-03-03 10:36:52 -05:00
James Westman
0eed1bb21a composer: Add font buttons to toolbar
This replaces the menu options in the overflow menu with nicer looking, more
discoverable toolbar buttons. They work much the same way as before.
2020-01-21 19:43:37 -06:00
Michael Gratton
1447d1acbc Minimise DOM changes made by ComposerPageState::cleanContent JS
By overriding ComposerPageState::getHtml to accept a parameter that
supports getting HTML with empty composer parts removed, cleanContent
can simply be made to linkify the page, thus allowing a ComposerWidget
to be re-used multiple times when sending an email.
2019-11-17 20:00:01 +11:00
Chris Heywood
fa430cac5d Improve passing of inline dropped file through to vala !343 2019-11-17 16:40:13 +11:00
Chris Heywood
f8fa4a4630 First changes for supporting drag & dropped and pasted images
See #90 and #304. Work in progress.
2019-11-17 16:40:13 +11:00
Alex Henrie
20284fe29c Remove unused variable urlRegex from ComposerPageState.containsKeywords 2019-10-26 03:02:41 -06:00
Alex Henrie
feed89225f Don't linkify text near a URL that looks like a URL with a bad protocol 2019-10-22 18:53:18 -06:00
Michael Gratton
69e3cdf9b5 Fix ComposerPageState::containsAttachmentKeyword
Just use ComposerPageState::htmlToText to get the email's main content
without quotes, not some custom code.
2019-10-07 23:49:12 +11:00
Michael Gratton
a8ef91f3a8 ui/composer-web-view.js: Improve keyword detection
Update ComposerPageState.containsKeywords to split on any punctuation,
not just spaces, so that text like "see the attachment." will get
detected.
2019-10-07 23:48:38 +11:00
Michael Gratton
5732d23e98 ui/composer-web-view.js: Add element blacklist to htmlToText
Update ComposerPageState.htmlToText() to allow ignoring certain elements
if needed. Update tests to test the function directly rather than going
through ComposerPageState.toText().
2019-10-07 23:42:49 +11:00
Alex Henrie
52d010bb22 Clean up composer link insertion and deletion
Allow deleting only the selected part of a link, and modify the existing
link instead of inserting a new one if the user didn't select any text.
Also restructure the code to avoid always-true or always-false if
statements.

Fixes #591
2019-10-05 10:25:25 -06:00
Rafael Fontenelle
2509c5c4f0 Fix misspellings 2019-05-22 20:47:08 +00:00
Jiří Černý
1a6113efa4 Ignore style nodes while converting HTML to text 2019-04-05 09:45:14 +02:00
Konstantin Kharlamov
65af96a499 composer-web-view: add missing semicolon after field assignment
Fixes LGTM warning: "Avoid automated semicolon insertion (93% of all
statements in the enclosing script have an explicit semicolon)."

Signed-off-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
2019-03-23 13:42:36 +03:00
Konstantin Kharlamov
0f773f9e21 composer-web-view: remove unused variable
Fixes LGTM warning "Unused variable state."

Signed-off-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
2019-03-23 13:42:36 +03:00
Michael Gratton
12c6bbca56 Fix signature not being updated when composer first opened without one
The ComposerPageState JS object assumed that if no signature was present
when first loaded, that none ever would be. This broke changing the
signature when the composer was opened for an account without one, and
the from account was changed to an account with a sig.

Instead of including the signature as part of the loaded body, always
include just a skeleton signature DIV and ensure the signature is loaded
dynamically after the body has been loaded. Update code and tests to
match this assumption, and add a unit test for updating the sig.

Fixes #309
2019-03-11 12:19:57 +11:00
Alex Henrie
67d819565e Don't add Geary-flavored markdown to plain text messages
Fixes #201
2019-02-08 23:16:01 -07:00
Alex Henrie
82cd2d92e1 Only collapse runs of space, tab, carriage return, and newline
Closes #184
2019-01-14 19:54:14 -07:00
Alex Henrie
a9efe8fd3a Add plaintext quote marker to blockquote lines in one pass 2019-01-01 17:55:28 -07:00
Alex Henrie
00da60debe Delineate tags a, b, i, and u in plaintext conversion 2018-12-31 11:36:41 -07:00
Michael James Gratton
f7ad510dcc Push WebView editing machinery from the composer to the client.
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.
2018-11-30 23:49:30 +11:00
Nikolas Tapia
63521d8566 Added support for lists in composer
This attempts to solve bug
[#714921](https://bugzilla.gnome.org/show_bug.cgi?id=714921).

They are available as two buttons on the format bar, next to font
options. The icons I used are taken from a free icons site just for demo
purposes and should be replaced by new icons. Also I did not include
hotkeys mainly because I could not come up with a good one, also they
are pretty uncommon I think.

Also added new icons to icons/CMakeLists.txt
2017-12-12 23:32:28 +11:00
Michael James Gratton
261e8a4ba3 Prevent composer body/sig/quote parts from losing focus. Bug 779369.
* ui/composer-web-view.js: Add a click handler for the document that
  prevents clicks outside the body parts from being processed.
2017-11-16 15:49:51 +11:00
Michael James Gratton
7ad97fb5d9 Handle font-family strings containing both single and double quotes.
Fixes a failing unit test with WebKitGTK 2.18.

* ui/composer-web-view.js (EditContext::init): Check for and strip both "
  and ' from start and end of font-family string.
2017-11-16 10:48:42 +11:00
Michael James Gratton
96ffcdb608 Split composer web view up into multiple parts.
This lets us implement changing signatures and deleting bottom-quoted
messages without having to reload the whole view, and makes it possible
to target only the user's content when modifying for send, etc.

* src/client/composer/composer-web-view.vala (ComposerWebView): Move
  composer CSS into composer-web-view.css resource file, load it when
  loading JS resource and add it to the view's user content manager.
  (ComposerWebView::load_html): Split up body, signature and quote into a
  DIV container for each.
  (ComposerWebView::linkify_content): Replaced with ::clean_content,
  which will also tidy up internal markup before sending. Update call
  site and unit test.

* src/engine/rfc822/rfc822-utils.vala (Geary.RFC822.Utils): Remove some
  more obtrusive white space when sending replies/forwards.

* test/client/composer/composer-web-view-test.vala,
  test/js/composer-page-state-test.vala: Update tests to expect new HTML
  and text output from ComposerWebView and use of individual parts for
  composer markup.

* ui/composer-web-view.js (ComposerPageState): Replace messageBody
  property and uses with bodyPart, signaturePart and quotePart. Set these
  content-editable on load. Move listeners from messageBody back to the
  document.body so they also listen for events on the additional
  parts. Keep track of text cursor location within the parts and set a
  class if so, to work around the lack of :focus-inside support.
  (ComposerPageState::updateSignature): Implement by updating the inner
  content of the signature part.
  (ComposerPageState::deleteQuotedMessage): Implement by removing the
  quote part from the DOM tree.
  (ComposerPageState::containsAttachmentKeyword): Consider only the
  bodyPart when scanning for attachments, remove hacks for ignoring the
  signature any any quoted message.
  (ComposerPageState::linkifyContent): Mirror ClientWebView change and
  replace with ::cleanContent. Ensure existing parts have contenteditable
  and focus class removed, remove signature and quote parts if empty.
  (ComposerPageState::getHtml): Generate HTML using clones of the three
  parts, so we can rmeove contenteditable and focus classes without
  modifying the actual DOM.
  (ComposerPageState::selectionChanged): Update focus class on parts as
  needed.
2017-02-01 00:41:45 +11:00
Michael James Gratton
67762f22cb Really fix JS error calling ComposerWebView::save_selection.
* ui/composer-web-view.js: Increment must be in brackets.
2017-02-01 00:41:45 +11:00
Michael James Gratton
5163b5198d Stop the insert link popover being dismissed when selecting text.
* src/client/composer/composer-web-view.vala (ComposerWebView): Add
  ::save_selection and ::free_selection to allow the selection to be
  saved when inserting a link. Thunk calls to JS.
  (ComposerWebView::insert_link): Add selection id param, pass through to
  JS.

* src/client/composer/composer-widget.vala
  (ComposerWidget::new_link_popover): Manage saving the editor's
  selection, passing its id when inserting a link, freeing it
  again. Convert into an async method so we can wait for the selection id
  to get back from the WebProcess, update call sites.
  (ComposerWidget::on_insert_link): Disconnect and reconnect selection
  changed signal so the popover isn't dismissed when the selection does
  change/

* ui/composer-web-view.js (ComposerPageState): Implement new
  ::saveSelection, ::freeSelection and selectionId param on ::insertLink.
2017-02-01 00:41:45 +11:00
Michael James Gratton
b24291defe Break containing blockquotes when Enter pressed in composer.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
848558f368 Reenable converting plain text URLs to links in HTML documents.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
e22ece508c Replace two composer IPC calls for indenting with a single one.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
e0bff994fa Reenable composer attachment keyword checking.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
48d92fa67c Let focus escape composer web view using Ctrl+Tab/Ctrl+Shift+Tab.
* src/client/composer/composer-widget.vala: Let default keyboard
  shortcuts handle focus move.

* ui/composer-web-view.js: Don't consume Tab presses with Crtl/Alt/Meta
  modifiers.
2017-02-01 00:41:44 +11:00
Michael James Gratton
dec06d93be Clean up how composer loads content into its web view.
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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
5dfcfe4c8e Update how ClientWebView HTML preferred size changes are sent to the app.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
ab4fec91be Enable editing a link by clicking on it.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
e4f50e1c36 Implement ComposerWebView::insert_link and ::delete_link.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
c476fdc6d1 Replace composer link dialog with a popover.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
53caf43fca Replace ad-hoc ComposerWebView cursor signal param w/ structured object.
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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
fcf5be297e Re-enable composer empty body checking and draft save timer.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
fd97ad2887 Reimplement inserting/removing \t chars in the composer.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
67d81c3e15 Re-implement composer font family/size action state updating.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
2bd5306d30 Reenable undo/redo composer actions.
* 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.
2017-02-01 00:41:44 +11:00
Michael James Gratton
636e514cda Minor code cleanup.
* 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.
2017-02-01 00:41:43 +11:00
Michael James Gratton
977bb2827a Minor code cleanup. 2017-02-01 00:41:43 +11:00
Michael James Gratton
17fda41b85 Fix non-breaking spaces breaking formatting in sent messages.
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.
2017-02-01 00:41:43 +11:00
Michael James Gratton
536fb04840 Minor code updates. 2017-02-01 00:41:43 +11:00