Abstract

This specification defines additions to events for text and related input to allow for the monitoring and manipulation of default browser behavior in the context of text editor applications and other applications that deal with text input and text formatting. This specification builds on the UI events spec [UI-EVENTS].

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Web Platform Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-editing-tf@w3.org (subscribe, archives) or raise a GitHub issues. All comments are welcome.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

The group expects to produce another working draft by October 31st, 2016. The test suite and implementation reports for the Input Events specification are still work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

1. Introduction

This document describes editing related additions to 2 events - Input and beforeinput which are described in the UI events spec [UI-EVENTS]. The goal of these events is to allow authors to understand and/or override default edit behavior both before and after editing occurs.

2. Definitions

DataTransfer
An DataTransfer object contains richtext and plaintext data for some inputtypes. [DATA-TRANSFER]

3. Problems solved

This section is not normative.

Creating a webbased texteditor requires a considerable amount of JavaScript on top of the browser code, among other things because:

  1. Browsers do not handle all editing operations the same way.
  2. Browsers are often buggy in the way they handle certain editing operations.
  3. Individual sites may have custom preferences for how they want to handle certain editing operations.
  4. The development of hihg-level text editing features in browsers has not followed the principles laid out in the Extensible Web Manifesto in that development of these features has not always been in coordination with the needs of the web developer community.

This spec seeks to alleviate the problem by providing a simple way for web developers to both override browser handeling of all user input related to text editing through the beforeinput event, and to monitor what browsers have changed in the DOM due to user input trough the input event.

4. Use cases

This section is not normative.

  1. Creating a JavaScript text editor in which the <strong>-tag is used instead of the <b>-tag to mark text that the user marks as bold, using any browser-builtin way to mark a text as bold, without having access to all existing browsers.
  2. Creating a JavaScript text editor which works with a data model in the background where JavaScript takes care of rendering changes to the edited text to the DOM.
  3. Creating a JavaScript editor which only allows a subset of richtext editing (for example: bold is allowed, but italic not).
  4. Creating a collaborative editor in which JavaScript is used to render changes to the DOM, based on user intentions with users using different browsers with different ways of expressing specific intentions.
  5. Creating a JavaScript editor with different user access options, where some users only can add or delete text and other users only can add or remove certain types of formatting.

5. Input Event Types

Input events are sent before (beforeinput event) and after (input event) a user attempts to edit the markup. This includes characters, deletions, and other related edits.

5.1 Interface InputEvent

The main part of the InputEvent is defined in [UI-EVENTS]

[Constructor(DOMString typeArg, optional InputEventInit inputEventInitDict)]
partial interface InputEvent {
    readonly attribute DOMString     inputType;
    readonly attribute DataTransfer? dataTransfer;
    sequence<StaticRange> getTargetRanges();
};

5.1.1 Overview

This section is not normative.

The following table provides a summary of when the data and dataTransfer attributes contain contents and when they are null as well as when the getTargetRanges() method returns an empty or non-empty Array, based on the inputType.

inputType data dataTransfer getTargetRanges()
"insertText" Yes null Non-empty Array
"cut" null Yes Non-empty Array
"paste" null Yes Non-empty Array
"drag" null Yes Non-empty Array
"drop" null Yes Non-empty Array
"insertNonText" null Yes Non-empty Array
"undo" null null Empty Array
"redo" null null Empty Array
All Remaining null null Non-empty Array

5.1.2 Attributes

inputType holds the type of input. Allowed values are the following: "insertText", "insertNonText", "insertLineBreak", "insertParagraph", "insertOrderedList", "insertUnorderedList", "insertHorizontalRule", "deleteWordForward", "deleteWordBackward", "deleteLineForward", "deleteLineBackward", "deleteComposedCharacterBackward", "deleteComposedCharacterForward", "deleteContentBackward", "deleteContentForward", "undo", "redo", "cut", "paste", "bold", "italic", "underline", "strikeThrough", "superscript", "subscript", "justifyCenter", "justifyRight", "justifyLeft", "indent", "outdent", "removeFormat", "drag", "drop". During initialization, the user agent [UI-EVENTS] is responsible for populating this field as follows:

