docs
Loading...
Searching...
No Matches
CAPI_Editor.h

Overview

Text-editing interface for a View.

#include <Ultralight/CAPI/CAPI_Editor.h>

The C editor functions run editing commands and manage composition state for the focused element in a View.

Standard keyboard shortcuts like Ctrl+C and Ctrl+V run automatically when you dispatch key events to a View. You use the editor functions to connect native controls like Edit menus and on-screen keyboards directly to the page, or to relay text from an OS input method.

This example updates native Edit menu items before display and runs the command the user picks:

static void UpdateEditMenu(void) {
ULEditor editor = ulViewGetEditor(view);
SetMenuItemEnabled("Cut", ulEditorCanExecute(editor, kEditorCommand_Cut));
SetMenuItemEnabled("Copy", ulEditorCanExecute(editor, kEditorCommand_Copy));
SetMenuItemEnabled("Paste", ulEditorCanExecute(editor, kEditorCommand_Paste));
}
static void OnEditMenuCommand(ULEditorCommand command) {
}
bool ulEditorExecute(ULEditor editor, ULEditorCommand command)
Run an editing command.
ULEditor ulViewGetEditor(ULView view)
Get the editor for a View.
ULEditorCommand
The editing commands you can run with ulEditorExecute().
Definition CAPI_Editor.h:108
@ kEditorCommand_Cut
Cut the selection to the clipboard.
Definition CAPI_Editor.h:110
@ kEditorCommand_Copy
Copy the selection to the clipboard.
Definition CAPI_Editor.h:111
@ kEditorCommand_Paste
Paste the clipboard's contents.
Definition CAPI_Editor.h:112
bool ulEditorCanExecute(ULEditor editor, ULEditorCommand command)
Whether or not a command would do anything right now.
struct C_Editor * ULEditor
Opaque handle to a View's Editor object.
Definition CAPI_Defines.h:90

The Editor Handle

Call ulViewGetEditor() with a ULView handle to obtain its editor. The returned ULEditor is borrowed (it's never NULL), so you don't destroy it yourself. It belongs to the handle you passed and stays valid until you destroy that handle with ulDestroyView().

Input Methods on Hosted Views

When you host a View directly, register the editing callbacks in <Ultralight/CAPI/CAPI_View.h> to coordinate an OS input method with the page:

For the complete input method lifecycle and candidate window placement rules, see <Ultralight/Editor.h>.

When styling composition clauses for ulEditorSetComposition(), zero-initialize each ULCompositionSegment struct. A zero-initialized ULColor represents an unset color.

This function updates the in-progress composition text and styles the active clause with a thick underline:

// Offsets are in UTF-16 code units.
static void OnCompositionUpdate(ULString text, unsigned int text_length,
unsigned int caret) {
ULCompositionSegment clause = {0}; // colors left unset
clause.range.end = text_length;
clause.thick = true;
ULCompositionRange selection = {caret, caret};
ulEditorSetComposition(ulViewGetEditor(view), text, &clause, 1, selection);
}
bool ulEditorSetComposition(ULEditor editor, ULString text, const ULCompositionSegment *segments, size_t num_segments, ULCompositionRange selection)
Set or update the in-progress text of an input method's composition.
struct C_String * ULString
Opaque handle to a String object.
Definition CAPI_Defines.h:96
A range of a composition's text, in UTF-16 code units (see ulEditorSetComposition()).
Definition CAPI_Editor.h:238
unsigned int end
The ending offset of the range (exclusive), in UTF-16 code units.
Definition CAPI_Editor.h:247
Underline style for part of a composition's text (see ulEditorSetComposition()).
Definition CAPI_Editor.h:258
ULCompositionRange range
The range of composition text this segment styles.
Definition CAPI_Editor.h:262
bool thick
Whether the underline is drawn thick (the convention for the active clause).
Definition CAPI_Editor.h:277
Note
AppCore panel Views already set the editing callbacks to run the window's input method. Setting an editing callback on a panel's View replaces AppCore's callback and turns off input method support for that View.
See also
<Ultralight/Editor.h>, ulViewGetEditor(), ulViewSetChangeEditableStateCallback(), ULEditableState, ULEditorCommand

Classes

struct  ULCompositionRange
 A range of a composition's text, in UTF-16 code units (see ulEditorSetComposition()). More...
struct  ULCompositionSegment
 Underline style for part of a composition's text (see ulEditorSetComposition()). More...
struct  ULEditableState
 The conditions that decide whether an input method should be active. More...

Functions

ULEditor ulViewGetEditor (ULView view)
 Get the editor for a View.
bool ulEditorExecute (ULEditor editor, ULEditorCommand command)
 Run an editing command.
bool ulEditorCanExecute (ULEditor editor, ULEditorCommand command)
 Whether or not a command would do anything right now.
bool ulEditorInsertText (ULEditor editor, ULString text)
 Insert text at the caret, replacing the selection (the same as typing it).
ULRect ulEditorGetCaretBounds (ULEditor editor)
 Get the bounds of the caret.
bool ulEditorSetComposition (ULEditor editor, ULString text, const ULCompositionSegment *segments, size_t num_segments, ULCompositionRange selection)
 Set or update the in-progress text of an input method's composition.
bool ulEditorCommitComposition (ULEditor editor, ULString text)
 Replace the active composition with the input method's final text.
bool ulEditorFinishComposition (ULEditor editor)
 Keep the active composition's in-progress text as final text.
bool ulEditorCancelComposition (ULEditor editor)
 Cancel the active composition and remove its text.
bool ulEditorHasComposition (ULEditor editor)
 Whether or not a composition is active.
ULRect ulEditorGetCompositionBounds (ULEditor editor)
 Get the bounds of the active composition's text, in viewport CSS pixels.
unsigned int ulEditorGetCompositionCharacterCount (ULEditor editor)
 Get the length of the active composition's text, in UTF-16 code units.
ULRect ulEditorGetCompositionCharacterBounds (ULEditor editor, unsigned int index)
 Get the bounds of one character of the active composition's text, in viewport CSS pixels.
bool ulEditorGetSelectionOffsets (ULEditor editor, unsigned int *start, unsigned int *end)
 Get the selection's offsets within the focused element's text.
ULString ulEditorGetTextInRange (ULEditor editor, unsigned int start, unsigned int end)
 Get part of the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).
