This behavior is in active design now - information on this page will be updated/modified. ====== behavior: richtext ====== WYSIWYG editing behavior. It allows to edit HTML and/or wiki text in WYSIWYG manner. The //richtext// is aimed to be used as: * blog (article) editors; * wiki and other forms of CMS; * online e-mail clients; The //richtext// uses so called //flat DOM// that is: - no nested ''
''s; - ''
  • '' is a kind of ''

    '' - can contain only text and spans; - no nested tables; - only two levels of spans are allowed - so called //background// (e.g. '''') and foreground ('''', '''', etc.) spans; - there are no elements inside the editor; - limited support of CSS, e.g. no //position// attribute at all. Screenshot of the sample below: {{h-smile:built-in-behaviors:richtext.jpg|Screenshot}} One more screenshot, [[h-smile:built-in-behaviors:richtext-rules|"show rulers" mode]]: {{h-smile:built-in-behaviors:rictext-tables.jpg|richtext with rules}} Floating image: {{h-smile:built-in-behaviors:richtext-img.jpg|floating image}} ===== Elements ===== that have this behavior applied by default (see [[master style sheet]]): * '' ..initial html.. '' - //richtext// is intrinsically dispaly:block element. ===== Value ===== ''get/set_value'' methods (htmlayout) and ''value'' property (sciter) reflect current editing document and can be either HTML text or wiki (dokuwiki by default) format. Editor allow images to be inserted from system clipboard so the ''value'' may contain image bits as base64 encoded chunks. Exact format will be specified later. ===== Attributes ===== that this behavior knows about: * ''tools="css selector"'' - CSS selector of the element containing tool buttons/elements. See below. * ''content-style="url"'' - url of style sheet that that defines list of elements supported by the instance of the editor and their styles. * ''allow-clipboard-images[=yes|no]'' - allows images to be inserted (pasted) from clipboard. If allowed and document contains pasted images (that have no permanent location) then bodies of such images will be emitted as: elements inside the '''' section of the document. ===== Events ===== Together with the standard set of events (mouse, keyboard, focus) //behavior: button// generates: * UI_STATE_CHANED event - is sent after state of editing regiters is changed. Internal implementation updates state of bound tool buttons. Posted (asynchronous) event. * EDIT_VALUE_CHANGED event - value of the element was changed due to user actions. Is sent when document was updated by the user first time from intital value. Or when document is rolled back to initial state (by using undo). Posted (asynchronous) event. * EDIT_VALUE_CHANGING event - sent when value of the element is about to change. Synchronous event. * PARSE_VALUE and EMIT_VALUE - events that allow to override default value parser and value emitter. * BEFORE_PASTE and AFTER_PASTE events. (planned but not supported for now) * BEFORE_COPY and AFTER_COPY events. (planned but not supported for now) ===== Methods ===== Richtext supports following so called ''xcall()'' methods, see dom::element::xcall() function. ==== Basic operations and state indicators: ==== * ''xcall("canUndo"): bool'' - returns boolean wrapped into ''json::value'', ''true'' - if //undo// is available and ''false'' if not; * ''xcall("doUndo")'' - executes undo operation; * ''xcall("canRedo"): bool'' - returns ''true'' - if //redo// is available and ''false'' if not; * ''xcall("doRedo")'' - executes redo operation; * ''xcall("canCut"): bool'' - returns ''true'' - if //cut// is available and ''false'' if not; * ''xcall("doCut")'' - executes cut operation - copy selection into the clipboard and deletes selected text; * ''xcall("canCopy"): bool'' - returns ''true'' - if //copy// is available and ''false'' if not; * ''xcall("doCopy")'' - executes copy operation - copy selection into the clipboard; * ''xcall("canPaste"): bool'' - returns ''true'' - if //paste// is available and ''false'' if not; * ''xcall("doPaste")'' - executes paste operation - pastes content of the the clipboard; * ''xcall("canSelectAll"): bool'' - returns ''true'' - if //select all[text]// is available in current state and ''false'' if not; * ''xcall("doSelectAll")'' - selects all text; * ''xcall("readOnly"): bool'' - returns ''true'' - if editor is in read-only mode; * ''xcall("readOnly", bool)'' - switches readOnly mode on and off; * ''xcall("showRulers",bool)'' - show/hide formatting rulers; ==== Load/Save, HTML or envelope ==== * ''xcall("loadHTML", html:string)'' - replaces current content from html string; * ''xcall("loadHTML", html:string, base_url:string)'' - replaces current content from html string, uses base_url for resolution of relative urls; * ''xcall("saveHTML") : string'' - returns current content as html string; * ''xcall("saveHTML", baseUrl:string, mode:string ) : string'' - returns current content as html string; ''mode'' here accepts following values: * ''"emit-pasted-images"'' - emit also bodies of images that was pasted from clipboard; * ''"emit-local-images"'' - emit bodies of clipboard and images with urls starting from ''file:''; * ''"emit-all-images"'' - emit bodies of all images used in the document. * ''xcall("savePlainText") : string'' - returns current content as plain text string; * ''xcall("loadFile", path:string)'' - replaces current content from html file given by the //path//; * ''xcall("saveFile", path:string)'' - saves current content to the file given by the //path//; * ''xcall("saveContent"):map'' - saves current document as an object having following structure: { "html": html-string, "resources": { "url1": { data: bytes | string, // data of the resource content-type: string, // mime type of the resource content-disposition: string, // url where this resource came from id: string // uuid of the resource } ... } } * ''xcall("loadContent", envelope:map)'' - replaces current content from the //envelope// object having structure d efined above; ==== Navigation: ==== * ''xcall("moveCaretTo", where:string, keepAnchor:true|false)'' - moves the caret from current position to //where//: * ''"next-char"'' - next character; * ''"prev-char"'' - previous character; * ''"next-word"'' - start of next word; * ''"prev-word"'' - end of previous word; * ''"doc-end"'' - end of the doc; * ''"doc-start"'' - start of the doc; * ''"line-end"'' - end of the line; * ''"line-start"'' - start of the line; * ''"line-up"'' - character in the previous line; * ''"line-down"'' - character in the next line; * ''"page-up"'' - previous page; * ''"page-down"'' - next page; If ''keepAnchor'' is ''true'' then this function is not changing anchor position of the selection. So this sequence ''moveCaretTo(line-end,false); moveCaretTo(line-end,true);'' will set selection on current line of text. * ''xcall("searchNext",modes:int, word:string)'' - search next word entry in the text, modes is an integer - ORed combination of these flags: * ''SEARCH_FORWARD = 0x00,'' * ''SEARCH_BACKWARD = 0x01,'' * ''SEARCH_WHOLE_WORD = 0x10,'' * ''SEARCH_MATCH_CASE = 0x20 '' ==== Edit operations and formatting: ==== * ''xcall("insertHtml", string)'' - does insertion of html fragment contained in the string at current caret position; * ''xcall("appendHtml", string)'' - appends the html fragment to the end of the document; * ''xcall("replaceBy", text:string)'' - replaces current selection by the text, if there is no selection then inserts the text at caret position. * ''xcall("getCurrentObjects"): array'' - returns array of "tagname.classname" strings - stack of current objects at the caret position; * ''xcall("getCurrentObjectAttributes", index:int): map'' - returns collection of attributes defined on element at //index// position in stack of current objects; * ''xcall("setCurrentObjectAttributes", index:int, attributes: map)'' - sets attributes of element at //index// position in stack of current objects; * ''xcall("getCurrentStyle"): map'' - returns cumulative collection of CSS properties in effect at current caret position; * ''xcall("getStyleRules"): array'' - returns list of CSS rules applied at current position; * ''xcall("getStyleRule", index:int): map'' - returns list of CSS properties of particular rule applied at current position; * ''xcall("setSpan",tag:string, attributes: undefined | map)'' - set span to the selection or caret position. Spans are ''b'',''strong'', ''em'', ''a'', etc. * ''xcall("setBlock", tag:string, attributes: undefined | map)'' - set block to the selection or to current block element. ''tag'' here can accept following values: "p","h1"..."h6", "pre" or two pseudo tags "ol/li" and "ul/li" for list items. * ''xcall("setFontColor", color:string | color)'' - set current color of the text by injecting '''' span; * ''xcall("setFontName", fontFamilyName:string)'' - set current font name by injecting '''' span; * ''xcall("setFontSize", fontSize:1..7)'' - set current font size by injecting '''' span; * ''xcall("toggleSpan", tagName:string)'' - switches on/off bold/italic/underline spans by adding/removing correspondent tags; * ''xcall("canIndentPlus"): undefined | bool'' - returns ''true'' or ''false'' if editor can or cannot apply indentation+. Will return ''undefined'' if context does not support indentation (e.g. inside ''pre''). * ''xcall("doIndentPlus")'' - increases indentation; * ''xcall("canIndentMinus"): undefined | bool'' - returns ''true'' or ''false'' if editor can or cannot apply indentation-. Will return ''undefined'' if context does not support indentation (e.g. inside ''pre''). * ''xcall("doIndentMinus")'' - decreases indentation; * ''xcall("setTextAlign", align:int)'' - sets text alignment, //align// here is one of: * ''ALIGN_LEFT = 1,'' * ''ALIGN_CENTER = 2,'' * ''ALIGN_RIGHT = 3,'' * ''ALIGN_JUSTIFY = 4,'' * ''xcall("setListUnordered")'' - wraps selection into ''