Note
The existence of the above mentioned inputTypes does not mean that any given implementation will support all of these. But if a given browser supports an editing operation which potentially leads to a change of the DOM, it MUST dispatch [ UI-EVENTS] the corresponding beforeinput and input events.
  1. If the user intends to insert plain text typing on a keyboard, IME, speech, or similar method, the inputType MUST be "insertText".
  2. If the user intends to insert content potentially containing more than just plain text using a keyboard, IME, speech, or similar method, the inputType MUST be "insertNonText".
  3. If the user intends to insert a line break using a keyboard, IME, speech, or similar method, the inputType MUST be "insertLineBreak".
  4. If the user intends to insert a paragraph break using a keyboard, IME, speech, or similar method, the inputType MUST be "insertParagraph".
  5. If the user intends to insert a numbered list using a keyboard, IME, speech, or similar method, the inputType MUST be "insertOrderedList".
  6. If the user intends to insert a bulleted list using a keyboard, IME, speech, or similar method, the inputType MUST be "insertUnorderedList".
  7. If the user intends to insert a horizontal rule using a keyboard, IME, speech, or similar method, the inputType MUST be "insertHorizontalRule".
  8. If the user intends to delete a character after the caret position during character composition using IME, the inputType MUST be "deleteComposedCharacterForward".
    1. Set the value of cancelable to false.
  9. If the user intends to delete a character before the caret position during character composition using IME, the inputType MUST be "deleteComposedCharacterBackward".
    1. Set the value of cancelable to false.
  10. If the user intends to delete a word directly before the caret position, using a keyboard, speech, or similar method, and the selection is empty, the inputType MUST be "deleteWordBackward".
  11. If the user intends to delete a word directly after the caret position using a keyboard, speech, or similar method, and the selection is empty, the inputType MUST be "deleteWordForward".
  12. If the user intends to delete a line directly before the caret position using a keyboard, speech, or similar method, and the selection is empty, the inputType MUST be "deleteLineBackward".
  13. If the user intends to delete a line directly after the caret position using a keyboard, speech, or similar method, and the selection is empty, the inputType MUST be "deleteLineForward".
  14. If the user intends to delete the content directly before the caret position and this intention is not covered by another inputType or the user itends to delete a non-collapsed selection with the selection collapsing to its start after the deletion, using a keyboard, speech, or similar method, the inputType MUST be "deleteContentBackward".
    Note
    If the selection is collapsed, deleteContentBackward will be used both when the user asks for text deletion within a text node, and when the user shows the intention to deletion of more complex elements or merge paragraphs if the caret is at the start of a text node. In some scripts, backward deletion within a text node with a collapsed selection will delete a code point rather than a grapheme. A grapheme can consist of several characters, where each character corresponds to a code point. The getTargetRanges() method can be used to find out how many characters the browser will remove by default if deleting within a text node.
  15. If the user intends to delete the content directly after the caret position and this intention is not covered by another inputType or the user itends to delete a non-collapsed selection with the selection collapsing to its end after the deletion, using a keyboard, speech, or similar method, the inputType MUST be "deleteContentForward".
    Note
    If the selection is collapsed, deleteContentForward will be used both when the user asks for text deletion within a text node, and when the user shows the intention to deletion of more complex elements or merge paragraphs if the caret is at the end of a text node. In some scripts, forward deletion within a text node with a collapsed selection will delete a grapheme rather than a code point. A grapheme can consist of several characters, where each character corresponds to a code point. The getTargetRanges() method can be used to find out how many characters the browser will remove by default if deleting within a text node.
  16. If the user intends to undo the last editing action using a keyboard, IME, speech, or similar method, the inputType MUST be "undo".
  17. If the user intends to redo the last editing action using a keyboard, IME, speech, or similar method, the inputType MUST be "redo".
  18. If the user intends to cut using a keyboard, context menu, speech, or similar method, the inputType MUST be "cut".
  19. If the user intends to paste using a keyboard, context menu, speech, or similar method, the inputType MUST be "paste".
  20. If the user intends to initiate bold text using a keyboard, context menu, speech, or similar method, the inputType MUST be "bold".
  21. If the user intends to initiate italic text using a keyboard, context menu, speech, or similar method, the inputType MUST be "italic".
  22. If the user intends to initiate underline text using a keyboard, context menu, speech, or similar method, the inputType MUST be "underline".
  23. If the user intends to initiate stricken through text using a keyboard, context menu, speech, or similar method, the inputType MUST be "strikeThrough".
  24. If the user intends to initiate superscript through text using a keyboard, context menu, speech, or similar method, the inputType MUST be "superscript".
  25. If the user intends to initiate subscript through text using a keyboard, context menu, speech, or similar method, the inputType MUST be "subscript".
  26. If the user intends to justify center the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "justifyCenter".
  27. If the user intends to justify right the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "justifyRight".
  28. If the user intends to justify left the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "justifyLeft".
  29. If the user intends to indent the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "indent".
  30. If the user intends to outdent the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "outdent".
  31. If the user intends to remove all formatting from the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "removeFormat".
  32. If the user intends to drag the current selection using keyboard, context menu, speech, or similar method, the inputType MUST be "drag".
  33. If the user intends to drop a dragged object into the current selection using a keyboard, context menu, speech, or similar method, the inputType MUST be "drop".