bool ulEditorReplaceTextInRange (ULEditor editor, unsigned int start, unsigned int end, ULString text)
 Replace part of the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).
bool ulEditorGetCompositionOffsets (ULEditor editor, unsigned int *start, unsigned int *end)
 Get the active composition's offsets within the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).

Enumerations

enum  ULEditorCommand {
  kEditorCommand_Cut = 0 , kEditorCommand_Copy , kEditorCommand_Paste , kEditorCommand_PasteAsPlainText ,
  kEditorCommand_SelectAll , kEditorCommand_Undo , kEditorCommand_Redo , kEditorCommand_MoveLeft ,
  kEditorCommand_MoveRight , kEditorCommand_MoveUp , kEditorCommand_MoveDown , kEditorCommand_MoveWordLeft ,
  kEditorCommand_MoveWordRight , kEditorCommand_MoveToBeginningOfLine , kEditorCommand_MoveToEndOfLine , kEditorCommand_MoveToBeginningOfParagraph ,
  kEditorCommand_MoveToEndOfParagraph , kEditorCommand_MoveToBeginningOfDocument , kEditorCommand_MoveToEndOfDocument , kEditorCommand_MovePageUp ,
  kEditorCommand_MovePageDown , kEditorCommand_MoveLeftAndModifySelection , kEditorCommand_MoveRightAndModifySelection , kEditorCommand_MoveUpAndModifySelection ,
  kEditorCommand_MoveDownAndModifySelection , kEditorCommand_MoveWordLeftAndModifySelection , kEditorCommand_MoveWordRightAndModifySelection , kEditorCommand_MoveToBeginningOfLineAndModifySelection ,
  kEditorCommand_MoveToEndOfLineAndModifySelection , kEditorCommand_MoveToBeginningOfParagraphAndModifySelection , kEditorCommand_MoveToEndOfParagraphAndModifySelection , kEditorCommand_MoveToBeginningOfDocumentAndModifySelection ,
  kEditorCommand_MoveToEndOfDocumentAndModifySelection , kEditorCommand_MovePageUpAndModifySelection , kEditorCommand_MovePageDownAndModifySelection , kEditorCommand_SelectWord ,
  kEditorCommand_SelectLine , kEditorCommand_SelectParagraph , kEditorCommand_Unselect , kEditorCommand_DeleteBackward ,
  kEditorCommand_DeleteForward , kEditorCommand_DeleteWordBackward , kEditorCommand_DeleteWordForward , kEditorCommand_DeleteToBeginningOfLine ,
  kEditorCommand_DeleteToEndOfLine , kEditorCommand_InsertNewline , kEditorCommand_InsertLineBreak , kEditorCommand_InsertTab ,
  kEditorCommand_InsertBacktab
}
 The editing commands you can run with ulEditorExecute(). More...
