You are here: Editor project page > Composer List Editing Rules
Composer List Editing Rules
- The most common action used to start, remove, or change a list is to Click on Toolbar button for Bulleted or Numbered list: . The resulting actions, as detailed below, apply only to the selected list items.
Select from the menu: Format | List... to bring up the List Properties
- The list type (Numbered, Bulleted, or Definition list) may be selected, or use "none" to remove an existing list.
- List attributes such as bullet style, number style, and starting number can be set here.
- The notable difference between using the dialog and the toolbar is that the settings apply to the entire list, not just the selected list item(s). For more advanced users, supporting this different behavior confers additional flexibility. This also simplifies the rules logic when working with Definition (DL) lists. Since we don't support DL lists on the toolbar, but only via the dialog, changing from OL/UL lists to DL lists and vice versa is greatly simplified for the user (and the rules code!)
A new list item can be created using just the keyboard:
- Pressing Enter/Return when caret is in a list item splits the item at the caret (if not at end of line) and creates a new list item of the same type at the same indent level.
- If list item contains no content, as after Enter/Return is used at the end of an existing item, pressing enter again will outdent or remove one level. If at the first level, this terminates the list. Thus successive presses of Enter/Return at any list level is a quick keyboard way to terminate a list.
We would like to have a key combination that would allow creating a new
list item at the next indented level. A proposal to use Ctrl+Enter (Cmd+Return on Mac) conflicts with that key's usage in Mail
Composer for "Send Message". Possible solutions:
- Have a Composer preference that changes the default keybinding for Ctrl+Enter. This must replace its usage for Send Message. That is, I think it would be too confusing to allow Ctrl+Enter only in Web Composer.
- Find another key binding. Note that we can't use Shift+Enter (that is "insert break", or "new paragraph at same list indent level") or Alt+Enter (that is Window's specific equivalent to "edit properties" of selected object or object at caret.)
- Have no specific key binding and only support the usual indent UI to push a new list item in one level. That is done by using the indent toolbar button or the Ctrl+= (Cmd+= on Mac) key binding.
Selection and Toolbar Usage Rules
In this document, we use a red vertical bar |
indicate a caret (collapsed selection) and red square brackets [around
text to indicate a selection range.]
For the purpose of creating or modifying lists, list items, and their attributes, a list item is "selected" when any part of the normal text or object selection is within the tag boundaries. This rule is also used for other "block" or "paragraph" container elements, such as P, DIV, H1, H2, etc. We also consider a BR tag to mark a "block" boundary (at least in the Mail Composer Rules. This may change in Web Composer rules if we use only P and DIV to define paragraphs.)
As with the Bold, Italic, and Underline text style buttons, the state of the list buttons tells the user about the selection and what action will occur when they click on the button.
The general rule is: A button is shown depressed when the entire selection is within a single list type. This includes the case of the collapsed selection -- just a caret in the page. This only applies to the most immediate list above the selected list items. If the selection is within a bulleted list, but that list is a child of a numbered list, we don't consider that numbered list to be set. Otherwise, complicated lists with multiple levels woud become very confusing for both the user and the code! Thus either one or the other list button can be shown depressed for any selection:
The general rules for what happens when you click on a list toolbar button:
- Clicking on a non-depressed button:
- For selected paragraphs that are not list items, make each paragraph a
If the selection includes existing list items, the new items are merged into the adjacent list, else a new list is created. If there is an adjacent list both before and after a paragraph, merge with the one before.
The definition of "adjacent" may be tricky: In its simplest form, a list is adjacent to another block if they are siblings of the same parent. Intervening <br> might be a problem, depending on other block rules. If a <br> is used to define a block, then the contents between each should be a separate list item; if there are no contents, then we should not create a list item for those.
- For selected list items whose parent list type is different than the toolbar
button type, remove the selected list items from the list and:
- If all child items have been removed from the list node, delete that list (and all parent nodes used for indenting that are now childless.)
- If there is no list of the desired type adjacent to the removed items, create a new parent list.
- If there is an adjacent list of the desired type, merge into that list by inserting before or after existing siblings, depending on which side the adjacent list is found. This may still require new list nodes because we should also:
- Create extra list nodes if needed to keep the moved list items at the same indent level as before the move.
- For selected list items whose parent is the same list type as the toolbar button type, do nothing.
- For selected paragraphs that are not list items, make each paragraph a list item.
- Clicking on a depressed button should remove all selected items from the
Should we try to retain the existing indent level(s) as we do when changing
list type? This could get very complicated to do and is not recommended
in this specification.
As shown in the examples below, I think it would be better to not replace indenting that was caused by list level with some other type of indenting, thus all list items removed become "flattened" to the same level.
Should we simply remove the content's parent LI nodes or replace them
with "normal" containers (e.g., P or DIV)?
They should become "normal", whatever that means. For example: it may be text separated by <br> in the case of Mail Composer, or within <p> or <div> if those are the rules for Web Composer.
- Should we try to retain the existing indent level(s) as we do when changing list type? This could get very complicated to do and is not recommended in this specification.
- When the selection spans existing text and/or objects, these should still be selected after the enclosing list item(s) are created or removed.
Here are some specific examples. Note that the "Click on" rules are not meant to imply different behavior for each list type, but rather what happens when the button clicked is the same or different type as in the selection. These examples are only for OL and UL lists, which share the HTML rule of requiring LI children. The added complication of switch to/from the DL list type is discussed below.
|A. Caret on a blank line:
|B. One paragraph selected:
This [is a paragraph.]
|C. More than one paragraph selected:
This [is a paragraph.
D. One list item selected in one list:
|Change selected item's list type
(creates new list):
|Remove selected item
|E. One list item selected in a sublist of a different type:
||Change selected item's list type
(creates new list):
|Remove selected item
|F. All list items selected in one list:
||Change list type
(creates new list):
|Remove all items
from list (deletes list):
|G. Two items selected in one list, one item in 2nd list (sublist).
Two lists are selected, both are of the same type.
|Remove selected items (creates
new list to keep indent level):
|Change selected item's
list type (note that remaining
bullet item is in different list):
|H. One item selected in one list, one item in 2nd list (sublist).
Two lists are selected, and they are different list types
|Change just 2nd selected
item's list type (creates new list):
|Change just 1st selected
item's list type (creates new list):
|I. One list item and list selected, plus one non-list paragraph
||Move non-list paragraph into
list as new item:
|Move non-list paragraph into
list as new item:
|J. A paragraph between 2 lists:
||Merge non-list paragraph into
list and merge 2nd list into 1st:
|Merge non-list paragraph into
new numbered list:
|J. A paragraph between 2 different list types:
||Merge non-list paragraph into 1st list along with item from 2nd
||Move item from 1st list while merging non-list paragraph into 2nd
These rules differ from the 4.x behavior, which are generally a mess and buggy, so it's not worth the time detailing the differences! One major difference is that in 4.x, when the selection is in just on list item, switching to a different list type changes the entire list to the new type. This is what happens in the current plan only when you change list type using the List Properties dialog.
After designing these rules, I examined MS Word 97 and discovered that they are remarkably similar, with one notable exception:
In this specification we try to preserve the existing indent level when changing list items from one type to another.. For most cases, this seems like the better behavior, although it does result in some odd lists in the more complicated selection cases.
For example, in case G above: In the first action, we are left with an item indented 2 levels, even though there are none in level 1. And in the second action, we have the appearance of a mixture of numbered and bulleted items at the same level, even though they are really in different lists. MS Word always "outdents" all list items whose type is changed all the way to the first level; it that seems to be a more extreme solution.
Definition lists consist of a DL list node, and the allowed child elements "Definition Term" (DT) and "Definition Description" (DD) that usually occur in pairs. Visually, the DT is simple left-aligned to the left margin, and the DD contents are indented. There is usually no multiple levels of indenting, as with OL and UL lists.
- In the List Properties dialog, an existing list or non-list paragraphs can be converted to a single DL list.
- In the Paragraph Styles combobox on the toolbar, or using the Format | Paragraph menu item, selected blocks can be converted to DT or DD list items.
The rules for converting selected lists or paragraphs into DL list:
- Identify the top-most block (common block parent node) of the selection.
- Insert a new DL list node just before this node, or split to a deeper level to obey HTML block containership rules, i.e., to a block parent that can accept a DL child node.
Convert all selected paragraphs and LI nodes to DD/DT nodes.
- Use DT if selected from the menu or toolbar combobox, otherwise use DD.
- Move children of each paragraph or LI into a new DD/DT node, which is inserted into the DL list.
- Delete all OL and/or UL lists (formerly parents of the moved nodes) that are now empty.
The rules for converting a DL list into an OL or UL list are simpler:
- For each DL element in the selection, create an OL or UL element to replace it. Insert this before the existing DL as described above.
- Within each DL: For each DT and DL element, create a LI element and move contents from the DT/DD into the LI, which is inserted in the new OL/UL.