aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/EditableView.tsx113
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx74
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx30
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx64
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx2
5 files changed, 158 insertions, 125 deletions
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index d7707a6fe..8036df471 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -3,7 +3,7 @@ import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as Autosuggest from 'react-autosuggest';
import { ObjectField } from '../../fields/ObjectField';
-import "./EditableView.scss";
+import './EditableView.scss';
export interface EditableProps {
/**
@@ -26,17 +26,16 @@ export interface EditableProps {
contents: any;
fontStyle?: string;
fontSize?: number;
- height?: number | "auto";
+ height?: number | 'auto';
sizeToContent?: boolean;
maxHeight?: number;
display?: string;
overflow?: string;
autosuggestProps?: {
resetValue: () => void;
- value: string,
- onChange: (e: React.ChangeEvent, { newValue }: { newValue: string }) => void,
- autosuggestProps: Autosuggest.AutosuggestProps<string, any>
-
+ value: string;
+ onChange: (e: React.ChangeEvent, { newValue }: { newValue: string }) => void;
+ autosuggestProps: Autosuggest.AutosuggestProps<string, any>;
};
oneLine?: boolean;
editing?: boolean;
@@ -81,16 +80,16 @@ export class EditableView extends React.Component<EditableProps> {
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
switch (e.key) {
- case "Tab":
+ case 'Tab':
e.stopPropagation();
this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, false);
this.props.OnTab?.(e.shiftKey);
break;
- case "Backspace":
+ case 'Backspace':
e.stopPropagation();
if (!e.currentTarget.value) this.props.OnEmpty?.();
break;
- case "Enter":
+ case 'Enter':
e.stopPropagation();
if (!e.ctrlKey) {
this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, true);
@@ -100,22 +99,26 @@ export class EditableView extends React.Component<EditableProps> {
this.props.isEditingCallback?.(false);
}
break;
- case "Escape":
+ case 'Escape':
e.stopPropagation();
this._editing = false;
this.props.isEditingCallback?.(false);
break;
- case ":":
+ case ':':
this.props.menuCallback?.(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y);
break;
- case "Shift": case "Alt": case "Meta": case "Control": break;
+ case 'Shift':
+ case 'Alt':
+ case 'Meta':
+ case 'Control':
+ break;
default:
if (this.props.textCallback?.(e.key)) {
this._editing = false;
- this.props.isEditingCallback?.(false,);
+ this.props.isEditingCallback?.(false);
}
}
- }
+ };
@action
onClick = (e: React.MouseEvent) => {
@@ -129,40 +132,44 @@ export class EditableView extends React.Component<EditableProps> {
}
e.stopPropagation();
}
- }
+ };
@action
finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) {
if (this.props.SetValue(value, shiftDown, enterKey)) {
this._editing = false;
- this.props.isEditingCallback?.(false,);
+ this.props.isEditingCallback?.(false);
} else {
this._editing = false;
this.props.isEditingCallback?.(false);
- !lostFocus && setTimeout(action(() => {
- this._editing = true;
- this.props.isEditingCallback?.(true);
- }), 0);
+ !lostFocus &&
+ setTimeout(
+ action(() => {
+ this._editing = true;
+ this.props.isEditingCallback?.(true);
+ }),
+ 0
+ );
}
}
- stopPropagation(e: React.SyntheticEvent) { e.stopPropagation(); }
+ stopPropagation(e: React.SyntheticEvent) {
+ e.stopPropagation();
+ }
@action
setIsFocused = (value: boolean) => {
const wasFocused = this._editing;
this._editing = value;
return wasFocused !== this._editing;
- }
-
-
+ };
renderEditor() {
- return this.props.autosuggestProps
- ? <Autosuggest
+ return this.props.autosuggestProps ? (
+ <Autosuggest
{...this.props.autosuggestProps.autosuggestProps}
inputProps={{
- className: "editableView-input",
+ className: 'editableView-input',
onKeyDown: this.onKeyDown,
autoFocus: true,
onBlur: e => this.finalizeEdit(e.currentTarget.value, false, true, false),
@@ -171,39 +178,49 @@ export class EditableView extends React.Component<EditableProps> {
onPointerUp: this.stopPropagation,
onKeyPress: this.stopPropagation,
value: this.props.autosuggestProps.value,
- onChange: this.props.autosuggestProps.onChange
+ onChange: this.props.autosuggestProps.onChange,
}}
/>
- : <input className="editableView-input" ref={this._inputref}
- style={{ display: this.props.display, overflow: "auto", fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
+ ) : (
+ <input
+ className="editableView-input"
+ ref={this._inputref}
+ style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
placeholder={this.props.placeholder}
onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
defaultValue={this.props.GetValue()}
autoFocus={true}
onKeyDown={this.onKeyDown}
- onKeyPress={this.stopPropagation} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation}
- />;
+ onKeyPress={this.stopPropagation}
+ onPointerDown={this.stopPropagation}
+ onClick={this.stopPropagation}
+ onPointerUp={this.stopPropagation}
+ />
+ );
}
render() {
if (this._editing && this.props.GetValue() !== undefined) {
- return this.props.sizeToContent ?
- <div style={{ display: "grid", minWidth: 100 }}>
- <div style={{ display: "inline-block", position: "relative", height: 0, width: "100%", overflow: "hidden" }}>
- {this.props.GetValue()}
- </div>
+ return this.props.sizeToContent ? (
+ <div style={{ display: 'grid', minWidth: 100 }}>
+ <div style={{ display: 'inline-block', position: 'relative', height: 0, width: '100%', overflow: 'hidden' }}>{this.props.GetValue()}</div>
{this.renderEditor()}
- </div> :
- this.renderEditor();
+ </div>
+ ) : (
+ this.renderEditor()
+ );
}
setTimeout(() => this.props.autosuggestProps?.resetValue());
- return this.props.contents instanceof ObjectField ? (null) :
- <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`} ref={this._ref}
- style={{ display: this.props.display, textOverflow: this.props.overflow, minHeight: "10px", whiteSpace: "nowrap", height: this.props.height || "auto", maxHeight: this.props.maxHeight }}
- onClick={this.onClick} placeholder={this.props.placeholder}>
- <span style={{ fontStyle: this.props.fontStyle, fontSize: this.props.fontSize }} >
- {this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()}
- </span>
- </div>;
+ return this.props.contents instanceof ObjectField ? null : (
+ <div
+ className={`editableView-container-editing${this.props.oneLine ? '-oneLine' : ''}`}
+ ref={this._ref}
+ style={{ display: this.props.display, textOverflow: this.props.overflow, minHeight: '10px', whiteSpace: 'nowrap', height: this.props.height || 'auto', maxHeight: this.props.maxHeight }}
+ onPointerDown={e => e.stopPropagation()}
+ onClick={this.onClick}
+ placeholder={this.props.placeholder}>
+ <span style={{ fontStyle: this.props.fontStyle, fontSize: this.props.fontSize }}>{this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()}</span>
+ </div>
+ );
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index ccac66996..91bd505c5 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -1,26 +1,24 @@
-import React = require("react");
-import { action, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc } from "../../../fields/Doc";
-import { LinkManager } from "../../util/LinkManager";
-import "./LinkDescriptionPopup.scss";
-import { TaskCompletionBox } from "./TaskCompletedBox";
-
+import React = require('react');
+import { action, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc } from '../../../fields/Doc';
+import { LinkManager } from '../../util/LinkManager';
+import './LinkDescriptionPopup.scss';
+import { TaskCompletionBox } from './TaskCompletedBox';
@observer
export class LinkDescriptionPopup extends React.Component<{}> {
-
@observable public static descriptionPopup: boolean = false;
- @observable public static showDescriptions: string = "ON";
+ @observable public static showDescriptions: string = 'ON';
@observable public static popupX: number = 700;
@observable public static popupY: number = 350;
- @observable description: string = "";
+ @observable description: string = '';
@observable popupRef = React.createRef<HTMLDivElement>();
@action
descriptionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
this.description = e.currentTarget.value;
- }
+ };
@action
onDismiss = (add: boolean) => {
@@ -28,7 +26,7 @@ export class LinkDescriptionPopup extends React.Component<{}> {
if (add) {
LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).description = this.description);
}
- }
+ };
@action
onClick = (e: PointerEvent) => {
@@ -36,35 +34,43 @@ export class LinkDescriptionPopup extends React.Component<{}> {
LinkDescriptionPopup.descriptionPopup = false;
TaskCompletionBox.taskCompleted = false;
}
- }
+ };
@action
componentDidMount() {
- document.addEventListener("pointerdown", this.onClick);
+ document.addEventListener('pointerdown', this.onClick, true);
}
componentWillUnmount() {
- document.removeEventListener("pointerdown", this.onClick);
+ document.removeEventListener('pointerdown', this.onClick, true);
}
render() {
- return <div className="linkDescriptionPopup" ref={this.popupRef}
- style={{
- left: LinkDescriptionPopup.popupX ? LinkDescriptionPopup.popupX : 700,
- top: LinkDescriptionPopup.popupY ? LinkDescriptionPopup.popupY : 350,
- }}>
- <input className="linkDescriptionPopup-input"
- onKeyDown={e => e.stopPropagation()}
- onKeyPress={e => e.key === "Enter" && this.onDismiss(true)}
- placeholder={"(Optional) Enter link description..."}
- onChange={(e) => this.descriptionChanged(e)}>
- </input>
- <div className="linkDescriptionPopup-btn">
- <div className="linkDescriptionPopup-btn-dismiss"
- onPointerDown={e => this.onDismiss(false)}> Dismiss </div>
- <div className="linkDescriptionPopup-btn-add"
- onPointerDown={e => this.onDismiss(true)}> Add </div>
+ return (
+ <div
+ className="linkDescriptionPopup"
+ ref={this.popupRef}
+ style={{
+ left: LinkDescriptionPopup.popupX ? LinkDescriptionPopup.popupX : 700,
+ top: LinkDescriptionPopup.popupY ? LinkDescriptionPopup.popupY : 350,
+ }}>
+ <input
+ className="linkDescriptionPopup-input"
+ onKeyDown={e => e.stopPropagation()}
+ onKeyPress={e => e.key === 'Enter' && this.onDismiss(true)}
+ placeholder={'(Optional) Enter link description...'}
+ onChange={e => this.descriptionChanged(e)}></input>
+ <div className="linkDescriptionPopup-btn">
+ <div className="linkDescriptionPopup-btn-dismiss" onPointerDown={e => this.onDismiss(false)}>
+ {' '}
+ Dismiss{' '}
+ </div>
+ <div className="linkDescriptionPopup-btn-add" onPointerDown={e => this.onDismiss(true)}>
+ {' '}
+ Add{' '}
+ </div>
+ </div>
</div>
- </div>;
+ );
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 08f255cab..73a711b9d 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -70,6 +70,8 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
@observable _dashDoc: Doc | undefined;
@observable _finalLayout: any;
@observable _resolvedDataDoc: any;
+ @observable _width: number = 0;
+ @observable _height: number = 0;
updateDoc = action((dashDoc: Doc) => {
this._dashDoc = dashDoc;
@@ -83,12 +85,14 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
}
if (this.props.width !== (this._dashDoc?._width ?? '') + 'px' || this.props.height !== (this._dashDoc?._height ?? '') + 'px') {
try {
+ this._width = NumCast(this._dashDoc?._width);
+ this._height = NumCast(this._dashDoc?._height);
// bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
this.props.view.dispatch(
this.props.view.state.tr.setNodeMarkup(this.props.getPos(), null, {
...this.props.node.attrs,
- width: (this._dashDoc?._width ?? '') + 'px',
- height: (this._dashDoc?._height ?? '') + 'px',
+ width: this._width + 'px',
+ height: this._height + 'px',
})
);
} catch (e) {
@@ -121,17 +125,17 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
componentDidMount() {
this._disposers.upater = reaction(
() => this._dashDoc && NumCast(this._dashDoc._height) + NumCast(this._dashDoc._width),
- () => {
+ action(() => {
if (this._dashDoc) {
- this.props.view.dispatch(
- this.props.view.state.tr.setNodeMarkup(this.props.getPos(), null, {
- ...this.props.node.attrs,
- width: (this._dashDoc?._width ?? '') + 'px',
- height: (this._dashDoc?._height ?? '') + 'px',
- })
- );
+ this._width = NumCast(this._dashDoc._width);
+ this._height = NumCast(this._dashDoc._height);
+ const parent = this._spanRef.current?.parentNode as HTMLElement;
+ if (parent) {
+ parent.style.width = this._width + 'px';
+ parent.style.height = this._height + 'px';
+ }
}
- }
+ })
);
}
@@ -172,8 +176,8 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
ref={this._spanRef}
className="dash-span"
style={{
- width: this.props.width,
- height: this.props.height,
+ width: this._width,
+ height: this._height,
position: 'absolute',
display: 'inline-block',
}}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index bbb7ddc85..eb87d11a4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -20,7 +20,7 @@ import { RichTextUtils } from '../../../../fields/RichTextUtils';
import { ComputedField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, OmitKeys, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
@@ -62,6 +62,7 @@ import { SummaryView } from './SummaryView';
import applyDevTools = require('prosemirror-dev-tools');
import React = require('react');
import { text } from 'body-parser';
+import { CollectionTreeView } from '../../collections/CollectionTreeView';
const translateGoogleApi = require('translate-google-api');
export interface FormattedTextBoxProps {
@@ -1500,7 +1501,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
onFocused = (e: React.FocusEvent): void => {
//applyDevTools.applyDevTools(this._editorView);
FormattedTextBox.Focused = this;
- this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props);
+ this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props);
};
@observable public static Focused: FormattedTextBox | undefined;
@@ -1588,6 +1589,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
@action
onBlur = (e: any) => {
+ if (this.ProseRef?.children[0] !== e.nativeEvent.target) return;
this.autoLink();
FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
@@ -1702,7 +1704,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
fitContentsToBox = () => this.props.Document._fitContentsToBox;
sidebarContentScaling = () => (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
- sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+ sidebarAddDocument = (doc: Doc | Doc[], sidebarKey: string = this.SidebarKey) => {
if (!this.layoutDoc._showSidebar) this.toggleSidebar();
// console.log("printting allSideBarDocs");
// console.log(this.allSidebarDocs);
@@ -1716,7 +1718,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.props
.ScreenToLocalTransform()
.translate(-(this.props.PanelWidth() - this.sidebarWidth()) / (this.props.NativeDimScaling?.() || 1), 0)
- .scale(1 / NumCast(this.layoutDoc._viewScale, 1));
+ .scale(1 / NumCast(this.layoutDoc._viewScale, 1) / (this.props.NativeDimScaling?.() || 1));
@computed get audioHandle() {
return (
@@ -1746,7 +1748,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
@computed get sidebarCollection() {
const renderComponent = (tag: string) => {
- const ComponentTag = tag === 'freeform' ? CollectionFreeFormView : tag === 'translation' ? FormattedTextBox : CollectionStackingView;
+ const ComponentTag = tag === 'freeform' ? CollectionFreeFormView : tag === 'tree' ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView;
return ComponentTag === CollectionStackingView ? (
<SidebarAnnos
ref={this._sidebarRef}
@@ -1755,6 +1757,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
nativeWidth={NumCast(this.layoutDoc._nativeWidth)}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
showSidebar={this.SidebarShown}
@@ -1765,30 +1768,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
removeDocument={this.removeDocument}
/>
) : (
- <ComponentTag
- {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- PanelHeight={this.props.PanelHeight}
- PanelWidth={this.sidebarWidth}
- xPadding={0}
- yPadding={0}
- scaleField={this.SidebarKey + '-scale'}
- isAnnotationOverlay={false}
- select={emptyFunction}
- NativeDimScaling={this.sidebarContentScaling}
- whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- removeDocument={this.sidebarRemDocument}
- moveDocument={this.sidebarMoveDocument}
- addDocument={this.sidebarAddDocument}
- CollectionView={undefined}
- ScreenToLocalTransform={this.sidebarScreenToLocal}
- renderDepth={this.props.renderDepth + 1}
- setHeight={this.setSidebarHeight}
- fitContentsToBox={this.fitContentsToBox}
- noSidebar={true}
- fieldKey={this.layoutDoc.sidebarViewType === 'translation' ? `${this.fieldKey}-translation` : `${this.fieldKey}-annotations`}
- />
+ <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.props.DocumentView?.()!), true)}>
+ <ComponentTag
+ {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ PanelHeight={this.props.PanelHeight}
+ PanelWidth={this.sidebarWidth}
+ xPadding={0}
+ yPadding={0}
+ scaleField={this.SidebarKey + '-scale'}
+ isAnnotationOverlay={false}
+ select={emptyFunction}
+ NativeDimScaling={this.sidebarContentScaling}
+ whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+ removeDocument={this.sidebarRemDocument}
+ moveDocument={this.sidebarMoveDocument}
+ addDocument={this.sidebarAddDocument}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
+ renderDepth={this.props.renderDepth + 1}
+ setHeight={this.setSidebarHeight}
+ fitContentsToBox={this.fitContentsToBox}
+ noSidebar={true}
+ treeViewHideTitle={true}
+ fieldKey={this.layoutDoc.sidebarViewType === 'translation' ? `${this.fieldKey}-translation` : `${this.fieldKey}-sidebar`}
+ />
+ </div>
);
};
return (
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 22ca76b2e..21326efaa 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -394,7 +394,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// remove all node type and apply the passed-in one to the selected text
changeListType = (mapStyle: string) => {
const active = this.view?.state && RichTextMenu.Instance.getActiveListStyle();
- const nodeType = this.view?.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? "" : mapStyle });
+ const nodeType = this.view?.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? '' : mapStyle });
if (!this.view || nodeType?.attrs.mapStyle === '') return;
const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list;