From 80bbbb3842cb89949d2b949ce8f5a2ed3921b112 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 17 Sep 2020 10:46:27 -0400 Subject: fixed deleting text links to work when there are multiple links in the same linkAnchor mark. addressed problem with text getting a negative height when its resized to fit content in a preview window when its also displayed in freeform. --- .../formattedText/FormattedTextBoxComment.tsx | 59 ++++++++++++++-------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 1bf885636..249aca812 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; -import { action } from "mobx"; +import { action, observable } from "mobx"; import { Mark, ResolvedPos } from "prosemirror-model"; import { EditorState, Plugin } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; @@ -23,6 +23,7 @@ import { FormattedTextBox } from "./FormattedTextBox"; import './FormattedTextBoxComment.scss'; import { schema } from "./schema_rts"; import React = require("react"); +import { observer } from "mobx-react"; export let formattedTextBoxCommentPlugin = new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } @@ -60,6 +61,7 @@ export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (mark // this view appears when clicking on text that has a hyperlink which is configured to show a preview of its target. // this will also display metadata information about text when the view is configured to display things like other people who authored text. // + export class FormattedTextBoxComment { static tooltip: HTMLElement; static tooltipText: HTMLElement; @@ -72,6 +74,13 @@ export class FormattedTextBoxComment { static _deleteRef: Opt; static _followRef: Opt; + static _nextRef: Opt; + + static _lastState?: EditorState; + static _lastView?: EditorView; + + @observable static _hrefInd = 0; + static _hrefs: string[] | undefined = []; constructor(view: any) { if (!FormattedTextBoxComment.tooltip) { @@ -101,6 +110,8 @@ export class FormattedTextBoxComment { if (linkDoc.author) { if (FormattedTextBoxComment._deleteRef?.contains(e.target as any)) { this.deleteLink(); + } else if (FormattedTextBoxComment._nextRef?.contains(e.target as any)) { + FormattedTextBoxComment.showPreview(FormattedTextBoxComment._lastView!, FormattedTextBoxComment._lastState, FormattedTextBoxComment._hrefs?.[(++FormattedTextBoxComment._hrefInd) % FormattedTextBoxComment._hrefs?.length]) } else { FormattedTextBoxComment.linkDoc = undefined; if (linkDoc.type !== DocumentType.LINK) { @@ -128,7 +139,6 @@ export class FormattedTextBoxComment { FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null; LinkDocPreview.LinkInfo = undefined; DocumentLinksButton.EditLink = undefined; - //FormattedTextBoxComment.tooltipText = undefined; FormattedTextBoxComment.Hide(); }); @@ -164,14 +174,20 @@ export class FormattedTextBoxComment { } static update(view: EditorView, lastState?: EditorState, forceUrl: string = "") { - const state = view.state; // Don't do anything if the document/selection didn't change - if (lastState && lastState.doc.eq(state.doc) && - lastState.selection.eq(state.selection)) { + if (!forceUrl && lastState?.doc.eq(view.state.doc) && lastState?.selection.eq(view.state.selection)) { return; } + FormattedTextBoxComment._lastState = lastState; + FormattedTextBoxComment._lastView = view; + FormattedTextBoxComment._hrefs = forceUrl ? forceUrl.trim().split(" ") : undefined; + FormattedTextBoxComment._hrefInd = 0; FormattedTextBoxComment.linkDoc = undefined; + FormattedTextBoxComment.showPreview(view, lastState, FormattedTextBoxComment._hrefs?.[FormattedTextBoxComment._hrefInd]); + } + static showPreview(view: EditorView, lastState?: EditorState, forceUrl: string = "") { + const state = view.state; const textBox = FormattedTextBoxComment.textBox; if (!textBox || !textBox.props) { return; @@ -209,7 +225,7 @@ export class FormattedTextBoxComment { state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node)); child = child || (nbef && state.selection.$from.nodeBefore); const mark = child ? findLinkMark(child.marks) : undefined; - const href = (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allLinks.find((item: { href: string }) => item.href)?.href || forceUrl; + const href = forceUrl || (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allLinks.find((item: { href: string }) => item.href)?.href; if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) { try { ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText); @@ -245,34 +261,35 @@ export class FormattedTextBoxComment { if (target?.author) { FormattedTextBoxComment.showCommentbox("", view, nbef); - const title = StrCast(target.title).length > 16 ? - StrCast(target.title).substr(0, 16) + "..." : target.title; - + const title = StrCast(target.title).length > 16 ? StrCast(target.title).substr(0, 16) + "..." : target.title; const docPreview =
{title} - {FormattedTextBoxComment.linkDoc.description !== "" ?

- {StrCast(FormattedTextBoxComment.linkDoc.description)}

: null} + {FormattedTextBoxComment.linkDoc.description === "" ? (null) : +

{StrCast(FormattedTextBoxComment.linkDoc.description)}

}
+ {(FormattedTextBoxComment._hrefs?.length || 0) <= 1 ? (null) :
Next Link
} placement="top"> +
this._nextRef = r}> + +
+
}
Delete Link
} placement="top"> -
this._deleteRef = r}> -
+
this._deleteRef = r}> + +
Follow Link
} placement="top"> -
this._followRef = r}> - +
this._followRef = r}> +
-
+
+
; - - FormattedTextBoxComment.showCommentbox("", view, nbef); ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText); -- cgit v1.2.3-70-g09d2 From 7645178696f5e85f12c841e3727b986cee7bec06 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 17 Sep 2020 11:05:14 -0400 Subject: tweaked external url tooltip for text box links --- src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 249aca812..47150c51a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -23,7 +23,6 @@ import { FormattedTextBox } from "./FormattedTextBox"; import './FormattedTextBoxComment.scss'; import { schema } from "./schema_rts"; import React = require("react"); -import { observer } from "mobx-react"; export let formattedTextBoxCommentPlugin = new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } @@ -95,7 +94,7 @@ export class FormattedTextBoxComment { FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText); FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip"; FormattedTextBoxComment.tooltip.style.pointerEvents = "all"; - FormattedTextBoxComment.tooltip.style.maxWidth = "200px"; + FormattedTextBoxComment.tooltip.style.maxWidth = "400px"; FormattedTextBoxComment.tooltip.style.maxHeight = "235px"; FormattedTextBoxComment.tooltip.style.width = "100%"; FormattedTextBoxComment.tooltip.style.height = "100%"; @@ -235,9 +234,10 @@ export class FormattedTextBoxComment { FormattedTextBoxComment.tooltipText.style.width = "100%"; FormattedTextBoxComment.tooltipText.style.height = "100%"; FormattedTextBoxComment.tooltipText.style.textOverflow = "ellipsis"; + FormattedTextBoxComment.tooltipText.style.cursor = "pointer"; FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText); - FormattedTextBoxComment.tooltipText.textContent = "external => " + href; + FormattedTextBoxComment.tooltipText.textContent = "URL: " + href; (FormattedTextBoxComment.tooltipText as any).href = href; if (href.startsWith("https://en.wikipedia.org/wiki/")) { wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500))); -- cgit v1.2.3-70-g09d2 From 04ab7a6a6d206014f99b46a6a8771c205cdb079a Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 17 Sep 2020 12:00:15 -0400 Subject: restored template button option for customizing layout but added a Full Toolbar mode to enable it. --- src/client/util/SettingsManager.tsx | 6 ++-- src/client/views/ContextMenu.tsx | 2 +- src/client/views/DocumentButtonBar.tsx | 38 +++++++++++--------- src/client/views/TemplateMenu.tsx | 28 +++++++-------- src/client/views/Templates.tsx | 41 ---------------------- .../views/collections/CollectionTreeView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 3 +- .../formattedText/FormattedTextBoxComment.tsx | 2 +- 8 files changed, 42 insertions(+), 81 deletions(-) delete mode 100644 src/client/views/Templates.tsx (limited to 'src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx') diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index fc8bc382e..17e93ad17 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -113,9 +113,9 @@ export class SettingsManager extends React.Component<{}> { Doc.UserDoc().showTitle = Doc.UserDoc().showTitle ? undefined : "creationDate"} checked={Doc.UserDoc().showTitle !== undefined} />
-
Alt Buttons
- Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"]} - checked={BoolCast(Doc.UserDoc()["documentLinksButton-hideEnd"])} /> +
Full Toolbar
+ Doc.UserDoc()["documentLinksButton-fullMenu"] = !Doc.UserDoc()["documentLinksButton-fullMenu"]} + checked={BoolCast(Doc.UserDoc()["documentLinksButton-fullMenu"])} />
Raise on drag
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 349fd077c..1f7abf61a 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -233,7 +233,7 @@ export class ContextMenu extends React.Component { - + {this.menuItems} diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 979b1198a..b155e33ff 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -23,7 +23,6 @@ import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { DocumentView } from './nodes/DocumentView'; import { GoogleRef } from "./nodes/formattedText/FormattedTextBox"; import { TemplateMenu } from "./TemplateMenu"; -import { Template, Templates } from "./Templates"; import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -255,9 +254,11 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
; } @observable _aliasDown = false; - onAliasButtonDown = (e: React.PointerEvent): void => { + onAliasButtonDown = action((e: React.PointerEvent): void => { + this.props.views()[0]?.select(false); + this._tooltipOpen = false; setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction); - } + }) onAliasButtonMoved = () => { if (this._dragRef.current) { const dragDocView = this.view0!; @@ -274,23 +275,28 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return false; } + _ref = React.createRef(); + @observable _tooltipOpen: boolean = false; @computed get templateButton() { const view0 = this.view0; - const templates: Map = new Map(); + const templates: Map = new Map(); const views = this.props.views(); - Array.from(Object.values(Templates.TemplateList)).map(template => - templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); + Array.from(["Caption", "Title", "TitleHover"]).map(template => + templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template] ? true : false, false as boolean))); return !view0 ? (null) : -
Tap: Customize layout. Drag: Create alias
}> -
+ CustomizeLayout
} open={this._tooltipOpen} onClose={action(() => this._tooltipOpen = false)} placement="bottom"> +
!this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))} > + this._aliasDown = true)} onClose={action(() => this._aliasDown = false)} - content={!this._aliasDown ? (null) : v).map(v => v as DocumentView)} templates={templates} />}> + content={!this._aliasDown ? (null) :
v).map(v => v as DocumentView)} templates={templates} />
}>
{}
-
; + + ; } openContextMenu = (e: React.MouseEvent) => { @@ -315,13 +321,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
- {DocumentLinksButton.StartLink || !Doc.UserDoc()["documentLinksButton-hideEnd"] ?
+ {DocumentLinksButton.StartLink || !Doc.UserDoc()["documentLinksButton-fullMenu"] ?
: (null)} - {/*
+ {!Doc.UserDoc()["documentLinksButton-fullMenu"] ? (null) :
{this.templateButton}
-
+ /*
{this.metadataButton}
@@ -330,7 +336,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{this.pinButton}
- {!Doc.UserDoc()["documentLinksButton-hideEnd"] ? (null) :
+ {!Doc.UserDoc()["documentLinksButton-fullMenu"] ? (null) :
{this.shareButton}
} {![DocumentType.VID, DocumentType.WEB].includes(StrCast(this.view0.props.Document.type) as DocumentType) ? (null) :
@@ -345,9 +351,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{this.menuButton}
-
+ {/* {Doc.UserDoc().noviceMode ? (null) :
{this.moreButton} -
+
} */}
; } } diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index c1878115d..cf2118cb2 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,10 +1,8 @@ import { action, observable, runInAction, ObservableSet, trace, computed } from "mobx"; import { observer } from "mobx-react"; -import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; import './TemplateMenu.scss'; import { DocumentView } from "./nodes/DocumentView"; -import { Template } from "./Templates"; import React = require("react"); import { Doc, DocListCast } from "../../fields/Doc"; import { Docs, DocUtils, } from "../documents/Documents"; @@ -18,13 +16,13 @@ import { List } from "../../fields/List"; import { TraceMobx } from "../../fields/util"; @observer -class TemplateToggle extends React.Component<{ template: Template, checked: boolean, toggle: (event: React.ChangeEvent, template: Template) => void }> { +class TemplateToggle extends React.Component<{ template: string, checked: boolean, toggle: (event: React.ChangeEvent, template: string) => void }> { render() { if (this.props.template) { return (
  • this.props.toggle(event, this.props.template)} /> - {this.props.template.Name} + {this.props.template}
  • ); } else { @@ -46,7 +44,7 @@ class OtherToggle extends React.Component<{ checked: boolean, name: string, togg export interface TemplateMenuProps { docViews: DocumentView[]; - templates: Map; + templates: Map; } @@ -69,8 +67,8 @@ export class TemplateMenu extends React.Component { @undoBatch @action - toggleTemplate = (event: React.ChangeEvent, template: Template): void => { - this.props.docViews.forEach(d => Doc.Layout(d.layoutDoc)["_show" + template.Name] = event.target.checked ? template.Name.toLowerCase() : ""); + toggleTemplate = (event: React.ChangeEvent, template: string): void => { + this.props.docViews.forEach(d => Doc.Layout(d.layoutDoc)["_show" + template] = event.target.checked ? template.toLowerCase() : ""); } @action @@ -113,21 +111,21 @@ export class TemplateMenu extends React.Component { const firstDoc = this.props.docViews[0].props.Document; const templateName = StrCast(firstDoc.layoutKey, "layout").replace("layout_", ""); const noteTypes = DocListCast(Cast(Doc.UserDoc()["template-notes"], Doc, null)?.data); - const addedTypes = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data); + const addedTypes = Doc.UserDoc().noviceMode ? [] : DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data); const layout = Doc.Layout(firstDoc); const templateMenu: Array = []; - //this.props.templates.forEach((checked, template) => - // templateMenu.push()); - //templateMenu.push(); - templateMenu.push(); + this.props.templates.forEach((checked, template) => + templateMenu.push()); + templateMenu.push(); templateMenu.push(); + !Doc.UserDoc().noviceMode && templateMenu.push(); addedTypes.concat(noteTypes).map(template => template.treeViewChecked = this.templateIsUsed(firstDoc, template)); this._addedKeys && Array.from(this._addedKeys).filter(key => !noteTypes.some(nt => nt.title === key)).forEach(template => templateMenu.push( this.toggleLayout(e, template)} />)); return
      - + {Doc.UserDoc().noviceMode ? (null) : } {templateMenu} - { fieldKey={"data"} moveDocument={returnFalse} removeDocument={returnFalse} - addDocument={returnFalse} /> + addDocument={returnFalse} />}
    ; } } diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx deleted file mode 100644 index a6dbaa650..000000000 --- a/src/client/views/Templates.tsx +++ /dev/null @@ -1,41 +0,0 @@ -export class Template { - constructor(name: string, layout: string) { - this._name = name; - this._layout = layout; - } - - private _name: string; - private _layout: string; - - get Name(): string { - return this._name; - } - - get Layout(): string { - return this._layout; - } -} - -export namespace Templates { - export const Caption = new Template("Caption", - `
    -
    {layout}
    -
    - -
    -
    ` ); - - export const Title = new Template("Title", - `
    -
    - {props.Document.title} -
    -
    -
    {layout}
    -
    -
    ` ); - export const TitleHover = new Template("TitleHover", Title.Layout); - - export const TemplateList: Template[] = [Title, TitleHover, Caption]; -} - diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e8944a5eb..19b8400c8 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -22,7 +22,6 @@ import { EditableView } from "../EditableView"; import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; import { DocumentView } from '../nodes/DocumentView'; import { KeyValueBox } from '../nodes/KeyValueBox'; -import { Templates } from '../Templates'; import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { CollectionViewType, CollectionView } from './CollectionView'; @@ -185,7 +184,7 @@ class TreeView extends React.Component { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10, templates: new List([Templates.Title.Layout]) }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List([]); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0b4f45dd6..7ff8b635c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -118,7 +118,7 @@ export class DocumentView extends DocComponent(Docu private get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); } public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive public get ContentDiv() { return this._mainCont.current; } - public get LayoutFieldKey() { return StrCast(this.props.layoutKey, Doc.LayoutFieldKey(this.layoutDoc)); } + public get LayoutFieldKey() { return this.props.layoutKey || Doc.LayoutFieldKey(this.layoutDoc); } @computed get ShowTitle() { return StrCast(this.layoutDoc._showTitle, !Doc.IsSystem(this.layoutDoc) && this.rootDoc.type === DocumentType.RTF && !this.props.treeViewDoc ? @@ -855,7 +855,6 @@ export class DocumentView extends DocComponent(Docu moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); } moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); - Doc.AreProtosEqual(this.props.Document, Cast(Doc.UserDoc().myUserDoc, Doc, null)) && moreItems.push({ description: "Toggle Alternate Button Bar", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" }); } } diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 47150c51a..f015d329c 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -110,7 +110,7 @@ export class FormattedTextBoxComment { if (FormattedTextBoxComment._deleteRef?.contains(e.target as any)) { this.deleteLink(); } else if (FormattedTextBoxComment._nextRef?.contains(e.target as any)) { - FormattedTextBoxComment.showPreview(FormattedTextBoxComment._lastView!, FormattedTextBoxComment._lastState, FormattedTextBoxComment._hrefs?.[(++FormattedTextBoxComment._hrefInd) % FormattedTextBoxComment._hrefs?.length]) + FormattedTextBoxComment.showPreview(FormattedTextBoxComment._lastView!, FormattedTextBoxComment._lastState, FormattedTextBoxComment._hrefs?.[(++FormattedTextBoxComment._hrefInd) % FormattedTextBoxComment._hrefs?.length]); } else { FormattedTextBoxComment.linkDoc = undefined; if (linkDoc.type !== DocumentType.LINK) { -- cgit v1.2.3-70-g09d2