data holds information plaintext data that is to be added to the document.

  1. If the inputType is "insertText", the value of data is to be the plain text string to be inserted.
  2. Else, the value of data is to be null.

dataTransfer holds information about richtext and plaintext data that is to be taken from or added to the document in a DataTransfer object if there is relevant data.

  1. If the inputType is "cut", "paste", "drag", "drop", or "insertNonText", the dataTransfer attribute is a prepopulated DataTransfer object so that:
    1. The DataTransfer object's drag data store item list contains one entry with the draf data item type string "text/html", whose kind is Plain Unicode string, and whose data is a HTML representation of the content that is to be cut, copied, pasted, dragged, dropped or added. [HTML-LIVING]
    2. The DataTransfer object's drag data store item list contains one entry with the draf data item type string "text/plain", whose kind is Plain Unicode string, and whose data is a plain text representation of the content that is to be cut, copied, pasted, dragged, dropped or added. [HTML-LIVING]
  2. Else, the dataTransfer attribute is null.

5.1.3 Methods

getTargetRanges() returns an Array of StaticRanges [STATIC-RANGE] affected by this event, unless the inputType is "undo" or "redo" in which case it returns an empty Array.

5.2 Event definitions

beforeinput
Type beforeinput
Interface InputEvent
Sync / Async Sync
Bubbles Yes
Trusted Targets Any Element with contenteditable attribute enabled.
Default action [UI-EVENTS] Varies: 'Update the DOM' for contentEditable=typing editing hosts for inputTypes "insertText" and "deleteComposedCharacter". 'Update the DOM element' for contentEditable="true" editing hosts for all inputTypes. None otherwise.
Context
(trusted events)
  • InputEvent.data: the string containing the data that was added to the element, which MAY be null if it doesn't apply.
  • InputEvent.dataTransfer: richtext data added or removed from element, which MAY be null if it doesn't apply.
  • InputEvent.getTargetRanges(): returns an arrays of Static Cranges which will be affected by the change to the DOM if it is not canceled.

A user agent MUST dispatch [UI-EVENTS] this event when the user has attempted to input in a contenteditable element. It does not necessarily mean the user agent [ UI-EVENTS] will then update the DOM.

A user agent MUST NOT dispatch [UI-EVENTS] this event due to events that are not caused by attempted user input, such as system events.

input
Type input
Interface InputEvent
Sync / Async Sync
Bubbles Yes
Trusted Targets Any Element with contenteditable attribute enabled.
Default action [UI-EVENTS] None
Context
(trusted events)
  • InputEvent.data: the string containing the data that was added to the element, which MAY be null if it doesn't apply.
  • InputEvent.dataTransfer: richtext data added or removed from element, which MAY be null if it doesn't apply.

A user agent MUST dispatch [UI-EVENTS] this event immediately after the DOM has been updated due to a user expressed intention to change the document contents which the browser has handled.

5.3 Acknowledgements

Thanks to: Michael Aufreiter, Adrian Bateman, Oliver Buchtala, Robin Berjon, Enrica Casucci, Domenic Denicola, Olivier Forget, Aryeh Gregor, Marijn Haverbeke, Yoshifumi Inoue, Koji Ishii, Gary Kacmarcik, Frederico Caldeira Knabben, Takayoshi Kochi, Piotrek Koszuliński, Travis Leithead, Grisha Lyukshin, Chaals McCathie Nevile, Masayuki Nakano, Ryosuke Niwa, Julie Parent, Ben Peters, Florian Rivoal, Morgan Smith, Hallvord R. M. Steen, Johan Sörlin, Cristian Talau, Dave Tapuska, Ojan Vafai, Léonie Watson, Xiaoqian Wu, Chong Zhang, Joanmarie, and everyone in the Editing Taskforce for their input and feedback.

A. References

A.1 Normative references

[DATA-TRANSFER]
WHATWG. The DataTransfer interface. URL: https://html.spec.whatwg.org/multipage/interaction.html#the-datatransfer-interface
[HTML-LIVING]
WHATWG. HTML Living Standard. URL: https://html.spec.whatwg.org/multipage/interaction.html
[STATIC-RANGE]
Gary Kačmarčík. W3C. [Proposal] StaticRange (to be used instead of Range for new APIs). unofficial. URL: https://discourse.wicg.io/t/proposal-staticrange-to-be-used-instead-of-range-for-new-apis/1472
[UI-EVENTS]
Gary Kacmarcik; Travis Leithead. W3C. UI Events. 4 August 2016. W3C Working Draft. URL: https://www.w3.org/TR/uievents/