enum  ULEditableType {
  kEditableType_None = 0 , kEditableType_Text , kEditableType_Password , kEditableType_TextArea ,
  kEditableType_ContentEditable , kEditableType_Other
}
 The kind of element that holds keyboard focus (see ULEditableState). More...
enum  ULInputMode {
  kInputMode_Unspecified = 0 , kInputMode_None , kInputMode_Text , kInputMode_Telephone ,
  kInputMode_Url , kInputMode_Email , kInputMode_Numeric , kInputMode_Decimal ,
  kInputMode_Search
}
 The focused element's inputmode hint (what kind of virtual keyboard the page asks for). More...
enum  ULEnterKeyHint {
  kEnterKeyHint_Unspecified = 0 , kEnterKeyHint_Enter , kEnterKeyHint_Done , kEnterKeyHint_Go ,
  kEnterKeyHint_Next , kEnterKeyHint_Previous , kEnterKeyHint_Search , kEnterKeyHint_Send
}
 The focused element's enterkeyhint (what label or icon the Enter key should present). More...

Function Documentation

◆ ulEditorCancelComposition()

bool ulEditorCancelComposition ( ULEditor editor)

Cancel the active composition and remove its text.

Parameters
editorThe editor.
Returns
Returns whether a composition was cancelled (false when none was active).

◆ ulEditorCanExecute()

bool ulEditorCanExecute ( ULEditor editor,
ULEditorCommand command )

Whether or not a command would do anything right now.

You can use this to grey out items in a native menu.

Parameters
editorThe editor.
commandThe command to check.
Returns
Returns true if ulEditorExecute() would run the command.

◆ ulEditorCommitComposition()

bool ulEditorCommitComposition ( ULEditor editor,
ULString text )

Replace the active composition with the input method's final text.

With no active composition, this inserts text at the caret.

Parameters
editorThe editor.
textThe final text.
Returns
Returns whether the text was inserted (false when there's no editable text).

◆ ulEditorExecute()

bool ulEditorExecute ( ULEditor editor,
ULEditorCommand command )

Run an editing command.

Parameters
editorThe editor.
commandThe command to run.
Returns
Returns whether the command ran (false whenever ulEditorCanExecute() would return false).

◆ ulEditorFinishComposition()

bool ulEditorFinishComposition ( ULEditor editor)

Keep the active composition's in-progress text as final text.

Call this when the input method closes without committing or cancelling (eg, focus moves away mid-composition).

Parameters
editorThe editor.
Returns
Returns whether a composition was finished (false when none was active).

◆ ulEditorGetCaretBounds()

ULRect ulEditorGetCaretBounds ( ULEditor editor)

Get the bounds of the caret.

The rect is in viewport CSS pixels (the same space as ulViewFireMouseEvent()). Multiply by ulViewGetDeviceScale() for device pixels.

Parameters
editorThe editor.
Returns
Returns the caret bounds (an empty rect when there's no caret in editable text).
Note
This updates any pending layout first– query it when you need it (eg, when opening a menu) rather than every frame.

◆ ulEditorGetCompositionBounds()

ULRect ulEditorGetCompositionBounds ( ULEditor editor)

Get the bounds of the active composition's text, in viewport CSS pixels.

You can use this as the area a candidate window shouldn't cover.

Parameters
editorThe editor.
Returns
Returns the bounds (all-zero when no composition is active).

◆ ulEditorGetCompositionCharacterBounds()

ULRect ulEditorGetCompositionCharacterBounds ( ULEditor editor,
unsigned int index )

Get the bounds of one character of the active composition's text, in viewport CSS pixels.

You can use this to place a candidate window. Anchor it on the composition's first character (index 0) so it doesn't move as the candidates change.

Parameters
editorThe editor.
indexThe character's offset within the composition's text, in UTF-16 code units.
Returns
Returns the character's bounds (all-zero when index is out of range or no composition is active).

◆ ulEditorGetCompositionCharacterCount()

unsigned int ulEditorGetCompositionCharacterCount ( ULEditor editor)

Get the length of the active composition's text, in UTF-16 code units.

Parameters
editorThe editor.
Returns
Returns the length (0 when no composition is active).

◆ ulEditorGetCompositionOffsets()

bool ulEditorGetCompositionOffsets ( ULEditor editor,
unsigned int * start,
unsigned int * end )

Get the active composition's offsets within the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).

You can use this to report the input method's marked range.

Parameters
editorThe editor.
startSet to the composition's start.
endSet to the composition's end (exclusive).
Returns
Returns whether the offsets were set (false when no composition is active in the focused element).

◆ ulEditorGetSelectionOffsets()

bool ulEditorGetSelectionOffsets ( ULEditor editor,
unsigned int * start,
unsigned int * end )

Get the selection's offsets within the focused element's text.

The offset functions (this, ulEditorGetTextInRange(), ulEditorReplaceTextInRange(), and ulEditorGetCompositionOffsets()) use UTF-16 code units into the text of the focused text field or editable region. For <input> and <textarea>, they match the element's selectionStart and selectionEnd.

Parameters
editorThe editor.
startSet to the selection's start.
endSet to the selection's end (the same as start for a caret).
Returns
Returns whether the offsets were set (false when the focused element isn't editable text, or the selection is outside it).

◆ ulEditorGetTextInRange()

ULString ulEditorGetTextInRange ( ULEditor editor,
unsigned int start,
unsigned int end )

Get part of the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).

Offsets past the end of the text are clamped to it.

Parameters
editorThe editor.
startThe start offset.
endThe end offset (exclusive).
Returns
Returns a new string with the text in the range (empty when the focused element isn't editable text). You must call ulDestroyString() when finished.
Warning
This reads password fields too, so treat the result as sensitive.

◆ ulEditorHasComposition()

bool ulEditorHasComposition ( ULEditor editor)

Whether or not a composition is active.

Parameters
editorThe editor.
Returns
Returns true if a composition is active.

◆ ulEditorInsertText()

bool ulEditorInsertText ( ULEditor editor,
ULString text )

Insert text at the caret, replacing the selection (the same as typing it).

Parameters
editorThe editor.
textThe text to insert.
Returns
Returns whether the text was inserted (false when there's no editable text to insert into).

◆ ulEditorReplaceTextInRange()

bool ulEditorReplaceTextInRange ( ULEditor editor,
unsigned int start,
unsigned int end,
ULString text )

Replace part of the focused element's text (see ulEditorGetSelectionOffsets() for the offsets).

This edits the same way typing does. The edit is one undo step, and the caret ends up after the new text. You can use this for an input method's replacement ranges (eg, the macOS accent picker replaces the character it targets).

Offsets past the end of the text are clamped to it.

Parameters
editorThe editor.
startThe start offset.
endThe end offset (exclusive).
textThe new text (an empty string deletes the range).
Returns
Returns whether the text was replaced (false when the focused element isn't editable text, or start is greater than end).
Note
An active composition is cancelled first, and the offsets apply to the text left after that.

◆ ulEditorSetComposition()

bool ulEditorSetComposition ( ULEditor editor,
ULString text,
const ULCompositionSegment * segments,
size_t num_segments,
ULCompositionRange selection )

Set or update the in-progress text of an input method's composition.

The first call starts a composition and replaces the selection. Later calls replace the previous in-progress text.

Parameters
editorThe editor.
textThe full in-progress text. Pass an empty string to remove it (the same as ulEditorCancelComposition()).
segmentsUnderline styles for parts of the text (eg, one per clause). Pass NULL to underline all of it.
num_segmentsThe number of entries in segments.
selectionThe caret or selection within text, in UTF-16 code units.
Returns
Returns whether the composition was applied (false when there's no editable text).
Note
During a composition, the page gets the standard composition events. Every keydown reports key code 229 (the same as in a browser).

◆ ulViewGetEditor()

ULEditor ulViewGetEditor ( ULView view)

Get the editor for a View.

Parameters
viewThe View.
Returns
Returns the View's editor (this is never NULL).
Note
Don't destroy the returned handle, it is owned by view and stays valid until you call ulDestroyView() on it.

Enumeration Type Documentation

◆ ULEditableType

The kind of element that holds keyboard focus (see ULEditableState).

Enumerator
kEditableType_None 

No element holds keyboard focus.

kEditableType_Text 

A single-line text field.

kEditableType_Password 

A password field.

kEditableType_TextArea 

A multi-line text area.

kEditableType_ContentEditable 

An editable (contenteditable) region.

kEditableType_Other 

A focused element that is not a text-editing target.

◆ ULEditorCommand

The editing commands you can run with ulEditorExecute().

Most commands act on editable text (a text field or an editable region). Copy, SelectAll, and the selection commands (the AndModifySelection forms, SelectWord, SelectLine, SelectParagraph, and Unselect) also work on a selection in regular page content.

Every caret motion has an AndModifySelection form that extends the selection instead of moving the caret (the Shift-key behavior).

Enumerator
kEditorCommand_Cut 

Cut the selection to the clipboard.

kEditorCommand_Copy 

Copy the selection to the clipboard.

kEditorCommand_Paste 

Paste the clipboard's contents.

kEditorCommand_PasteAsPlainText 

Paste the clipboard's text without its formatting.

kEditorCommand_SelectAll 

Select all the text (or the whole page).

kEditorCommand_Undo 

Undo the last edit.

kEditorCommand_Redo 

Redo the last undone edit.

kEditorCommand_MoveLeft 

Move the caret one character left.

kEditorCommand_MoveRight 

Move the caret one character right.

kEditorCommand_MoveUp 

Move the caret one line up.

kEditorCommand_MoveDown 

Move the caret one line down.

kEditorCommand_MoveWordLeft 

Move the caret one word left.

kEditorCommand_MoveWordRight 

Move the caret one word right.

kEditorCommand_MoveToBeginningOfLine 

Move the caret to the start of the line.

kEditorCommand_MoveToEndOfLine 

Move the caret to the end of the line.

kEditorCommand_MoveToBeginningOfParagraph 

Move the caret to the start of the paragraph.

kEditorCommand_MoveToEndOfParagraph 

Move the caret to the end of the paragraph.

kEditorCommand_MoveToBeginningOfDocument 

Move the caret to the start of the text.

kEditorCommand_MoveToEndOfDocument 

Move the caret to the end of the text.

kEditorCommand_MovePageUp 

Move the caret one page up.

kEditorCommand_MovePageDown 

Move the caret one page down.

kEditorCommand_MoveLeftAndModifySelection 

Select one character left.

kEditorCommand_MoveRightAndModifySelection 

Select one character right.

kEditorCommand_MoveUpAndModifySelection 

Select one line up.

kEditorCommand_MoveDownAndModifySelection 

Select one line down.

kEditorCommand_MoveWordLeftAndModifySelection 

Select one word left.

kEditorCommand_MoveWordRightAndModifySelection 

Select one word right.

kEditorCommand_MoveToBeginningOfLineAndModifySelection 

Select to line start.

kEditorCommand_MoveToEndOfLineAndModifySelection 

Select to line end.

kEditorCommand_MoveToBeginningOfParagraphAndModifySelection 

Select to paragraph start.

kEditorCommand_MoveToEndOfParagraphAndModifySelection 

Select to paragraph end.

kEditorCommand_MoveToBeginningOfDocumentAndModifySelection 

Select to text start.

kEditorCommand_MoveToEndOfDocumentAndModifySelection 

Select to text end.

kEditorCommand_MovePageUpAndModifySelection 

Select one page up.

kEditorCommand_MovePageDownAndModifySelection 

Select one page down.

kEditorCommand_SelectWord 

Select the word at the caret.

kEditorCommand_SelectLine 

Select the line at the caret.

kEditorCommand_SelectParagraph 

Select the paragraph at the caret.

kEditorCommand_Unselect 

Clear the selection (no caret remains).

kEditorCommand_DeleteBackward 

Delete the selection or the previous character.

kEditorCommand_DeleteForward 

Delete the selection or the next character.

kEditorCommand_DeleteWordBackward 

Delete the word before the caret.

kEditorCommand_DeleteWordForward 

Delete the word after the caret.

kEditorCommand_DeleteToBeginningOfLine 

Delete to the start of the line.

kEditorCommand_DeleteToEndOfLine 

Delete to the end of the line.

kEditorCommand_InsertNewline 

Insert a new paragraph (the Enter key).

kEditorCommand_InsertLineBreak 

Insert a line break in the paragraph (Shift+Enter).

kEditorCommand_InsertTab 

Insert a tab.

kEditorCommand_InsertBacktab 

Insert a backtab (Shift+Tab).

◆ ULEnterKeyHint

The focused element's enterkeyhint (what label or icon the Enter key should present).

Enumerator
kEnterKeyHint_Unspecified 
kEnterKeyHint_Enter 
kEnterKeyHint_Done 
kEnterKeyHint_Go 
kEnterKeyHint_Next 
kEnterKeyHint_Previous 
kEnterKeyHint_Search 
kEnterKeyHint_Send 

◆ ULInputMode

The focused element's inputmode hint (what kind of virtual keyboard the page asks for).

Enumerator
kInputMode_Unspecified 
kInputMode_None 
kInputMode_Text 
kInputMode_Telephone 
kInputMode_Url 
kInputMode_Email 
kInputMode_Numeric 
kInputMode_Decimal 
kInputMode_Search 

Go to the source code of this file.